1. 程式人生 > >Android UI開發第四十篇——ScrollTricks介紹

Android UI開發第四十篇——ScrollTricks介紹

ScrollTricks是一個開源控制元件,實現了兩個簡單功能:

1、Quick Return:向上滑動時,View也向上滑動並且消失,當向下滑動時,View馬上出現。例如Google Now的搜尋功能。

2、Sticky:類似的同步滾動,特定的View最多滑動到頂部並保持固定不動。例如大眾點評或美團的“立即購買”功能。

<com.example.android.scrolltricks.ObservableScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <View style="@style/Item.Top" />

            <View android:id="@+id/placeholder"
                android:layout_width="match_parent"
                android:layout_height="@dimen/sticky_height" />

            <View style="@style/Item.Bottom" />
            <View style="@style/Item.Bottom.Alt" />
            <View style="@style/Item.Bottom" />
            <View style="@style/Item.Bottom.Alt" />
            <View style="@style/Item.Bottom" />
            <View style="@style/Item.Bottom.Alt" />

        </LinearLayout>

        <TextView android:id="@+id/sticky" style="@style/Item.Sticky" />

    </FrameLayout>

</com.example.android.scrolltricks.ObservableScrollView>


    ScrollTricks的兩個效果原理是兩個相同的View同在一個FrameLayout佈局,這裡是android:id="@+id/placeholder",android:id="@+id/sticky"兩個View。監控ScrollView的滑動,根據android:id="@+id/placeholder" View的位置控制android:id="@+id/sticky"View的位置。主要是對ScrollView滾動的Y值得監聽。

看一下sticky的實現:

public class StickyFragment extends Fragment implements ObservableScrollView.Callbacks {
    private TextView mStickyView;
    private View mPlaceholderView;
    private ObservableScrollView mObservableScrollView;

    public StickyFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater
                .inflate(R.layout.fragment_content, container, false);

        mObservableScrollView = (ObservableScrollView) rootView.findViewById(R.id.scroll_view);
        mObservableScrollView.setCallbacks(this);

        mStickyView = (TextView) rootView.findViewById(R.id.sticky);
        mStickyView.setText(R.string.sticky_item);
        mPlaceholderView = rootView.findViewById(R.id.placeholder);

        mObservableScrollView.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        onScrollChanged(mObservableScrollView.getScrollY());
                    }
                });

        return rootView;
    }

    @Override
    public void onScrollChanged(int scrollY) {
    	
    	Log.d("onScroll", "Y:"+scrollY+"|"+mPlaceholderView.getTop());
        mStickyView.setTranslationY(Math.max(mPlaceholderView.getTop(), scrollY));
    }

    @Override
    public void onDownMotionEvent() {
    }

    @Override
    public void onUpOrCancelMotionEvent() {
    }
}

ObservableScrollView的實現:

public class ObservableScrollView extends ScrollView {
    private Callbacks mCallbacks;

    public ObservableScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mCallbacks != null) {
            mCallbacks.onScrollChanged(t);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mCallbacks != null) {
            switch (ev.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    mCallbacks.onDownMotionEvent();
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    mCallbacks.onUpOrCancelMotionEvent();
                    break;
            }
        }
        return super.onTouchEvent(ev);
    }

    @Override
    public int computeVerticalScrollRange() {
        return super.computeVerticalScrollRange();
    }

    public void setCallbacks(Callbacks listener) {
        mCallbacks = listener;
    }

    public static interface Callbacks {
        public void onScrollChanged(int scrollY);
        public void onDownMotionEvent();
        public void onUpOrCancelMotionEvent();
    }
}


下載:

/*** @author 張興業*  http://blog.csdn.net/xyz_lmn*/