Android中ScrollView如何監聽滑動距離(總結)
阿新 • • 發佈:2018-12-18
需求:想實現像美團中列表下拉後出現懸浮窗的效果。
思路:首先對ScrollView進行滑動監聽,然後在onScrollChanged()方法中獲取到滑動的Y值,接著進行相關操作即可。
實現步驟:
1、自定義MyScrollView
(1)重寫onScrollChanged()獲取Y值。
(2)自定義滑動監聽介面onScrollListener並公開此介面。
public class MyScrollView extends ScrollView { private OnScrollListener onScrollListener; public MyScrollView(Context context) { super(context); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected int computeVerticalScrollRange() { return super.computeVerticalScrollRange(); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (onScrollListener != null) { onScrollListener.onScroll(t); } } /** * 介面對外公開 * @param onScrollListener */ public void setOnScrollListener(OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } /** * * 滾動的回撥介面 * * @author xiaanming * */ public interface OnScrollListener{ /** * 回撥方法, 返回MyScrollView滑動的Y方向距離 * @param scrollY * 、 */ void onScroll(int scrollY); } }
2、佈局檔案如下:
(主要是建立兩個相同的佈局,頂部一個,相應的位置一個,後面有用)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:id="@+id/parent_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> <com.deepreality.myscrollviewxfdemo.MyScrollView android:id="@+id/Main_SView" android:layout_width="match_parent" android:layout_height="wrap_content"> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="150dp" android:scaleType="fitXY" android:src="@mipmap/img2" /> <RelativeLayout android:id="@+id/Main_rView1" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/colorWhite"> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:padding="10dp" android:scaleType="fitXY" android:src="@mipmap/icon_user_nickname" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="你好" android:layout_centerInParent="true"/> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:padding="10dp" android:scaleType="fitXY" android:src="@mipmap/tips" /> </RelativeLayout> <ImageView android:layout_width="match_parent" android:layout_height="150dp" android:layout_marginTop="10dp" android:scaleType="fitXY" android:src="@mipmap/img2" /> ……(程式碼省略) </LinearLayout> <RelativeLayout android:id="@+id/Main_rView" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/colorWhite"> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:padding="10dp" android:scaleType="fitXY" android:src="@mipmap/icon_user_nickname" /> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:padding="10dp" android:scaleType="fitXY" android:src="@mipmap/tips" /> </RelativeLayout> </FrameLayout> </com.deepreality.myscrollviewxfdemo.MyScrollView> </LinearLayout>
3、MainActivity.java的程式碼如下:
public class MainActivity extends AppCompatActivity implements MyScrollView.OnScrollListener { private Context mContext; private RelativeLayout rTopView, rView1; private MyScrollView myScrollView; private LinearLayout lLayoutParent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); baseDataInit(); bindViews(); viewsAddListener(); } private void baseDataInit() { mContext = this; } private void bindViews() { rTopView = findViewById(R.id.Main_rView); rView1 = findViewById(R.id.Main_rView1); myScrollView = findViewById(R.id.Main_SView); lLayoutParent = findViewById(R.id.parent_layout); } private void viewsAddListener() { //當佈局的狀態或者控制元件的可見性發生改變回調的介面 lLayoutParent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //這一步很重要,使得上面的購買佈局和下面的購買佈局重合 onScroll(myScrollView.getScrollY()); } }); myScrollView.setOnScrollListener(this); } @Override public void onScroll(int scrollY) { int mBuyLayout2ParentTop = Math.max(scrollY, rView1.getTop()); rTopView.layout(0, mBuyLayout2ParentTop, rTopView.getWidth(), mBuyLayout2ParentTop + rTopView.getHeight()); } }
其中,onScroll()介面方法中監聽到的是垂直方向滑動的距離Y,可以根據自己的需要進行佈局的其他操作。