Barre d'Outils Android + Tab Layout + tiroir, cache la barre d'outils lors de la défilement et de prendre TabLayout vers le haut

j'ai activité qui a tiroir attaché à elle. Chaque menu du tiroir est un fragment, et sous l'un des menus j'ai un fragment avec TabLayout , et chaque onglet contient un RecyclerView . Donc maintenant, quand je fais défiler le RecyclerView , la mise en page de l'onglet se cache mais ToolBar reste en haut. Ce dont j'ai besoin, c'est de ToolBar pour me cacher( scrollFlags:scroll|enterAlways ), et TabLayout devrait apparaître en haut.

ainsi la configuration actuelle est:

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

24
demandé sur Vishal Pawale 2015-11-30 16:29:14

10 réponses

Moins Le Code Plus Efficace

Bonjour @Vishal j'ai trouvé trop pour vous. parce que je cherche aussi ce sujet avant un certain temps.

j'ai trouvé une bibliothèque brillante nommée MaterialViewPager c'est entièrement personnaliser avec ce que vous voulez cacher en mode scroll.

voir la vidéo sur https://www.youtube.com/watch?v=r95Tt6AS18c

enter image description here

12
répondu Vishal Patel 2016-01-04 10:20:49

pouvez-vous utiliser la bibliothèque de conception de soutien? Il a ce comportement intégré à faire exactement ce que vous avez décrit. Il utilise CoordinatorLayout pour accomplir ceci.

<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>
7
répondu Tyler Pfaff 2015-12-08 23:05:28

tout d'abord, vous devez mettre en œuvre un logiciel d'écoute. Ici vous pouvez trouver un exemple Hidingscrollistener.

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();
}

que vous avez besoin de modifier votre adaptateur RecyclerView. Vous devez ajouter une vue vide en haut de votre RecyclerView aussi haut que votre Tolbar.

Voici un exemple de mise en page pour votre vue vide.

<?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" />

que vous avez besoin pour remplacer les méthodes getItemViewType et getITemCount de votre adaptateur comme dessous.

@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;
    }

que dans la méthode adaptat's onCreateViewHolder retourner une mise en page appropriée pour la position de votre RecyclerView likew ci-dessous:

 @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);
        }

    }

et enfin ajouter votre implémentation Hidingscrollistener à votre RecyclerView comme ci-dessous:

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);

j'espère que je comprends votre problème correctement, et mon application peut vous aider.

bonne chance.

Edit: Vous pouvez mettre en œuvre LoadMore et PullToRefresh mise en œuvre facile à cette solution. Vous pouvez ajouter votre requête api à loadMore . Il y a une partie tricy dans PullToRefresh . Après avoir tiré pour rafraîchir, nettoyer vos données et notifier adaptateur ne pas oublier de mettre visibleItemCount et totalItemCount à 0 dans votre masquage exécution de rouleau. Si vous ne mettez pas à 0, après vous actualisé votre charge plus ne fonctionnera pas correctement. Vous obtiendrez moins de données que votre compte d'article dans votre pagination.

6
répondu savepopulation 2015-12-16 11:45:20

j'avais la même architecture dans mon application, c'est comme ça que je la fais:

<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"
    />

Le ViewPager utilisés pour les onglets et les NestedScrollView utilisé comme FrameLayout pour l'autre fragment, je montre le ViewPager pour les fragments qui a besoin d'onglets et je cache le NestedScrollView dans les autres cas.

vous pouvez trouver le comportement ici pour le NestedScrollView FixedScrollingViewBehavior

2
répondu Context 2015-12-03 20:23:11

vous pouvez essayer le suivant, que j'ai utilisé pour cacher la barre d'outils, et faire le scrollview prendre l'écran entier pour la lecture pleine page dans ma conception de l'application.

Il est comme suit.

  1. Cacher la barre d'outils.
  2. obtenez la largeur et la hauteur de votre écran.
  3. stocke la hauteur et la largeur de l'onglet à une variable temporaire.
  4. attribuer la largeur de l'écran du téléphone et Hauteur par rapport à la disposition de votre onglet.

cela peut se faire de la manière suivante:

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);

J'espère que ça aidera.

2
répondu HourGlass 2015-12-09 11:08:51

vous pouvez nous montrer votre code xml si vous voulez trouver vos bogues, ci-dessous est mon partage de code pour ceux qui veulent mettre en œuvre barre d'outils, tiroir, onglet, et RecycleView dans l'application theri.

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

j'Espère que ça aide

2
répondu Gujarat Santana 2015-12-09 14:14:13
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 et TabLayout sont les 2 principales méthodes de navigation pour android. DrawerLayout et TabLayout présentés dans une même activité font contre l'android developement guildline. Et si vous le faites de votre application sera très difficile à utiliser.

Imaginez que, si l'utilisateur fait un balayage à droite-gauche, devez-vous glisser geste le pagerview ou le drawerlayout? Je vois que vous pouvez appliquer le geste de glisser vers le drawerlayout lorsque l'utilisateur glisse de la droite-egde de la l'activité, sinon vous pouvez demander le geste à la pagerview, mais comment vous assurez-vous que l'utilisateur connaît cette règle?

même les utilisateurs savent glisser votre activité (les utilisateurs peuvent très avoir du sens de nos jours), votre application semble encore très compliquée.

ma suggestion est,

 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.
2
répondu Daniel Martin Shum 2015-12-10 09:20:34

pour autant que je sache, il n'y a rien de construit qui fasse cela pour vous. Cependant, vous pouvez jeter un coup d'oeil au code source Google IO, en particulier la BaseActivity. Rechercher "auto hide" ou regarder onMainContentScrolled

pour cacher la barre d'outils, vous pouvez faire quelque chose comme ceci:

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

si vous voulez le montrer à nouveau vous appelez:

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

trouvé ici: android lollipop toolbar: comment pour cacher/montrer la barre d'outils en faisant défiler?

1
répondu Will Evers 2017-05-23 12:26:26

pour cacher votre barre d'outils à tout moment vous pouvez utiliser:

getSupportActionBar().hide();

pour plus d'explication de la vue url1 ou url2

0
répondu Karan Khurana 2017-05-23 12:34:39

supprimer la disposition du coordonnateur utilisée dans l'activité tabbed. Utilisation LinearLayout

0
répondu droid1233 2018-08-09 17:47:23