【问题标题】:How to hide and show the Android ActionBar like in Google Inbox app?如何像在 Google Inbox 应用中一样隐藏和显示 Android ActionBar?
【发布时间】:2016-08-21 20:52:02
【问题描述】:

我想在用户滚动屏幕时显示和隐藏 Android ActionBar。我在 SO 中找到了一些示例,例如 this 问题。但是这个问题中显示的代码及其答案在列表滚动一些像素后使动作隐藏,我想让这个滚动就像谷歌的收件箱应用程序一样,即动作栏由布局根据用户拉动向上或向下滚动屏幕,换句话说,我想在用户向下/向上滚动的同时显示/隐藏操作栏。

有人面临这样的问题吗?有什么想法吗?

【问题讨论】:

    标签: android android-listview scroll android-actionbar google-inbox


    【解决方案1】:

    超级简单:

    1. 放弃ListView。 ListView 已成为过去。请改用RecyclerView
    2. 向其添加RecyclerView.OnScrollListener,以获得逐像素滚动。
    3. 在您的活动布局上使用Toolbar。所以你可以控制它的位置。
    4. 在您的Toolbar 上调用setTranslationY(val) 以使用RecyclerView“滚动”它。

    上述类的文档的一些链接:

    【讨论】:

    • 感谢您的回答。真的,我应该已经迁移到 RecyclerView 了。我会尝试这种方法并在完成后立即接受您的回答。
    • 您最近在带有列表的应用程序(快速返回、动画项目等)上看到的所有花哨的酷炫效果都在使用 RecyclerView。 ListView 非常有限,Google 正在放弃它,我们(开发人员)也应该尽快放弃。祝你好运。
    【解决方案2】:

    我创建了一个基于解决方案的@Budius 答案和这个link

    先添加这个类

    public class HidingRecyclerViewScrollListener extends RecyclerView.OnScrollListener {
    
        private final int UP = 0;
        private final int DOWN = 1;
        private final int margin = 5;
        private View mView;
        RecyclerView.LayoutManager mLayoutManager;
    
        private float currentPoint = 0;
        private int lastDirection = 1;
    
        public HidingRecyclerViewScrollListener(View view, LinearLayoutManager layoutManager) {
            this.mLayoutManager = layoutManager;
            mView = view;
        }
    
        public HidingRecyclerViewScrollListener(View view, GridLayoutManager layoutManager) {
            this.mLayoutManager = layoutManager;
            mView = view;
        }
    
        public HidingRecyclerViewScrollListener(View view, StaggeredGridLayoutManager layoutManager) {
            this.mLayoutManager = layoutManager;
            mView = view;
        }
    
        public int getFirstVisibleItem(int[] firstVisibleItemPositions) {
            int minSize = 0;
            for (int i = 0; i < firstVisibleItemPositions.length; i++) {
                if (i == 0) {
                    minSize = firstVisibleItemPositions[i];
                } else if (firstVisibleItemPositions[i] < minSize) {
                    minSize = firstVisibleItemPositions[i];
                }
            }
            return minSize;
        }
    
    
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            float nextPoint = currentPoint + dy;
    
    
            if (nextPoint < 0) {
                nextPoint = 0;
            }
    
    
            if (nextPoint > viewSize()) {
                nextPoint = viewSize();
            }
    
            lastDirection = nextPoint >= currentPoint ? UP : DOWN;
    
            currentPoint = nextPoint;
    
            mView.setTranslationY(-currentPoint);
        }
    
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                if (lastDirection == UP) {
                    if (getFirstVisibleItem() > 0) {
    
                        currentPoint = viewSize();
                    }
                }
                if (lastDirection == DOWN) {
                    //Volta para origem
                    currentPoint = 0;
                }
                mView.animate().translationY(-currentPoint);
            }
        }
    
        private int getFirstVisibleItem() {
            int firstVisibleItem = 0;
            if (mLayoutManager instanceof StaggeredGridLayoutManager) {
                int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findFirstVisibleItemPositions(null);
                firstVisibleItem = getFirstVisibleItem(lastVisibleItemPositions);
            } else if (mLayoutManager instanceof LinearLayoutManager) {
                firstVisibleItem = ((LinearLayoutManager) mLayoutManager).findFirstVisibleItemPosition();
            } else if (mLayoutManager instanceof GridLayoutManager) {
                firstVisibleItem = ((GridLayoutManager) mLayoutManager).findFirstVisibleItemPosition();
            }
            return firstVisibleItem;
        }
    
        private int viewSize() {
            return mView.getHeight() + margin;
        }
    }
    

    使用简单,只使用你的recyclerView的addOnScrollListener添加

    recyclerView = (RecyclerView) view.findViewById(R.id.mRecyclerView );
    layoutManager = new LinearLayoutManager(getContext());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.addOnScrollListener(new HidingRecyclerViewScrollListener(mView, layoutManager));
    
    • mView是你要控制的视图

    • 您可以将此类与 LinearLayoutManager、GridLayoutManager 和 StaggeredGridLayoutManager 一起使用(但我从不使用 GridLayoutManager 进行测试)

    在 RecyclerView 中使用下面的代码使列表不会停留在您要控制的对象下方,此代码更简单更好测试,但在 RecyclerView 中使用 Hearder 如上面链接中所述具有更好的结果。

    android:clipToPadding="false"
    android:paddingTop="@dimen/outher_view_dimem"
    

    如果你使用 SwipeRefreshLayout 使用下面的代码来显示 ProgressBar

    swipeRefreshLayout.setProgressViewOffset(true, 0, mViewHeight + actionBarHeight);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      相关资源
      最近更新 更多