1. 程式人生 > >Android關於CoordinatorLayout和ListView滑動衝突的解決(上滑ToolBar隱藏,下滑出現)

Android關於CoordinatorLayout和ListView滑動衝突的解決(上滑ToolBar隱藏,下滑出現)

最近專案中使用到了CoordinatorLayout這種佈局方式,搭配RecycleView,實現起來比較簡單,而且不用自己處理滑動事件,但是改為了ListView後發生了滑動衝突.

所以想到了以下解決方案:

1.使用事件分發,當ListView在Y軸滑動時,將事件交給CoordinatorLayout處理,無效!!!

2.取消ListView在Y軸的滑動,計算手指移動的距離,交給CoordinatorLayout來scroll,無效!!!

以上都不行,google了下,發現由於由於CoordinatorLayout實現NestedScrollingParent介面,RecycleView實現了NestedScrollingChild介面,所以就可以在NestedScrollingChildHelper的幫助下實現滑動聯動,知道了原因這就簡單了,讓我們的LIstView實現NestedScrollingChild介面,檢視下NestedScrollingChild介面的原始碼

**
 * This interface should be implemented by {@link android.view.View View} subclasses that wish
 * to support dispatching nested scrolling operations to a cooperating parent
 * {@link android.view.ViewGroup ViewGroup}.
 *
 * <p>Classes implementing this interface should create a final instance of a
 * {@link NestedScrollingChildHelper} as a field and delegate any View methods to the
 * <code>NestedScrollingChildHelper</code> methods of the same signature.</p>
 *
 * <p>Views invoking nested scrolling functionality should always do so from the relevant
 * {@link ViewCompat}, {@link ViewGroupCompat} or {@link ViewParentCompat} compatibility
 * shim static methods. This ensures interoperability with nested scrolling views on Android
 * 5.0 Lollipop and newer.</p>
 */
public interface NestedScrollingChild {
..............
}
看到開頭註釋中這樣一段話:
實現這個介面必須建立NestedScrollingChildHelper,並且將View的方法交給NestedScrollingChildHelper的同名方法來處理,所以我們就在自定義ListView中加入

public class MyListView extends ListView implements NestedScrollingChild{
 
private final NestedScrollingChildHelper mScrollingChildHelper;
 
public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mScrollingChildHelper = new NestedScrollingChildHelper(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setNestedScrollingEnabled(true);
        }
 
 
    }
 
 
    @Override
    public void setNestedScrollingEnabled(boolean enabled) {
        mScrollingChildHelper.setNestedScrollingEnabled(enabled);
    }
 
    @Override
    public boolean isNestedScrollingEnabled() {
        return mScrollingChildHelper.isNestedScrollingEnabled();
    }
 
    @Override
    public boolean startNestedScroll(int axes) {
        return mScrollingChildHelper.startNestedScroll(axes);
    }
 
    @Override
    public void stopNestedScroll() {
        mScrollingChildHelper.stopNestedScroll();
    }
 
    @Override
    public boolean hasNestedScrollingParent() {
        return mScrollingChildHelper.hasNestedScrollingParent();
    }
 
    @Override
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
                                        int dyUnconsumed, int[] offsetInWindow) {
        return mScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
                dxUnconsumed, dyUnconsumed, offsetInWindow);
    }
 
    @Override
    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
        return mScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
    }
 
    @Override
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
        return mScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
    }
 
    @Override
    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
        return mScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
    }
 
}

最後在xml佈局檔案中,在MyListView外層巢狀一層NestedScrollView即可
<android.support.v4.widget.NestedScrollView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:fillViewport="true"
                    app:layout_behavior="@string/appbar_scrolling_view_behavior">
                <com.dipaitv.widget.MyListView
                    android:id="@+id/listview"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
 
                </com.dipaitv.widget.MyListView>
                </android.support.v4.widget.NestedScrollView>