나는 CoordinatorLayout
두 아이들이, 헤더 역할을하는 View
과 RecyclerView
:사용자 정의 CoordinatorLayout.Behavior 및 RecyclerView 스크롤 문제
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
app:layout_behavior="some.package.AlphaBehavior">
<ImageView
android:id="@+id/header_iv"
style="@style/some_style"/>
<TextView
android:id="@+id/header_retails_tv"
style="@style/some_style_tv"
android:text="@string/some_text"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
</android.support.design.widget.CoordinatorLayout>
나는 헤더와 I의 크기에 RecyclerView
에 동적으로 패딩을 설정 clipToPadding
을 false
으로 설정하면 RecyclerView
이 헤더 아래에 표시되고 사용자가 위로 스크롤하면 RecyclerView
이 헤더보기 위에 표시됩니다.
내가 list
까지 사용자가 스크롤 및 헤더가있을 때 페이드가 볼 수 있도록 할 때 다시보기에서 페이드를 달성하기 위해 사용자 정의 CoordinatorLayout.Behavior
를 만들어의 AlphaBehavior
:
public class AlphaBehavior extends CoordinatorLayout.Behavior {
private float alpha = 1.0f;
private float scrolly = 0.f;
private int headerSize = 0;
private Animation defaultFadeInAnimation;
public AlphaBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
defaultFadeInAnimation = AnimationUtils.loadAnimation(context, android.R.anim.fade_in);
}
public void setHeaderSize(int headerSize) {
this.headerSize = headerSize;
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof RecyclerView;
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
scrolly += dyConsumed;
Log.d(Constants.TAG, dyConsumed + "/" + dyUnconsumed + "/" + scrolly);
float totalScrollY = ((RecyclerView)target).computeVerticalScrollOffset();
Log.d(Constants.TAG, "totalScrollY:" + totalScrollY);
alpha = (headerSize - totalScrollY)/headerSize;
if (alpha < 0.f) alpha = 0.f;
if (alpha > 1.0f) alpha = 1.f;
if (dyConsumed < 0 && totalScrollY > headerSize) {
alpha = 0.f;
}
Log.d(Constants.TAG, "alpha:" + alpha);
child.setAlpha(alpha);
}
@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
int pos = ((LinearLayoutManager)((RecyclerView)target).getLayoutManager()).findFirstCompletelyVisibleItemPosition();
Log.d(Constants.TAG, "pos:" + pos);
if (pos == 0 && child.getAlpha() == 0.f) {
child.startAnimation(defaultFadeInAnimation);
}
}
// overriding this in case we don't the other events are not called
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
}
그러나 나는 문제에 직면하고있다 : 사용자가 스크롤을 매우 빠르게하면 행동의 이벤트가 올바르게 호출되지 않는다. scrollY
회원은 전체 스크롤과 관련이 없으며 totalScrollY
회원 (RecyclerView
스크롤을 계산하여 얻음)이 올바르지 않습니다. onStopNestedScroll
이벤트에서 firstCompletelyVisibleItem
을 찾으려고 시도했지만 recyclerView
이 목록 시작 부분에 도달하면 2 또는 3 위치를 반환합니다.
하여 확인하시기 바랍니다을 나는 어쩌면 누군가를 위해 유용 코드를 넣어 이안 레이크의 [대답] (https://medium.com/@ianhlake/flings-are-definitely-quite-a-bit-different-from- regular-scrolling-in-being-muchless-fine-grained-3dfc82062aaf). – wonsuc