Android: 当滚动ListView时,使用动画隐藏RelativeLayout

3

我尝试实现一个动画,用于隐藏位于listview上方的RelativeLayout。我希望它具有以下行为:

  • 向下滚动:隐藏RelativeLayout
  • 向上滚动:只有当我在顶部时才显示RelativeLayout

enter image description here

我创建的以下代码有效,但存在两个问题:

  1. 当我向下或向上滚动时,如果我在listview的顶部,relativelayout会闪烁。我必须快速滚动才能隐藏这次攀登。 => 我的代码存在问题,也许在listIsAtTop()函数上?
  2. 第二个问题是,我没有动画。我使用setVisivility(VISIBLE or GONE)来显示或隐藏relativeLayout。这不够用户友好,对吗?:) 我不知道如何添加一个小平移动画来隐藏和显示这个相对布局。

在Account_Activity类的onCreate()中:

list = (com.app.frisbeee.account_view.CustomListView)findViewById(R.id.accountview_listview);
adapter = new Account_view_custom_adapter(Account_view_act.this, annoncesList);
            list.setAdapter(adapter);
            adapter.notifyDataSetChanged();
            registerForContextMenu(list);

            list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    list.showContextMenuForChild(view);   
                }
            });

            list.setOnDetectScrollListener(new OnDetectScrollListener() {
                @Override
                public void onUpScrolling() {
                    /* do something */
                    Log.d("INFO", "UPPPPPPPPPPP");
                    if (listIsAtTop()) {
                        RelativeLayout relative1 = (RelativeLayout) findViewById(R.id.relative1);
                        relative1.setVisibility(View.VISIBLE);
                    }
                }

                @Override
                public void onDownScrolling() {
                    /* do something */
                    Log.d("INFO", "DOWNNNNNNNN");
                    if (!listIsAtTop()) {
                        RelativeLayout relative1 = (RelativeLayout) findViewById(R.id.relative1);
                        relative1.setVisibility(View.GONE);
                    }

                }
            });

        }

listIsAtTop函数的代码:

private boolean listIsAtTop()   {   
        if (list.getChildCount() == 0) {
            return true;
        }
        return list.getFirstVisiblePosition() == 0 && (list.getChildCount() == 0 || list.getChildAt(0).getTop() == 0);
    }

CustomListView 用于检测滚动 UP 和 DOWN:

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AbsListView;

public class CustomListView extends android.widget.ListView {

    private OnScrollListener onScrollListener;
    private OnDetectScrollListener onDetectScrollListener;

    public CustomListView(Context context) {
        super(context);
        onCreate(context, null, null);
    }

    public CustomListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        onCreate(context, attrs, null);
    }

    public CustomListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        onCreate(context, attrs, defStyle);
    }

    private void onCreate(Context context, AttributeSet attrs, Integer defStyle) {
        setListeners();
    }

    private void setListeners() {
        super.setOnScrollListener(new OnScrollListener() {

            private int oldTop;
            private int oldFirstVisibleItem;

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (onScrollListener != null) {
                    onScrollListener.onScrollStateChanged(view, scrollState);
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (onScrollListener != null) {
                    onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
                }

                if (onDetectScrollListener != null) {
                    onDetectedListScroll(view, firstVisibleItem);
                }
            }

            private void onDetectedListScroll(AbsListView absListView, int firstVisibleItem) {
                View view = absListView.getChildAt(0);
                int top = (view == null) ? 0 : view.getTop();

                if (firstVisibleItem == oldFirstVisibleItem) {
                    if (top > oldTop) {
                        onDetectScrollListener.onUpScrolling();
                    } else if (top < oldTop) {
                        onDetectScrollListener.onDownScrolling();
                    }
                } else {
                    if (firstVisibleItem < oldFirstVisibleItem) {
                        onDetectScrollListener.onUpScrolling();
                    } else {
                        onDetectScrollListener.onDownScrolling();
                    }
                }

                oldTop = top;
                oldFirstVisibleItem = firstVisibleItem;
            }
        });
    }

    @Override
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }

    public void setOnDetectScrollListener(OnDetectScrollListener onDetectScrollListener) {
        this.onDetectScrollListener = onDetectScrollListener;
    }
}

请在实现后告诉我。我也需要相同的功能。过去我通过更改“LayoutWeight”来实现了相同的功能,但这种方法很不正规。 - VenomVendor
1个回答

0

尝试使用以下代码实现listIsAtTop()函数:

private boolean listIsAtTop()   {   
    if(listView.getChildCount() == 0) return true;
    return listView.getChildAt(0).getTop() == 0;
}

关于滑动动画:
slide_down.xml 代码:
<set xmlns:android="http://schemas.android.com/apk/res/android">  
    <translate android:fromXDelta="0" android:fromYDelta="-1000" android:duration="1500"/>
</set>

slide_up.xml的代码:

<set xmlns:android="http://schemas.android.com/apk/res/android">  
    <translate android:fromXDelta="0" android:fromYDelta="1000" android:duration="1500"/>
</set>

然后在onCreate方法中加载动画:

Animation slideUp = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_up);

然后将其附加到您的RelativeLayout:

relative1.startAnimation(slideUp);

希望这能有所帮助 :)

谢谢。它的工作效果不是很好。我必须把这行代码放在哪里:relative1.startAnimation(slideUp); 我试着把它放在setVisibility之前..你有尝试过你的代码吗? - wawanopoulos
你可以把那行代码放在任何你想要执行动画的地方。是的,我已经尝试过这段代码了,我经常使用动画 :P 动画没有起作用吗?当你运行它时发生了什么? - Jonny07
我明白了。你只是将动画应用于浅粉色部分吗?还是也将其应用于深粉色和灰色条形区域? - Jonny07
即使没有动画,我也遇到了闪烁的问题。在我的日志中,当我处于顶部位置“UPPPPPPPPPPP”和“DOWNNNN”时,会显示日志,这可能是闪烁的原因。也许是listIsAtTop函数出了问题? - wawanopoulos
好的。我想我知道这里发生了什么。我在viewpager中遇到了类似的问题(闪烁问题)。我没有确切的答案,但我肯定可以指导你正确的方向。在所有滚动更改/滚动监听器中放置一些调试日志,并在到达列表顶部时检查是否显示了大量日志。不只是一个,而是如果您继续向上滚动,我怀疑您会看到10-50个“顶部”消息的日志。 - Jonny07
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接