隐藏在RecyclerView / ListView中动作条onScroll(Hiding the

2019-06-21 07:14发布

在我的应用我有在顶部某种动作条和它下面的列表视图的活动。 我想要做的 - 是在列表中滚动起来,所以它隐藏,然后,当列表被滚动下来 - 它应该向下滚动与列表,就像是刚刚在上屏幕边框。 我怎样才能实现这个功能呢?

Answer 1:

已更新2015年6月3日:

谷歌现在支持这种使用CoordinatorLayout

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_done" />

</android.support.design.widget.CoordinatorLayout>

来源: https://github.com/chrisbanes/cheesesquare/blob/master/app/src/main/res/layout/include_list_viewpager.xml

这里记载: https://developer.android.com/reference/android/support/design/widget/AppBarLayout.html

原来的答案:

例如类似于谷歌播放音乐和Umano应用:

https://github.com/umano/AndroidSlidingUpPanel

看看在这个库中的代码。 当你滑动面板了,在ActionBar上滑为好。

从演示

   getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);

   SlidingUpPanelLayout layout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
    layout.setShadowDrawable(getResources().getDrawable(R.drawable.above_shadow));
    layout.setAnchorPoint(0.3f);
    layout.setPanelSlideListener(new PanelSlideListener() {
        @Override
        public void onPanelSlide(View panel, float slideOffset) {
            Log.i(TAG, "onPanelSlide, offset " + slideOffset);
            if (slideOffset < 0.2) {
                if (getActionBar().isShowing()) {
                    getActionBar().hide();
                }
            } else {
                if (!getActionBar().isShowing()) {
                    getActionBar().show();
                }
            }
        }

        @Override
        public void onPanelExpanded(View panel) {
            Log.i(TAG, "onPanelExpanded");

        }

        @Override
        public void onPanelCollapsed(View panel) {
            Log.i(TAG, "onPanelCollapsed");

        }

        @Override
        public void onPanelAnchored(View panel) {
            Log.i(TAG, "onPanelAnchored");

        }
    });

在这里下载例子:

https://play.google.com/store/apps/details?id=com.sothree.umano

ListView控件 - 无库:

我最近想相同的功能,这完美的作品对我来说:

当用户向上滚动时,动作条将被隐藏,以给用户的整个屏幕上班工作,。

当用户向下滚动,让走,动作条会回来。

getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);

listView.setOnScrollListener(new OnScrollListener() {
    int mLastFirstVisibleItem = 0;

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {   }           

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {    
        if (view.getId() == listView.getId()) {
            final int currentFirstVisibleItem = listView.getFirstVisiblePosition();

            if (currentFirstVisibleItem > mLastFirstVisibleItem) {
                // getSherlockActivity().getSupportActionBar().hide();
                getSupportActionBar().hide();
            } else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
                // getSherlockActivity().getSupportActionBar().show();
                getSupportActionBar().show();
            }

            mLastFirstVisibleItem = currentFirstVisibleItem;
        }               
    }
});

RecyclerView - 无库

    this.mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
        int mLastFirstVisibleItem = 0;

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            final int currentFirstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();

            if (currentFirstVisibleItem > this.mLastFirstVisibleItem) {
                MainActivity.this.getSupportActionBar().hide();
            } else if (currentFirstVisibleItem < this.mLastFirstVisibleItem) {
                MainActivity.this.getSupportActionBar().show();
            }

            this.mLastFirstVisibleItem = currentFirstVisibleItem;
        }
    });

让我知道如果你需要帮助了!



Answer 2:

您遇到的闪烁,因为通过隐藏/显示动作条的内容布局更改的可用空间,这将导致重新布局。 与此的第一个可见项目的位置变化的指数,以及(您可以通过注销mLastFirstVisibleItemcurrentFirstVisibleItem验证这一点。

你可以通过让动作条覆盖你的内容布局与闪烁应付。 要启用动作栏覆盖模式,你需要创建一个扩展现有的动作栏为主题的自定义主题,并设置了android:windowActionBarOverlay属性为true。

有了这个,你可以消除闪烁,但操作栏将覆盖你的ListView的内容。 一个简单的解决方案,这是设置ListView的(或根布局的)顶部填充到动作杆的高度。

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?android:attr/actionBarSize" />

不幸的是,这将导致在顶部的固定填充。 这种解决方案的改进方案是给一个标题视图添加到其具有的高度列表视图机器人:?ATTR / actionBarSize(和删除顶部填充预先设定)



Answer 3:

你所寻找被称为快速返回模式 ,应用到操作栏。 谷歌IO 2014应用程序使用这一点。 我用它在我的应用程序之一,你可以查看源代码 ,谷歌的应用程序,看看他们是如何得到它。 该BaseActivity类是,你有你需要什么,阅读代码和提取只是特定功能。 享受编码! :)



Answer 4:

我相信,这不是最好的解决办法。 但是我还没有找到一个更好的呢。 希望这将是有益的。

    static boolean scroll_down;
    ...
    mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
                if (scroll_down) {
                    actionBar.hide();
                } else {
                    actionBar.show();
                }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (dy > 70) {
                //scroll down
                scroll_down = true;

            } else if (dy < -5) {
                //scroll up
                scroll_down = false;
            }
        }
    });


Answer 5:

我有一个想法,这是一个好主意。

listView.setOnScrollListener(new OnScrollListener() {
    int mLastFirstVisibleItem = 0;

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
      switch (scrollState) {
            case OnScrollListener.SCROLL_STATE_FLING:
                if (view.getId()==lv_searchresult_results.getId()){
                final int currentFirstVisibleItem=lv_searchresult_results.getFirstVisiblePosition();
                    if(currentFirstVisibleItem>mLastFirstVisibleItem){

                    ObjectAnimator.ofFloat(toolbar, "translationY", -toolbar.getHeight()).start();
                    else if(currentFirstVisibleItem<(mLastFirstVisibleItem)){

                    ObjectAnimator.ofFloat(toolbar, "translationY", 0).start();
                    }
                    mLastFirstVisibleItem= currentFirstVisibleItem;
                }

                if(lv_searchresult_results.getLastVisiblePosition() == myAdapter.getListMap().size()){ 
                    if(myAdapter.getListMap().size() < allRows&&!upLoading){

                    }
                }
                break;
            case OnScrollListener.SCROLL_STATE_IDLE:

                if (view.getFirstVisiblePosition()<=1){
                    ObjectAnimator.ofFloat(toolbar, "translationY", 0).start();

                }
                    if(lv_searchresult_results.getLastVisiblePosition() == myAdapter.getListMap().size()){
                    if(myAdapter.getListMap().size() < allRows&&!upLoading){


                    }
                }
                break;


Answer 6:

我认为它会正常工作.....

listView.setOnScrollListener(new OnScrollListener() {
            int mLastFirstVisibleItem = listView.getLastVisiblePosition();
            boolean isScrolling = false;

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if(scrollState == 0)
                    isScrolling = false;
                else if(scrollState == 1)
                    isScrolling = true;
                else if(scrollState == 2)
                    isScrolling = true;     
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {    
                if (view.getId() == myTeamListView.getId()) {

                    if(isScrolling) {
                    final int currentFirstVisibleItem = myTeamListView.getLastVisiblePosition();

                    if (currentFirstVisibleItem > mLastFirstVisibleItem) {                      
                        ((AppCompatActivity)getActivity()).getSupportActionBar().hide();
                    } else if (currentFirstVisibleItem < mLastFirstVisibleItem) {                       
                        ((AppCompatActivity)getActivity()).getSupportActionBar().show();                    
                    }
                    mLastFirstVisibleItem = currentFirstVisibleItem;
                    }
                }
            }
        });


Answer 7:

如果您使用的是CoordinatorLayout,这里的伎俩。

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:layout_scrollFlags="scroll|enterAlways" />

app:layout_scrollFlags="scroll|enterAlways"行将会导致我们的工具栏在屏幕上滚过当用户向下滚动列表,只要他开始滚动起来的工具栏会再次出现。



文章来源: Hiding the ActionBar on RecyclerView/ListView onScroll