Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android監聽ScrollView滾動實現仿美團、大眾點評的購買懸浮效果完善版

Android監聽ScrollView滾動實現仿美團、大眾點評的購買懸浮效果完善版

編輯:Android開發實例

 我之前寫了一篇關於美團網,大眾點評的購買框效果的文章http://www.fengfly.com/plus/view-214540-1.html ,我自己感覺效果並不是很好,如果快速滑動界面,顯示懸浮框的時候會出現一卡的現象,有些朋友說有時候會出現兩個布局的情況,特別是對ScrollView滾動的Y值得監聽,我還使用了Handler來獲取,還有朋友給我介紹了Scrolling Tricks這個東西,我下載試了下,確實美團網,大眾點評的購買框用的是這種效果,但是Scrolling Tricks只能在API11以上使用,這個有點小悲劇,然後我做了下修改,並將實現思路分享給大家,實現起來很簡單
首先還是要先對ScrollView進行滾動監聽,直接在onScrollChanged()方法中就能獲取滾動的Y值,之前那篇文章使用了Handler,走彎路了,直接看代碼吧

  1. package com.example.meituandemo; 
  2.  
  3. import android.content.Context; 
  4. import android.util.AttributeSet; 
  5. import android.widget.ScrollView; 
  6. /** 
  7.  *  
  8.  * @author xiaanming 
  9.  * 
  10.  */ 
  11. public class MyScrollView extends ScrollView { 
  12.     private OnScrollListener onScrollListener; 
  13.      
  14.     public MyScrollView(Context context) { 
  15.         this(context, null); 
  16.     } 
  17.      
  18.     public MyScrollView(Context context, AttributeSet attrs) { 
  19.         this(context, attrs, 0); 
  20.     } 
  21.  
  22.     public MyScrollView(Context context, AttributeSet attrs, int defStyle) { 
  23.         super(context, attrs, defStyle); 
  24.     } 
  25.      
  26.     /** 
  27.      * 設置滾動接口 
  28.      * @param onScrollListener 
  29.      */ 
  30.     public void setOnScrollListener(OnScrollListener onScrollListener) { 
  31.         this.onScrollListener = onScrollListener; 
  32.     } 
  33.      
  34.      
  35.     @Override 
  36.     public int computeVerticalScrollRange() { 
  37.         return super.computeVerticalScrollRange(); 
  38.     } 
  39.      
  40.  
  41.     @Override 
  42.     protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
  43.         super.onScrollChanged(l, t, oldl, oldt); 
  44.         if(onScrollListener != null){ 
  45.             onScrollListener.onScroll(t); 
  46.         } 
  47.     } 
  48.  
  49.  
  50.  
  51.     /** 
  52.      *  
  53.      * 滾動的回調接口 
  54.      *  
  55.      * @author xiaanming 
  56.      * 
  57.      */ 
  58.     public interface OnScrollListener{ 
  59.         /** 
  60.          * 回調方法, 返回MyScrollView滑動的Y方向距離 
  61.          * @param scrollY 
  62.          *              、 
  63.          */ 
  64.         public void onScroll(int scrollY); 
  65.     } 
  66.      
  67.      
  68.  

接下來看看主界面的布局文件

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  2.     android:id="@+id/parent_layout" 
  3.     xmlns:tools="http://schemas.android.com/tools" 
  4.     android:layout_width="match_parent" 
  5.     android:layout_height="match_parent" 
  6.     android:orientation="vertical" > 
  7.  
  8.     <ImageView 
  9.         android:id="@+id/imageView1" 
  10.         android:layout_width="match_parent" 
  11.         android:layout_height="45dip" 
  12.         android:scaleType="centerCrop" 
  13.         android:src="@drawable/navigation_bar" /> 
  14.  
  15.     <com.example.meituandemo.MyScrollView 
  16.         android:id="@+id/scrollView" 
  17.         android:layout_width="fill_parent" 
  18.         android:layout_height="fill_parent" > 
  19.  
  20.         <FrameLayout 
  21.             android:layout_width="match_parent" 
  22.             android:layout_height="wrap_content" > 
  23.  
  24.             <LinearLayout 
  25.                 android:layout_width="match_parent" 
  26.                 android:layout_height="wrap_content" 
  27.                 android:orientation="vertical" > 
  28.  
  29.                 <ImageView 
  30.                     android:id="@+id/iamge" 
  31.                     android:layout_width="match_parent" 
  32.                     android:layout_height="wrap_content" 
  33.                     android:background="@drawable/pic" 
  34.                     android:scaleType="centerCrop" /> 
  35.  
  36.                 <include 
  37.                     android:id="@+id/buy" 
  38.                     layout="@layout/buy_layout" /> 
  39.  
  40.                 <ImageView 
  41.                     android:layout_width="match_parent" 
  42.                     android:layout_height="wrap_content" 
  43.                     android:background="@drawable/one" 
  44.                     android:scaleType="centerCrop" /> 
  45.  
  46.                 <ImageView 
  47.                     android:layout_width="match_parent" 
  48.                     android:layout_height="wrap_content" 
  49.                     android:background="@drawable/one" 
  50.                     android:scaleType="centerCrop" /> 
  51.  
  52.                 <ImageView 
  53.                     android:layout_width="match_parent" 
  54.                     android:layout_height="wrap_content" 
  55.                     android:background="@drawable/one" 
  56.                     android:scaleType="centerCrop" /> 
  57.             </LinearLayout> 
  58.  
  59.             <include 
  60.                 android:id="@+id/top_buy_layout" 
  61.                 layout="@layout/buy_layout" /> 
  62.         </FrameLayout> 
  63.     </com.example.meituandemo.MyScrollView> 
  64.  
  65. </LinearLayout> 

下面是布局的效果圖
 

從主界面的布局你可以看出,我們在上面放置了一個購買的布局,可能你會想,先讓上面的布局隱藏起來,等下面的布局滑動上來就將其顯示出來,如果這樣子就跟我之前寫的那篇文章差不多,效果不是很棒,所以這篇修改版的肯定不是這樣子的,我們還是先看主界面的代碼吧

  1. package com.example.meituandemo; 
  2.  
  3. import android.app.Activity; 
  4. import android.os.Bundle; 
  5. import android.view.ViewTreeObserver.OnGlobalLayoutListener; 
  6. import android.widget.LinearLayout; 
  7.  
  8. import com.example.meituandemo.MyScrollView.OnScrollListener; 
  9.  
  10. /** 
  11.  *  
  12.  * @author xiaanming 
  13.  * 
  14.  */ 
  15. public class MainActivity extends Activity implements OnScrollListener{ 
  16.     /** 
  17.      * 自定義的MyScrollView 
  18.      */ 
  19.     private MyScrollView myScrollView; 
  20.     /** 
  21.      * 在MyScrollView裡面的購買布局 
  22.      */ 
  23.     private LinearLayout mBuyLayout; 
  24.     /** 
  25.      * 位於頂部的購買布局 
  26.      */ 
  27.     private LinearLayout mTopBuyLayout; 
  28.      
  29.  
  30.     @SuppressWarnings("deprecation") 
  31.     @Override 
  32.     protected void onCreate(Bundle savedInstanceState) { 
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(R.layout.activity_main); 
  35.          
  36.         myScrollView = (MyScrollView) findViewById(R.id.scrollView); 
  37.         mBuyLayout = (LinearLayout) findViewById(R.id.buy); 
  38.         mTopBuyLayout = (LinearLayout) findViewById(R.id.top_buy_layout); 
  39.          
  40.         myScrollView.setOnScrollListener(this); 
  41.          
  42.         //當布局的狀態或者控件的可見性發生改變回調的接口 
  43.         findViewById(R.id.parent_layout).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
  44.              
  45.             @Override 
  46.             public void onGlobalLayout() { 
  47.                 //這一步很重要,使得上面的購買布局和下面的購買布局重合 
  48.                 onScroll(myScrollView.getScrollY()); 
  49.                  
  50.             } 
  51.         }); 
  52.     } 
  53.  
  54.  
  55.  
  56.  
  57.     @Override 
  58.     public void onScroll(int scrollY) { 
  59.         int mBuyLayout2ParentTop = Math.max(scrollY, mBuyLayout.getTop()); 
  60.         mTopBuyLayout.layout(0, mBuyLayout2ParentTop, mTopBuyLayout.getWidth(), mBuyLayout2ParentTop + mTopBuyLayout.getHeight()); 
  61.     } 
  62.  
  63.  
  64.  

界面就短短的幾行代碼,可能看完這些代碼你還是沒有明白到底是怎麼做到的,沒關系,我給大家說說,其實我們是讓上面的購買布局和下面的購買布局重合起來了,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不是相對於父布局的,這點要注意下,這樣子也能實現效果,不過相對於此,要復雜的多,所以我們遇到類似的功能直接使用這種就行了,簡潔明了,好了,你是不迫不及待的想看下效果,那我們接下來就運行下程序吧

 

運行程序你會發現,無論我們怎麼滑動,都不會出現之前那篇文章的那些情況,很流暢吧,這跟美團,大眾點評的效果完全一致,好了,修改版的講解就到這裡結束了

源碼下載

 

轉自:http://blog. csdn. net/xiaanming/article/details/17761431

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved