我的活动附有抽屉。抽屉的每个菜单都是一个片段,在其中一个菜单下我有一个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
答案 0 :(得分:13)
更少代码更有效
你好@Vishal我发现你太多了。因为我也在一段时间之前搜索这个主题。
我找到了一个名为MaterialViewPager的精彩库,它完全可以自定义你想要在滚动模式中隐藏的内容。
上的视频答案 1 :(得分:8)
您可以使用支持设计库吗?它内置了这种行为,可以完全按照您的描述进行操作。它使用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>
答案 2 :(得分:6)
首先,您需要实现滚动侦听器。在这里您可以找到一个示例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最高的RecyclerView顶部。
以下是空视图的示例布局。
<?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,则在刷新负载后,更多将无法正常工作。在您的分页中,您的项目数量会减少。
答案 3 :(得分:2)
我的应用程序中有相同的架构,我是如何做到的:
<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
的行为答案 4 :(得分:2)
如果你想找到你的bug,你可以告诉我们你的xml代码, 以下是我想要在theri应用程序中实现Toolbar,Drawer,Tab和RecycleView的人的代码共享。
https://github.com/Gujarats/Android-Toolbar-Drawer-tab-recyvleview-
希望有所帮助
答案 5 :(得分:2)
您可以尝试使用以下隐藏工具栏的以下内容,并使滚动视图占据整个屏幕,以便在我的应用程序设计中读取整页。
如下。
这可以通过以下方式完成:
<select id="roles" name="roles" path="roles">
<option value="NONE">Select</option>
<c:forEach items="${rolesList}" var="role">
<option value="${role.role_id}">${role.role}</option>
</c:forEach>
</select>
希望它有所帮助。
答案 6 :(得分:1)
据我所知,没有什么可以为你做的。但是,您可以查看Google IO源代码,尤其是BaseActivity。搜索“自动隐藏”或查看onMainContentScrolled
为了隐藏工具栏,您可以执行以下操作:
toolbar.animate().translationY(-toolbar.getBottom()).setInterpolator(new AccelerateInterpolator()).start();
如果您想再次显示,请致电:
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator()).start();
在此处找到:android lollipop toolbar: how to hide/show the toolbar while scrolling?
答案 7 :(得分:1)
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 developpement guildline。如果你这样做,你的应用程序将很难使用。
想象一下,如果用户进行左右滑动,是否应该向pagerview或者drawerlayout滑动手势?我看到当用户从活动的右侧滑动时,您可以将滑动手势应用于drawerlayout,否则您可以将手势应用于pagerview,但是如何确保用户知道此规则?
即使用户知道如何刷你的活动(用户现在可能很有意义),您的应用仍然看起来非常复杂。
我的建议是,
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.
答案 8 :(得分:0)
答案 9 :(得分:0)
删除选项卡活动中使用的协调器布局。使用LinearLayout