我在RecyclerView
内有ViewPager
只占据屏幕的下半部分,而我想要做的是在RecyclerView
收到垂直滚动事件。
UI层次结构简而言之:
CoordinatorLayout
--- AppBarLayout
--- Toolbar
--- Bunch of static LinearLayouts, occupy most of screen
--- TabLayout
--- ViewPager
--- Fragments with RecyclerView
我有什么:
根据我的理解,RecyclerView
具有内存效率,并试图适应屏幕中可用的任何空间。在我的应用中,我有一个ViewPager
托管多个标签,每个标签都有RecyclerView
来显示不同的内容。
你能否告诉我一些关于如何使整个屏幕滚动的想法?我猜测最佳镜头是为屏幕中间的静态内容添加一个带有视差的CollapsingToolbarLayout
。我甚至试图这样做,但UI完全被打破了。这很困难,因为我只希望屏幕中间的内容滚动出来,而不是顶部的工具栏。我对NestedScrollView
也没有太大的运气,显然它与ViewPager
和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.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_contributor"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:focusableInTouchMode="true">
<android.support.v7.widget.SearchView
android:id="@+id/searchview_contributor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:icon="@drawable/ic_search_white_24dp"
app:defaultQueryHint="Bla bla"
app:iconifiedByDefault="false"/>
<ImageButton
android:layout_width="24dp"
android:layout_height="24dp"
android:background="@android:color/transparent"
android:src="@drawable/ic_person_outline_black_24dp"/>
</android.support.v7.widget.Toolbar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:text="La Bla"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:text="Bla Bla"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
>
<!-- Bunch of stuff, but irrelevant -->
<android.support.design.widget.TabLayout
android:id="@+id/tablayout_profile"
android:layout_width="match_parent"
android:layout_height="40dp"/>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager_profile"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Viewpager中的片段:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview_photos"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
提前致谢!
更新:我在这里收到的回复(感谢我的回复)来得太晚了。如果有人知道哪个是正确的答案,请告诉我!
答案 0 :(得分:3)
public class CustomRecyclerView extends RecyclerView {
public CustomRecyclerView(Context context) {
super(context);
}
public CustomRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
int lastEvent = -1;
boolean isLastEventIntercepted = false;
private float xDistance, yDistance, lastX, lastY;
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
lastX = e.getX();
lastY = e.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = e.getX();
final float curY = e.getY();
xDistance += Math.abs(curX - lastX);
yDistance += Math.abs(curY - lastY);
lastX = curX;
lastY = curY;
if (isLastEventIntercepted && lastEvent == MotionEvent.ACTION_MOVE) {
return false;
}
if (xDistance > yDistance) {
isLastEventIntercepted = true;
lastEvent = MotionEvent.ACTION_MOVE;
return false;
}
}
lastEvent = e.getAction();
isLastEventIntercepted = false;
return super.onInterceptTouchEvent(e);
}
}
这样就可以改变您的Recyclerview。
答案 1 :(得分:1)
我用CollapsingToolbarLayout
完成了与此类似的事情。
这里的技巧是拥有两个工具栏,一个位于顶部,一个位于searchview,另一个位于专用于折叠布局的工具栏上。
您的searchview工具栏将包含app:collapseMode="pin"
。
您的按钮栏将显示app:collapseMode="pin"
。
按钮栏下方的LinearLayout将具有默认的折叠模式,因此它将滚动。你甚至可以用app:collapseMode="parallax"
给它一个视差效果。
您的TabLayout
将app:collapseMode="pin"
,因此它会在按钮栏下方向上滚动并固定在那里。
您的ViewPager
应位于CollapsingToolbarLayout
之外且属性为app:layout_behavior="@string/appbar_scrolling_view_behavior"
。
CollapsingToolbarLayout
会想要显示标题。只需在折叠工具栏上调用setTitle(null)
,然后在searchview工具栏上设置真实标题即可。
您可以将导航和菜单放在searchview工具栏和折叠工具栏上,它们应该按预期工作。
我稍后会发布一些XML;我只是想开始这个答案。
答案 2 :(得分:1)
看起来您只是错过了app:layout_scrollFlags
属性。您应该将它添加到Toolbar
和线性页眉布局中。例如,您可以使用:app:layout_scrollFlags="scroll|enterAlways"
如我所见,您的ViewPager
已经app:layout_behavior="@string/appbar_scrolling_view_behavior"
,在您指定scrollFlags