您好,登錄后才能下訂單哦!
我之前寫了一篇關于美團網,大眾點評的購買框效果的文章Android對ScrollView滾動監聽,實現美團、大眾點評的購買懸浮效果,我自己感覺效果并不是很好,如果快速滑動界面,顯示懸浮框的時候會出現一卡的現象,有些朋友說有時候會出現兩個布局的情況,特別是對ScrollView滾動的Y值得監聽,我還使用了Handler來獲取,還有朋友給我介紹了Scrolling Tricks這個東西,我下載試了下,確實美團網,大眾點評的購買框用的是這種效果,但是Scrolling Tricks只能在API11以上使用,這個有點小悲劇,然后我做了下修改,并將實現思路分享給大家,實現起來很簡單
首先還是要先對ScrollView進行滾動監聽,直接在onScrollChanged()方法中就能獲取滾動的Y值,之前那篇文章使用了Handler,走彎路了,直接看代碼吧
package com.example.meituandemo; import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; /** * @blog http://blog.csdn.net/xiaanming * * @author xiaanming * */ public class MyScrollView extends ScrollView { private OnScrollListener onScrollListener; public MyScrollView(Context context) { this(context, null); } public MyScrollView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * 設置滾動接口 * @param onScrollListener */ public void setOnScrollListener(OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } @Override public 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); } } /** * * 滾動的回調接口 * * @author xiaanming * */ public interface OnScrollListener{ /** * 回調方法, 返回MyScrollView滑動的Y方向距離 * @param scrollY * 、 */ public void onScroll(int scrollY); } }
接下來看看主界面的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/parent_layout" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageView1" android:layout_width="match_parent" android:layout_height="45dip" android:scaleType="centerCrop" android:src="@drawable/navigation_bar" /> <com.example.meituandemo.MyScrollView android:id="@+id/scrollView" android:layout_width="fill_parent" android:layout_height="fill_parent" > <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:id="@+id/iamge" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/pic" android:scaleType="centerCrop" /> <include android:id="@+id/buy" layout="@layout/buy_layout" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/one" android:scaleType="centerCrop" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/one" android:scaleType="centerCrop" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/one" android:scaleType="centerCrop" /> </LinearLayout> <include android:id="@+id/top_buy_layout" layout="@layout/buy_layout" /> </FrameLayout> </com.example.meituandemo.MyScrollView> </LinearLayout>
下面是布局的效果圖:
從主界面的布局你可以看出,我們在上面放置了一個購買的布局,可能你會想,先讓上面的布局隱藏起來,等下面的布局滑動上來就將其顯示出來,如果這樣子就跟我之前寫的那篇文章差不多,效果不是很棒,所以這篇修改版的肯定不是這樣子的,我們還是先看主界面的代碼吧
package com.example.meituandemo; import android.app.Activity; import android.os.Bundle; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.LinearLayout; import com.example.meituandemo.MyScrollView.OnScrollListener; /** * @blog http://blog.csdn.net/xiaanming * * @author xiaanming * */ public class MainActivity extends Activity implements OnScrollListener{ /** * 自定義的MyScrollView */ private MyScrollView myScrollView; /** * 在MyScrollView里面的購買布局 */ private LinearLayout mBuyLayout; /** * 位于頂部的購買布局 */ private LinearLayout mTopBuyLayout; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myScrollView = (MyScrollView) findViewById(R.id.scrollView); mBuyLayout = (LinearLayout) findViewById(R.id.buy); mTopBuyLayout = (LinearLayout) findViewById(R.id.top_buy_layout); myScrollView.setOnScrollListener(this); //當布局的狀態或者控件的可見性發生改變回調的接口 findViewById(R.id.parent_layout).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //這一步很重要,使得上面的購買布局和下面的購買布局重合 onScroll(myScrollView.getScrollY()); } }); } @Override public void onScroll(int scrollY) { int mBuyLayout2ParentTop = Math.max(scrollY, mBuyLayout.getTop()); mTopBuyLayout.layout(0, mBuyLayout2ParentTop, mTopBuyLayout.getWidth(), mBuyLayout2ParentTop + mTopBuyLayout.getHeight()); } }
主界面就短短的幾行代碼,可能看完這些代碼你還是沒有明白到底是怎么做到的,沒關系,我給大家說說,其實我們是讓上面的購買布局和下面的購買布局重合起來了,layout()這個方法是確定View的大小和位置的,然后將其繪制出來,里面的四個參數分別是View的四個點的坐標,他的坐標不是相對屏幕的原點,而且相對于他的父布局來說的。
我們在主頁面最外層的ViewGroup添加了布局狀態改變的監聽器,當繪制完了屏幕會回調到方法onGlobalLayout()中,我們在onGlobalLayout()方法中手動調用了下onScroll()方法,剛開始myScrollView.getScrollY()等于0,所以說當scrollY小于mBuyLayout.getTop()的時候,上面的購買布局的上邊緣到myScrollView的上邊緣的距離等于mBuyLayout.getTop()(即下面布局的上邊緣到myScrollView的上邊緣)所以剛開始上面的購買布局和下面的購買布局重合了。
當myScrollView向上滾動,而上面購買布局的上邊緣始終要和myScrollView的上邊緣保持mBuyLayout.getTop()這個距離,所以上面的購買布局也跟著向上滾動,當scrollY大于mBuyLayout.getTop()的時候,表示購買布局上邊緣滑動到了導航欄布局,所以此時購買布局的上邊緣與myScrollView的上邊緣始終要保持scrollY這個距離,所以購買布局才會一直在導航欄下面,就好像粘住了一樣,不知道你了解了沒有?好了,不過根據這種思路你也可以剛開始使用一個懸浮框來覆蓋在下面的購買布局上面,然后onScroll()方法中更新懸浮框的位置,不過懸浮框的x,y不是相對于父布局的,這點要注意下,這樣子也能實現效果,不過相對于此,要復雜的多,所以我們遇到類似的功能直接使用這種就行了,簡潔明了,好了,你是不迫不及待的想看下效果,那我們接下來就運行下程序吧。
運行程序你會發現,無論我們怎么滑動,都不會出現之前那篇文章的那些情況,很流暢吧,這跟美團,大眾點評的效果完全一致,好了,修改版的講解就到這里結束了,有問題的請在下面留言,我會為大家解答的!
項目源碼,點擊下載
含有多個購買布局的效果,下一個購買布局會將上一個購買布局頂上去,使用方法也很簡單,只需要將你需要設置的布局設置Tag為sticky, 如
<FrameLayout android:layout_width="fill_parent" android:layout_height="100dip" android:background="#ff00ffff" android:tag="sticky" > <Button android:id="@+id/button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Button" /> </FrameLayout>
這樣子這個布局滾動到了頂部就會粘在頂部,大家可以下載試試!
推薦大家下載下面的代碼:多個購買布局效果源碼,點擊下載
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。