it-roy-ru.com

Панель инструментов Android + Tab Layout + Drawer, Скрыть панель инструментов при прокрутке и взять TabLayout наверх

У меня есть деятельность, к которой прикреплен ящик. Каждое меню ящика представляет собой фрагмент, и в одном из меню у меня есть фрагмент с TabLayout, и каждая вкладка содержит RecyclerView. Теперь, когда я прокручиваю RecyclerView, макет вкладки скрывается, но ToolBar остается наверху. Мне нужно, чтобы ToolBar был скрыт (scrollFlags:scroll|enterAlways), а TabLayout должен отображаться вверху.

Итак, текущая настройка:

Activity with attached DrawerLayout -> Fragment with TabLayout -> Tab Fragment 1 with RecyclerView -> Tab Fragment 2 with RecyclerView

25
Vishal Pawale

Меньше кода более эффективно

Здравствуйте, @Vishal. Я нашел слишком много для вас. потому что я также ищу эту тему в ближайшее время.

Я нашел одну замечательную библиотеку с именем MaterialViewPager это полностью настраивается с тем, что вы хотите скрыть в режиме прокрутки.

Смотрите видео на https://www.youtube.com/watch?v=r95Tt6AS18c

 enter image description here

13
Vishal Patel

Можете ли вы использовать библиотеку поддержки дизайна? Это поведение встроено, чтобы делать именно то, что вы описали. Для этого используется 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:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:animateLayoutChanges="true"
    >
    <Android.support.design.widget.AppBarLayout
        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:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        <Android.support.design.widget.TabLayout
            Android:id="@+id/tabanim_tabs"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content" />
    </Android.support.design.widget.AppBarLayout>
    <Android.support.v4.view.ViewPager
        Android:id="@+id/tabanim_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:src="@drawable/ic_alarm_add_white_48dp"
        app:layout_anchor="@id/tabanim_viewpager"
        app:layout_anchorGravity="bottom|right|end"
        Android:layout_margin="16dp"
        />

</Android.support.design.widget.CoordinatorLayout>
8
Tyler Pfaff

Сначала вам нужно реализовать прослушиватель с прокруткой. Здесь вы можете найти пример HidingScrollListener. 

public abstract class HidingScrollListener extends RecyclerView.OnScrollListener {

    private static final float HIDE_THRESHOLD = 10;
    private static final float SHOW_THRESHOLD = 70;

    private int mToolbarOffset = 0;
    private boolean mControlsVisible = true;
    private int mToolbarHeight;
    private int mTotalScrolledDistance;
    private int previousTotal = 0;
    private boolean loading = true;
    private int visibleThreshold = 4;
    int firstVisibleItem, visibleItemCount, totalItemCount;
    private LinearLayoutManager layoutManager;

    public HidingScrollListener(Context context, LinearLayoutManager layoutManager) {
        mToolbarHeight = Tools.getToolbarHeight(context);
        this.layoutManager = layoutManager;
    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            if (mTotalScrolledDistance < mToolbarHeight) {
                setVisible();
            } else {
                if (mControlsVisible) {
                    if (mToolbarOffset > HIDE_THRESHOLD) {
                        setInvisible();
                    } else {
                        setVisible();
                    }
                } else {
                    if ((mToolbarHeight - mToolbarOffset) > SHOW_THRESHOLD) {
                        setVisible();
                    } else {
                        setInvisible();
                    }
                }
            }
        }

    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        clipToolbarOffset();
        onMoved(mToolbarOffset);

        if ((mToolbarOffset < mToolbarHeight && dy > 0) || (mToolbarOffset > 0 && dy < 0)) {
            mToolbarOffset += dy;
        }
        if (mTotalScrolledDistance < 0) {
            mTotalScrolledDistance = 0;
        } else {
            mTotalScrolledDistance += dy;
        }
        // for load more
        visibleItemCount = recyclerView.getChildCount();
        totalItemCount = layoutManager.getItemCount();
        firstVisibleItem = layoutManager.findFirstVisibleItemPosition();

        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false;
                previousTotal = totalItemCount;
            }
        }
        if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
            // End has been reached
            // Do something

            loading = true;
            onLoadMore();
        }
    }

    private void clipToolbarOffset() {
        if (mToolbarOffset > mToolbarHeight) {
            mToolbarOffset = mToolbarHeight;
        } else if (mToolbarOffset < 0) {
            mToolbarOffset = 0;
        }
    }

    private void setVisible() {
        if (mToolbarOffset > 0) {
            onShow();
            mToolbarOffset = 0;
        }
        mControlsVisible = true;
    }

    private void setInvisible() {
        if (mToolbarOffset < mToolbarHeight) {
            onHide();
            mToolbarOffset = mToolbarHeight;
        }
        mControlsVisible = false;
    }

    public abstract void onMoved(int distance);

    public abstract void onShow();

    public abstract void onHide();

    public abstract void onLoadMore();
}

Чем вам нужно изменить свой адаптер RecyclerView. Вам нужно добавить пустое представление в верхней части вашего RecyclerView так же высоко, как ваш Tolbar.

Вот пример макета для вашего пустого представления.

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="@dimen/abc_action_bar_default_height_material" />

Чем вам нужно переопределить методы getItemViewType и getITemCount вашего адаптера, как показано ниже.

@Override
    public int getItemViewType(int position) {
        if (isPositionHeader(position)) {
            return TYPE_HEADER;
        }
        return TYPE_ITEM;
    }

    private boolean isPositionHeader(int position) {
        return position == 0;
    }

    @Override
    public int getItemCount() {
        return mObjects.size() + 1;
    }

Затем метод onCreateViewHolder адаптера возвращает правильную компоновку для позиции вашего RecyclerView, как показано ниже:

 @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = null;
        switch (viewType) {
            case TYPE_HEADER:
                view = LayoutInflater.from(mContext).inflate(R.layout.layout_recycler_header, parent, false);
                return new RecyclerHeaderViewHolder(view);

            default:
                view = LayoutInflater.from(mContext).inflate(R.layout.row_recyclerview_category, parent, false);
                return new ViewHolder(view);
        }

    }

И, наконец, добавьте реализацию HidingScrollListener в RecyclerView, как показано ниже:

final int mToolbarHeight = Tools.getToolbarHeight(getActivity());
        RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        mRecyclerView.setAdapter(mAdapter);
        mViewPager.setPadding(mRecyclerView.getPaddingLeft(),
                mToolbarHeight,
                mRecyclerView.getPaddingRight(),
                mRecyclerView.getPaddingBottom());

        mHidingScrollListener = new HidingScrollListener(getActivity(), linearLayoutManager) {
            @Override
            public void onMoved(int distance) {
              mToolbarContainer.setTranslationY(-distance);
            }

            @Override
            public void onShow() {
                mToolbarContainer.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start();
            }

            @Override
            public void onHide() {
               mToolbarContainer.animate()
                        .translationY(-mToolbarHeight)
                        .setInterpolator(new AccelerateInterpolator(2))
                        .start();
            }

            @Override
            public void onLoadMore() {
            }
        };
        mRecyclerView.setOnScrollListener(mHidingScrollListener);

Я надеюсь, что я правильно понимаю вашу проблему, и моя реализация может помочь вам. 

Удачи.

Правка: Вы можете легко реализовать LoadMore и PullToRefresh реализацию этого решения. Вы можете добавить свой запрос API в loadMore . Есть сложная часть в PullToRefresh . После того, как вы обновите данные, очистите свои данные и адаптер уведомлений, не забывайте устанавливать visibleItemCount и totalItemCount 0 в вашей реализации скрытой прокрутки. Если вы не установите 0, после обновления ваша загрузка будет работать некорректно. Вы получите меньше данных, так как количество элементов в вашей нумерации страниц.

6
savepopulation

Вы можете попробовать следующее, которое я использовал, чтобы скрыть панель инструментов, и заставить представление прокрутки занимать весь экран для полного просмотра страницы в моем приложении.

Это так.

  1. Скрыть панель инструментов. 
  2. Получите ширину экрана вашего телефона и высоту.
  3. Сохраните макет вкладки Высота и ширина во временную переменную.
  4. Присвойте ширину экрана телефона и высоту макету вкладки.

Это можно сделать следующим образом:

getSupportActionBar().hide();    
int mwidth = getApplicationContext().getResources().getDisplayMetrics().widthPixels;
int mheight = getApplicationContext().getResources().getDisplayMetrics().heightPixels;
temp = (TabLayout) myfrag.getActivity().findViewById(R.id.TabLayout_genesis);
int getwidth = temp.getWidth();
int getheight = temp.getHeight();
temp.setMinimumHeight(mheight);
temp.setMinimumWidth(mwidth);

Надеюсь, поможет. 

2
HourGlass

У меня была та же архитектура в моем приложении, вот как я это делаю:

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

<Android.support.design.widget.AppBarLayout
    Android:id="@+id/appbar_layout"
    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/main_toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="?attr/actionBarSize"
    Android:background="@color/chat_primary_color"
    app:layout_scrollFlags="scroll|enterAlways"
    Android:elevation="4dp"/>

<Android.support.design.widget.TabLayout
    Android:id="@+id/tab_layout"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="?attr/colorPrimary"
    Android:elevation="6dp"
    Android:minHeight="?attr/actionBarSize"
    Android:layout_below="@id/main_toolbar"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</Android.support.design.widget.AppBarLayout>

<Android.support.v4.view.ViewPager
    Android:id="@+id/pager"
    Android:layout_width="match_parent"
    Android:layout_height="fill_parent"
    Android:layout_below="@id/appbar_layout"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    />
<Android.support.v4.widget.NestedScrollView
    Android:id="@+id/container_fragment"
    Android:layout_width="match_parent"
    Android:layout_height="fill_parent"
    Android:layout_below="@id/appbar_layout"
    Android:fillViewport="true"
    Android:foregroundGravity="center"
    app:layout_behavior=".FixedScrollingViewBehavior"
    />

ViewPager, используемый для вкладок, и NestedScrollView, используемый как FrameLayout для другого фрагмента, я показываю ViewPager для фрагментов, которым требуются вкладки, и скрываю NestedScrollView в другом случае.

Вы можете найти поведение здесь для NestedScrollView FixedScrollingViewBehavior

2
Context

Вы можете показать нам свой xml-код, если хотите найти ошибки, Ниже приведен мой общий код для тех, кто хочет реализовать панель инструментов, Drawer, Tab и RecycleView в своем приложении.

https://github.com/Gujarats/Android-Toolbar-Drawer-tab-recyvleview-

Надеюсь, поможет

2
Gujarat Santana

Насколько я знаю, в этом нет ничего полезного. Однако вы можете взглянуть на исходный код Google IO, особенно на BaseActivity. Ищите «автоматическое скрытие» или посмотрите на onMainContentScrolled

Чтобы скрыть панель инструментов, вы можете сделать что-то вроде этого:

toolbar.animate().translationY(-toolbar.getBottom()).setInterpolator(new AccelerateInterpolator()).start();

Если вы хотите показать это снова, вы звоните:

toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator()).start();

Найдено здесь: Панель инструментов Android Lollipop: как скрыть/показать панель инструментов при прокрутке?

1
Will Evers
Everyone is giving the code, "Talk is cheap, show me the code" right. 
I prefer not showing the code this time. 
I will talk. I do not recommand such a complicated activity.

DrawerLayout и TabLayout являются двумя основными методами навигации для Android. DrawerLayout и TabLayout, показанные в одном действии, действуют против линии гильдии разработки Android. И если вы сделаете это, ваше приложение будет очень трудно использовать. 

Представьте себе, что, если пользователь делает пролистывание влево-вправо, следует ли вам жестом перелистывать просмотр пейджера или раскладку ящика? Я вижу, что вы можете применить жест смахивания к ящику в выдвижном ящике, когда пользователь проведет пальцем по правой стороне действия, в противном случае вы можете применить жест к просмотру пейджера, но как убедиться, что пользователь знает это правило? 

Даже пользователи знают, как сильно ударить по вашей активности (в настоящее время пользователи могут иметь смысл), ваше приложение по-прежнему выглядит очень сложным.

Мое предложение 

 if you have less than 5 main menus, just use tablayout + actionbar, 
 if you have more than 5 main menus, use drawerlayout + actionbar. 
 you don't have to use both navigation in a row, you can still place the important actions to the actionbar right.
1
Daniel Martin Shum

Чтобы скрыть панель инструментов в любое время, вы можете использовать:

getSupportActionBar().hide();

для более подробного объяснения смотрите url1 или url2

0
Karan Khurana

Удалить макет координатора, используемый во вкладках. Используйте LinearLayout

0
droid1233