国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現美團、大眾點評的購買懸浮效果(ScrollView滾動監聽)

2019-12-12 03:33:58
字體:
來源:轉載
供稿:網友

隨著移動互聯網的快速發展,它已經和我們的生活息息相關了,在公交地鐵里面都能看到很多人的人低頭看著自己的手機屏幕,從此“低頭族”一詞就產生了,作為一名移動行業的開發人員,我自己也是一名“低頭族”,上下班時間在公交地鐵上看看新聞來打發下時間,有時候也會看看那些受歡迎的App的一些界面效果,為什么人家的app那么受歡迎?跟用戶體驗跟UI設計也有直接的關系,最近在美團和大眾點評的App看到如下效果,我感覺用戶好,很人性化,所以自己也嘗試著實現了下,接下來就講解下實現思路!

如上圖(2)我們看到了,當立即搶購布局向上滑動到導航欄布局的時候,立即搶購布局就貼在導航欄布局下面,下面的其他的布局還是可以滑動,當我們向下滑動的時候,立即搶購的布局又隨著往下滑動了,看似有點復雜,但是一說思路可能你就頓時恍然大悟了。
當我們向上滑動過程中,我們判斷立即搶購的布局是否滑到導航欄布局下面,如果立即搶購的上面頂到了導航欄,我們新建一個立即搶購的懸浮框來顯示在導航欄下面,這樣子就實現了立即搶購貼在導航欄下面的效果啦,而當我們向下滑動的時候,當立即搶購布局的下面剛好到了剛剛新建的立即搶購懸浮框的下面的時候,我們就移除立即搶購懸浮框,可能說的有點拗口,既然知道了思路,接下來我們就來實現效果。
新建一個Android項目,取名MeiTuanDemo,先看立即搶購(buy_layout.xml)的布局,這里為了方便我直接從美團上面截去了圖片

<?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="horizontal"  android:layout_width="fill_parent"  android:layout_height="wrap_content" >   <ImageView   android:id="@+id/buy_layout"   android:layout_width="fill_parent"   android:layout_height="wrap_content"   android:background="@drawable/buy" />  </LinearLayout> 

立即搶購的布局實現了,接下來實現主界面的布局,上面是導航欄布局,為了方便還是直接從美團截取的圖片,然后下面的ViewPager布局,立即搶購布局,其他布局 放在ScrollView里面,界面還是很簡單的

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  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:scaleType="centerCrop"   android:layout_width="match_parent"   android:layout_height="45dip"   android:src="@drawable/navigation_bar" />      <com.example.meituandemo.MyScrollView   android:id="@+id/scrollView"   android:layout_width="fill_parent"   android:layout_height="fill_parent" >    <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>  </com.example.meituandemo.MyScrollView>  </LinearLayout> 

你會發現上面的主界面布局中并不是ScrollView,而是自定義的一個MyScrollView,接下來就看看MyScrollView類中的代碼

package com.example.meituandemo;  import android.content.Context; import android.os.Handler; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ScrollView; /**  * 博客地址:http://blog.csdn.net/xiaanming  *  * @author xiaanming  *  */ public class MyScrollView extends ScrollView {  private OnScrollListener onScrollListener;  /**   * 主要是用在用戶手指離開MyScrollView,MyScrollView還在繼續滑動,我們用來保存Y的距離,然后做比較   */  private int lastScrollY;    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;  }    /**   * 用于用戶手指離開MyScrollView的時候獲取MyScrollView滾動的Y距離,然后回調給onScroll方法中   */  private Handler handler = new Handler() {    public void handleMessage(android.os.Message msg) {    int scrollY = MyScrollView.this.getScrollY();        //此時的距離和記錄下的距離不相等,在隔5毫秒給handler發送消息    if(lastScrollY != scrollY){     lastScrollY = scrollY;     handler.sendMessageDelayed(handler.obtainMessage(), 5);    }    if(onScrollListener != null){     onScrollListener.onScroll(scrollY);    }       };   };   /**   * 重寫onTouchEvent, 當用戶的手在MyScrollView上面的時候,   * 直接將MyScrollView滑動的Y方向距離回調給onScroll方法中,當用戶抬起手的時候,   * MyScrollView可能還在滑動,所以當用戶抬起手我們隔5毫秒給handler發送消息,在handler處理   * MyScrollView滑動的距離   */  @Override  public boolean onTouchEvent(MotionEvent ev) {   if(onScrollListener != null){    onScrollListener.onScroll(lastScrollY = this.getScrollY());   }   switch(ev.getAction()){   case MotionEvent.ACTION_UP:     handler.sendMessageDelayed(handler.obtainMessage(), 5);    break;   }   return super.onTouchEvent(ev);  }    /**   *   * 滾動的回調接口   *   * @author xiaanming   *   */  public interface OnScrollListener{   /**    * 回調方法, 返回MyScrollView滑動的Y方向距離    * @param scrollY    *    、    */   public void onScroll(int scrollY);  }      } 

一看代碼你也許明白了,就是對ScrollView的滾動Y值進行監聽,我們知道ScrollView并沒有實現滾動監聽,所以我們必須自行實現對ScrollView的監聽,我們很自然的想到在onTouchEvent()方法中實現對滾動Y軸進行監聽,可是你會發現,我們在滑動ScrollView的時候,當我們手指離開ScrollView。它可能還會繼續滑動一段距離,所以我們選擇在用戶手指離開的時候每隔5毫秒來判斷ScrollView是否停止滑動,并將ScrollView的滾動Y值回調給OnScrollListener接口的onScroll(int scrollY)方法中,我們只需要對ScrollView調用我們只需要對ScrollView調用setOnScrollListener方法就能監聽到滾動的Y值。
實現了對ScrollView滾動的Y值進行監聽,接下來就簡單了,我們只需要顯示立即搶購懸浮框和移除懸浮框了,接下來看看主界面Activity的代碼編寫

package com.example.meituandemo;  import android.app.Activity; import android.content.Context; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.LinearLayout; import com.example.meituandemo.MyScrollView.OnScrollListener; /**  * 博客地址:http://blog.csdn.net/xiaanming  *  * @author xiaanming  *  */ public class MainActivity extends Activity implements OnScrollListener{  private MyScrollView myScrollView;  private LinearLayout mBuyLayout;  private WindowManager mWindowManager;  /**   * 手機屏幕寬度   */  private int screenWidth;  /**   * 懸浮框View   */  private static View suspendView;  /**   * 懸浮框的參數   */  private static WindowManager.LayoutParams suspendLayoutParams;  /**   * 購買布局的高度   */  private int buyLayoutHeight;  /**   * myScrollView與其父類布局的頂部距離   */  private int myScrollViewTop;   /**   * 購買布局與其父類布局的頂部距離   */  private int buyLayoutTop;     @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);      myScrollView.setOnScrollListener(this);   mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);   screenWidth = mWindowManager.getDefaultDisplay().getWidth();  }   /**   * 窗口有焦點的時候,即所有的布局繪制完畢的時候,我們來獲取購買布局的高度和myScrollView距離父類布局的頂部位置   */  @Override  public void onWindowFocusChanged(boolean hasFocus) {   super.onWindowFocusChanged(hasFocus);   if(hasFocus){    buyLayoutHeight = mBuyLayout.getHeight();    buyLayoutTop = mBuyLayout.getTop();        myScrollViewTop = myScrollView.getTop();   }  }     /**   * 滾動的回調方法,當滾動的Y距離大于或者等于 購買布局距離父類布局頂部的位置,就顯示購買的懸浮框   * 當滾動的Y的距離小于 購買布局距離父類布局頂部的位置加上購買布局的高度就移除購買的懸浮框   *   */  @Override  public void onScroll(int scrollY) {   if(scrollY >= buyLayoutTop){    if(suspendView == null){     showSuspend();    }   }else if(scrollY <= buyLayoutTop + buyLayoutHeight){    if(suspendView != null){     removeSuspend();    }   }  }    /**   * 顯示購買的懸浮框   */  private void showSuspend(){   if(suspendView == null){    suspendView = LayoutInflater.from(this).inflate(R.layout.buy_layout, null);    if(suspendLayoutParams == null){     suspendLayoutParams = new LayoutParams();     suspendLayoutParams.type = LayoutParams.TYPE_PHONE; //懸浮窗的類型,一般設為2002,表示在所有應用程序之上,但在狀態欄之下     suspendLayoutParams.format = PixelFormat.RGBA_8888;     suspendLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL        | LayoutParams.FLAG_NOT_FOCUSABLE; //懸浮窗的行為,比如說不可聚焦,非模態對話框等等     suspendLayoutParams.gravity = Gravity.TOP; //懸浮窗的對齊方式     suspendLayoutParams.width = screenWidth;     suspendLayoutParams.height = buyLayoutHeight;     suspendLayoutParams.x = 0; //懸浮窗X的位置     suspendLayoutParams.y = myScrollViewTop; ////懸浮窗Y的位置    }   }      mWindowManager.addView(suspendView, suspendLayoutParams);  }      /**   * 移除購買的懸浮框   */  private void removeSuspend(){   if(suspendView != null){    mWindowManager.removeView(suspendView);    suspendView = null;   }  }  } 

上面的代碼比較簡單,根據ScrollView滑動的距離來判斷顯示和移除懸浮框,懸浮框的實現主要是通過WindowManager這個類來實現的,調用這個類的addView方法用于添加一個懸浮框,removeView用于移除懸浮框。
通過上述代碼就實現了美團,大眾點評的這種效果,在運行項目之前我們必須在AndroidManifest.xml中加入<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

我們運行下項目看下效果吧


好了,今天的講解到此結束,有疑問的朋友可以留言。
項目源碼,點擊下載
PS:大家有興趣的話可以看看Android仿美團網,大眾點評購買框懸浮效果之修改版

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 图木舒克市| 云和县| 新建县| 花垣县| 吴桥县| 孙吴县| 黎城县| 金堂县| 富阳市| 上林县| 增城市| 楚雄市| 湄潭县| 瓮安县| 元朗区| 龙川县| 五大连池市| 湘乡市| 建平县| 香港 | 林口县| 伊春市| 美姑县| 霍林郭勒市| 伊金霍洛旗| 松潘县| 报价| 北票市| 太和县| 安仁县| 开远市| 西昌市| 扶沟县| 民县| 博罗县| 禄丰县| 长岭县| 长寿区| 东乌| 宿州市| 黄冈市|