and*_*per 10 android resize material-design android-recyclerview
在Lollipop的手机应用程序中,当您到达"最近"或"联系人"选项卡,并且您尝试滚动时,首先发生的事情是调整上部区域的大小,其中包括最近的事件和搜索框,如下所示:

如果RecyclerView上有超过3个项目,只要上部区域可以缩小到最小尺寸,RecyclerView就不会向下滚动.
向上滚动也是如此:只要上部区域没有完全放大,RecyclerView就不会向上滚动.
我找不到实现此功能的最佳方法.
更具体地说,我对上部区域的大小调整有一个问题,因此它将在Lollipop上运行时一样平滑.
为了简化,我只需要调整屏幕的一部分,而不是手机的应用程序("最近的事件"和搜索框)上显示的2.
我尝试过多种方法:
使RecyclerView变得像整个屏幕一样大,同时拥有一个假的,大的空头.当我滚动时,我还将"translationY"设置为顶部的真实内容.这有一个问题,显示滚动条作为上部区域的一部分(我想在正确的位置显示滚动条).此外,由于您必须处理其他页面的RecyclerViews滚动值,因此它非常复杂.这是一个类似于某些第三方库的解决方案,例如这个(在这里我使用了布局而不是ImageView,但代码几乎相同).
与2相同,但我更改了视图的scaleY,而不是更改LayoutParams.
对于#2和#3,问题是在某些情况下,只要我在某个值中滚动+ Y的事件,我也会得到相同值的-Y滚动(反之亦然) ,使调整大小效果的处理"跳跃"(上下,即使用户滚动得很好).
我猜测为什么会这样,当我移动RecyclerView时,用户做的下一个事件与原始事件完全不同,因为我改变了RecyclerView的定位方式或大小.
我尝试过使用setOnTouchListener(甚至与GestureDetectorCompat一起)和setOnScrollListener.所有这些都引起了同样奇怪的问题.
我该如何解决这个问题?为什么会发生,为什么不总是发生?
编辑:我试图改变#2,所以我不会处理RecyclerView的触摸事件,而是处理其容器的触摸事件(一些LinearLayout).由于某种原因,容器没有响应触摸事件,所以我用RelativeLayout替换它,并在该布局内的所有内容上放置一个视图,这将响应触摸事件(并相应地更改上部区域).这很有效,但是在需要时我无法将事件进一步传递给子视图.
我认为最好的事情是自定义RecyclerView(扩展它)触摸处理.也许添加一个用于滚动的监听器,当RecyclerView即将滚动时,它会询问它是否正常,如果没有,它将不会尝试滚动直到触发事件被触发并重置其状态.
好的,一种解决方案(我仍然不喜欢,但有效)是使用一个“ TouchInterceptionFrameLayout ”类(来自我找到的库),它允许您决定何时允许滚动,何时不允许滚动,当它不应该滚动时,您可以更改同时具有分页选项卡和 ViewPager 的布局的填充(或您希望的内容)。
viewPager&tabs 的容器覆盖整个区域,并且具有变化的填充。
这是布局:
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<!-- put upper content here -->
</LinearLayout>
<LinearLayout
android:id="@+id/pagerAndTabsContainer"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.astuetz.PagerSlidingTabStrip
android:id="@+id/viewPagerSlidingTabsStrip"
android:layout_width="match_parent"
android:background="@color/default_background"
android:layout_height="48dip"/>
<android.support.v4.view.ViewPager
android:background="@color/default_background"
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout>
Run Code Online (Sandbox Code Playgroud)
然后,您需要一些初始化代码(当布局阶段完成并且您可以获得视图的实际大小时):
// the upper area height, that can be shrunk to a size of 0 height when needed
mResizeableViewHeight = mHeaderView.getHeight();
// set initial padding if you wish to show the upper area by default
mPagerAndTabsContainer.setPadding(0, mResizeableViewHeight, 0, 0);
prepareViewPager(mViewPager); // set the pages and fragments...
// init the "TouchInterceptionFrameLayout" to handle touch events
mContentView.setScrollInterceptionListener(mInterceptionListener);
Run Code Online (Sandbox Code Playgroud)
在 TouchInterceptionFrameLayout.TouchInterceptionListener 的“shouldInterceptTouchEvent”函数上,您决定何时应该阻止触摸,并且在此接口的“onMoveMotionEvent”上,您应该处理被阻止的触摸。
对于每个具有 recyclerView 的片段,使用ObservableRecyclerView代替,并调用以下行:
// get the fragment that shows the screen I've made (with the layout)
Fragment fragment = getTargetFragment();
// let the recyclerView handle filtered touches
mRecyclerView.setTouchInterceptionViewGroup(((IGetContainer) fragment).getContainer());
// if you wish to put animations when you do a touch-up event, this may be handy (or use onUpOrCancelMotionEvent of the "TouchInterceptionListener" too/instead ) :
if (fragment instanceof ObservableScrollViewCallbacks)
mRecyclerView.setScrollViewCallbacks((ObservableScrollViewCallbacks) fragment);
Run Code Online (Sandbox Code Playgroud)
我不太喜欢这个解决方案,因为它用触摸包装覆盖了整个屏幕,因为它导致 viewPager 的过度绘制(并要求您为其设置背景),并且因为它与我的相比有点复杂心里。无论我如何使用滚动规则,它也比 Lollipop 的电话应用程序流畅得多。
我可以让 TouchInterceptionListener 开始处理触摸事件,前提是它们源自 RecyclerView,但这使得它的复杂性变得更糟。
| 归档时间: |
|
| 查看次数: |
1197 次 |
| 最近记录: |