1、自定义一个控件,用于包裹需要回滚的view,SpringBackLayout 代码如下:
package com.test.cellscroll;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Scroller;
public class SpringBackLayout extends FrameLayout {
private static final String TAG = "SpringBackLayout";
private Scroller mScroller;
public SpringBackLayout(Context context) {
this(context, null);
}
public SpringBackLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SpringBackLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mScroller = new Scroller(context);
}
@Override
public void computeScroll() {
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if(child != null){
child.setNestedScrollingEnabled(true);
}
super.addView(child, index, params);
}
@Override
public void removeView(View view) {
super.removeView(view);
}
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
return true;
}
@Override
public void onNestedScrollAccepted(View child, View target, int axes) {
super.onNestedScrollAccepted(child, target, axes);
mScroller.forceFinished(true);
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(target, dx, dy, consumed);
if(consumed != null){
dx -= consumed[0];
dy -= consumed[1];
}
int consumedx = computeNestedPreScroll(getScrollX(), dx);
int consumedy = computeNestedPreScroll(getScrollY(), dy);
if(consumed != null){
consumed[0] += consumedx;
consumed[1] += consumedy;
}
scrollBy(consumedx, consumedy);
}
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
smooteScrollBy(dxUnconsumed, dyUnconsumed);
}
@Override
public void onStopNestedScroll(View child) {
super.onStopNestedScroll(child);
if(getScrollX() != 0 || getScrollY() != 0){
mScroller.startScroll(getScrollX(), getScrollY(), -getScrollX(), - getScrollY());
invalidate();
}
}
@Override
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
return super.onNestedFling(target, velocityX, velocityY, consumed);
}
protected void smooteScrollBy(int dx, int dy){
dx = computeScrollBy(getScrollX(), dx);
dy = computeScrollBy(getScrollY(), dy);
scrollBy(dx, dy);
}
private int computeScrollBy(int start, int dur){
start = dur > 0 ? start : -start;
int result = (int) ((800f - start) / 1920 * dur);
if((dur > 0 && result < 0) || (dur < 0 && result > 0)){
return 0;
}
return result;
}
private int computeNestedPreScroll(int start, int dur){
if(start == 0){
return 0;
}
if((start < 0 && dur < 0) || (start > 0 && dur > 0)){
return 0;
}
int end = start + dur;
if((end < 0 && start < 0) || (end > 0 && start > 0)){
return dur;
}
return dur - end;
}
}
2、在布局文件中的应用,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<com.test.cellscroll.SpringBackLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<android.support.v7.widget.RecyclerView
android:id="@+id/viewRecycler"
android:layout_width="match_parent"
android:layout_height="126dp"
android:layout_marginTop="50dp"/>
</com.test.cellscroll.SpringBackLayout>
回滚效果已实现。