web-dev-qa-db-ja.com

Androidツールバー+タブレイアウト+引き出し、スクロール時にツールバーを非表示にし、TabLayoutを一番上に移動する

引き出しが付いているアクティビティがあります。引き出しの各メニューはフラグメントであり、メニューの1つの下には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アダプターを変更する必要があるより。 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にはトリッキーな部分があります。プルして更新した後、データを消去し、非表示スクロール実装でset visibleItemCountおよびtotalItemCountを0に設定することを忘れないようにアダプターに通知します。 0に設定しない場合、負荷を更新した後、それ以上は正しく動作しません。ページネーションでアイテムがカウントされると、データが少なくなります。

6
savepopulation

私の知る限り、これを構築するものは何もありません。ただし、Google IOソースコード、特にBaseActivityを参照してください。「自動非表示」を検索するか、onMainContentScrolledを参照してください。

ツールバーを非表示にするには、次のようにします。

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

もう一度表示したい場合は、次を呼び出します。

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

ここにあります: Android Lollipop toolbar:スクロール中にツールバーを非表示/表示する方法?

2
Will Evers

次のいずれかを試してみてください。ツールバーを非表示にするために使用しており、アプリケーション設計で全画面表示を行うためにスクロールビューに画面全体を表示させます。

以下の通りです。

  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と、他のタブにFrameLayoutとして使用されるNestedScrollViewフラグメント、私はタブを必要とするフラグメントのViewPagerを表示し、他の場合にはNestedScrollViewを非表示にします。

NestedScrollViewの動作はこちらで確認できます FixedScrollingViewBehavior

2
Context

バグを見つけたい場合は、XMLコードを表示できます。以下は、riアプリケーションにToolbar、Drawer、Tab、RecycleViewを実装したい人のための私のコードシェアです。

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

それが役に立てば幸い

2
Gujarat Santana
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の2つの主要なナビゲーションメソッドです。同じアクティビティで表示されるDrawerLayoutとTabLayoutは、Android開発ギルドラインに対して行います。そうすると、アプリの使用が非常に難しくなります。

ユーザーが右から左にスワイプした場合、pagerviewまたはdrawerlayoutでジェスチャーをスワイプする必要があると想像してください。ユーザーがアクティビティの右端からスワイプすると、スワイプジェスチャをドロワーレイアウトに適用できますが、そうでない場合はページャービューにジェスチャを適用できますが、ユーザーがこのルールを確実に確認するにはどうすればよいですか?

ユーザーがアクティビティをスワイプする方法を知っていても(最近ではユーザーは非常に理にかなっているかもしれません)、アプリはまだ非常に複雑に見えます。

私の提案は、

 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

いつでもツールバーを非表示にするには:

getSupportActionBar().hide();

詳細ビューについては url1 または url2

0
Karan Khurana

タブ付きアクティビティで使用されるコーディネーターレイアウトを削除します。 LinearLayoutを使用する

0
droid1233