Как сделать Recycler View не прокручивать, когда appbar защелкивается

Я сделал привязку панели приложений следующим образом:

enter image description here

обратите внимание, что когда свиток остается посередине (i.e заголовок наполовину виден, затем панель приложения автоматически защелкивается)

в случае Google play это то, что оснастка выглядит так:

enter image description here

теперь я хочу, чтобы оснастка работала как в google play. То есть, когда происходит привязка, только панель приложений должна snap и представление recycler не должны перемещаться. Было бы лучше, если бы решение также поддерживало устройства pre lollipop.

спасибо!

4 ответов


я нашел решение, которое хорошо работает в моем проекте. Он состоит из 2 поведений, один для AppBarLayout и другой для контейнера прокрутки. Вы можете найти его на GitHub здесь: appbar-snap-поведение

его довольно легко установить:

compile "com.github.godness84:appbar-snap-behavior:0.1.1"

не забудьте добавить maven { url "https://jitpack.io" } в корень сборки.gradle в конце репозиториев:

allprojects {
        repositories {
            ...
            maven { url "https://jitpack.io" }
        }
}

затем:

  1. добавить app:layout_behavior="com.github.godness84.appbarsnapbehavior.AppBarSnapBehavior" в свой AppBarLayout
  2. использовать app:layout_behavior="com.github.godness84.appbarsnapbehavior.ScrollingViewBehavior" в контейнер прокрутки.

к сожалению, поскольку поведение AppBarLayout по умолчанию заменено, некоторые функции больше не доступны (например AppBarLayout.setExpanded ()), но нормальный ситуациях это работает! Попробуй и дай мне знать.


посмотреть мою библиотеку Выдвижная Панель Инструментов

вы должны добавить это build.gradle

compile 'it.michelelacorte.retractabletoolbar:library:1.0.0'

, чем в MainActivity.java использовать RecyclerView и так:

RetractableToolbarUtil.ShowHideToolbarOnScrollingListener showHideToolbarListener;
recyclerView.addOnScrollListener(showHideToolbarListener = new RetractableToolbarUtil.ShowHideToolbarOnScrollingListener(toolbar));

if (savedInstanceState != null) {
            showHideToolbarListener.onRestoreInstanceState((RetractableToolbarUtil.ShowHideToolbarOnScrollingListener.State) savedInstanceState
                    .getParcelable(RetractableToolbarUtil.ShowHideToolbarOnScrollingListener.SHOW_HIDE_TOOLBAR_LISTENER_STATE));
}

это эффект:

enter image description here

EDIT:

С 23.1.0 Design library вы можете добавить |snap атрибут компоновки панели инструментов:

       <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways|snap />

он должен быть более или менее то, что вы выглядящий.


Привет используйте нижеприведенный макет он будет работать точно так же, как приложение google play store, которое я тестировал

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="@dimen/appbar_padding_top"
    android:theme="@style/AppTheme.AppBarOverlay">

    <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|snap"
        app:popupTheme="@style/AppTheme.PopupOverlay">

    </android.support.v7.widget.Toolbar>

    <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/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

также обратите внимание, что я использовал следующую библиотеку поддержки дизайна

compile 'com.android.support:design:23.1.1'

дайте мне знать, в случае каких-либо вопросов я, безусловно, поможет вам в этом.


мне удалось "обойти" проблему.

Я создал абстрактный класс, используйте его в своих проектах !

ЭТО МАКЕТ:

<FrameLayout
    android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
        >

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="@dimen/status_bar_height" />

        <FrameLayout
            android:id="@+id/appBarLayout"
            android:layout_width="match_parent"
            android:layout_height="@dimen/status_bar_app_bar"
            android:background="@color/appbar"
            >

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_marginTop="@dimen/status_bar_height"
                android:background="@color/appbar" />

            <android.support.design.widget.AppBarLayout 
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:layout_gravity="bottom"
                android:background="@color/appbar"
                />

        </FrameLayout>

    </FrameLayout>

framelayout будет вашим" новым " appbar.

затем ваши фрагменты (те, что в viewpager) должны расширить этот класс:

public abstract class SnappableAppBarFragment extends Fragment {

    public int scrollAttuale;
    private boolean attivaSnap = true;
    private boolean isTouching = false;

    public void setSnapActivated(boolean state){attivaSnap = state;}

    public void setUpSnappableAppbar(final View fragMainView, final NestedScrollView nestedScrollView, final FrameLayout appBar, final int actionBarHeight) {
        nestedScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {
                if (!attivaSnap)
                    return;
                int scrollY = nestedScrollView.getScrollY();
                int differenza = scrollAttuale - scrollY;
                if (differenza > 0 && appBar.getY() < 0) {
                    //Esci
                    appBar.animate().translationYBy(differenza).setDuration(0).start();
                    if (appBar.getY() > 0) {
                        appBar.animate().translationY(0).setDuration(0).start();
                    }
                }
                if (differenza < 0 && appBar.getY() > -actionBarHeight) {
                    //Entra
                    appBar.animate().translationYBy(differenza).setDuration(0).start();
                    if (appBar.getY() < -actionBarHeight)
                        appBar.animate().translationY(-actionBarHeight).setDuration(0).start();
                }

                if (differenza >= -2 && differenza <= 2 && !isTouching ){
                    int spazioTot = actionBarHeight;
                    if ((Math.abs(appBar.getY()) < spazioTot / 2 || nestedScrollView.getScrollY() <= 200) && appBar.getY() != 0) {
                        //Espandi
                        appBar.animate().translationY(0).setDuration(270).start();
                    } else if (appBar.getY() != 0) {
                        //Chiudi
                        appBar.animate().translationY(-actionBarHeight).setDuration(270).start();
                    }
                }
                scrollAttuale = scrollY;
                //Scrolling verso l'alto differenza è positiva
                //Scrolling verso il basso differenza è negativa
            }
        });
        fragMainView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (!attivaSnap)
                    return false;

                if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                    isTouching = false;
                    Handler handler = new Handler();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            int spazioTot = actionBarHeight;
                            //   && nestedScrollView.getScrollY() <= 200  && nestedScrollView.getScrollY() <= 200   && nestedScrollView.getScrollY() <= 200
                            if ((Math.abs(appBar.getY()) < spazioTot / 2 || nestedScrollView.getScrollY() <= 200) && appBar.getY() != 0) {
                                //Espandi
                                appBar.animate().translationY(0).setDuration(270).start();
                            } else if (appBar.getY() != 0) {
                                //Chiudi
                                appBar.animate().translationY(-actionBarHeight).setDuration(270).start();
                            }
                        }
                    }, 0);
                }
                if (motionEvent.getAction() == MotionEvent.ACTION_DOWN || motionEvent.getAction() == MotionEvent.ACTION_SCROLL) {
                    isTouching = true;
                }
                return false;
            }
        });
    }
}

и, наконец, фрагментами:

 public class Fragment1 extends SnappableAppBarFragment {

          ...

        @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                     Bundle savedInstanceState) {
                // Inflate the layout for this fragment
                viewPrincipale = inflater.inflate(R.layout.fragment_home, container, false);

                mainActivity = (MainActivity) getActivity();

                setUpSnappableAppbar(viewPrincipale, (NestedScrollView) viewPrincipale.findViewById(R.id.nestedScrollView), parentAppBar, actionBarHeight);

        ...

        }

        public void setParentAppBar(FrameLayout frameLayout) {
            parentAppBar = frameLayout;
        }

        public void setActionBarHeight(int height) {
            actionBarHeight = height;
        }   
        ...
    }

В конце концов, при объявлении фрагментов установите parentappbar и actionbarheight из активность:

fragment1.setParentAppBar((FrameLayout) findViewById(R.id.appBarLayout));
fragment1.setActionBarHeight(toolbar.getLayoutParams().height);

вот это, извините, если это долго, но это единственный способ я нашел, чтобы заставить его работать !

кроме того, извините за плохой английский, я итальянский разработчик :P Пока!--5-->

EDIT: ВАЖНО!! Изменение в SNAPPABLEAPPBARFRAGMENT это: final int actionBarHeight для окончательного поплавка actionBarHeight !!! ЭТО БУДЕТ БОЛЕЕ ГЛАДКО: D