轉:http://blog.csdn.net/xiaanming/article/details/17374599html
很榮幸我可以成爲CSDN 2013年度博客之星評選的候選人,但願繼續獲得你們的支持與鼓勵,看到的朋友幫我投上寶貴的一票吧!java
投票地址:http://vote.blog.csdn.net/blogstaritem/blogstar2013/xiaanmingandroid
轉帖請註明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming),請尊重他人的辛勤勞動成果,謝謝!app
隨着移動互聯網的快速發展,它已經和咱們的生活息息相關了,在公交地鐵裏面都能看到不少人的人低頭看着本身的手機屏幕,今後「低頭族」一詞就產生了,做爲一名移動行業的開發人員,我本身也是一名「低頭族」,上下班時間在公交地鐵上看看新聞來打發下時間,有時候也會看看那些受歡迎的App的一些界面效果,爲何人家的app那麼受歡迎?跟用戶體驗跟UI設計也有直接的關係,最近在美團和大衆點評的App看到以下效果,我感受用戶好,很人性化,因此本身也嘗試着實現了下,接下來就講解下實現思路!ide
如上圖(2)咱們看到了,噹噹即搶購佈局向上滑動到導航欄佈局的時候,當即搶購佈局就貼在導航欄佈局下面,下面的其餘的佈局仍是能夠滑動,當咱們向下滑動的時候,當即搶購的佈局又隨着往下滑動了,看似有點複雜,可是一說思路可能你就頓時恍然大悟了。佈局
當咱們向上滑動過程當中,咱們判斷當即搶購的佈局是否滑到導航欄佈局下面,若是當即搶購的上面頂到了導航欄,咱們新建一個當即搶購的懸浮框來顯示在導航欄下面,這樣子就實現了當即搶購貼在導航欄下面的效果啦,而當咱們向下滑動的時候,噹噹即搶購佈局的下面恰好到了剛剛新建的當即搶購懸浮框的下面的時候,咱們就移除當即搶購懸浮框,可能說的有點拗口,既然知道了思路,接下來咱們就來實現效果。this
新建一個Android項目,取名MeiTuanDemo,先看當即搶購(buy_layout.xml)的佈局,這裏爲了方便我直接從美團上面截去了圖片spa
- <?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裏面,界面仍是很簡單的.net
- <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;
-
-
-
-
-
-
- public class MyScrollView extends ScrollView {
- private OnScrollListener onScrollListener;
-
-
-
- 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);
- }
-
-
-
-
-
- public void setOnScrollListener(OnScrollListener onScrollListener) {
- this.onScrollListener = onScrollListener;
- }
-
-
-
-
-
- private Handler handler = new Handler() {
-
- public void handleMessage(android.os.Message msg) {
- int scrollY = MyScrollView.this.getScrollY();
-
-
- if(lastScrollY != scrollY){
- lastScrollY = scrollY;
- handler.sendMessageDelayed(handler.obtainMessage(), 5);
- }
- if(onScrollListener != null){
- onScrollListener.onScroll(scrollY);
- }
-
- };
-
- };
-
-
-
-
-
-
-
- @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);
- }
-
-
-
-
-
-
-
-
-
- public interface OnScrollListener{
-
-
-
-
-
- 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的代碼編寫
上面的代碼比較簡單,根據ScrollView滑動的距離來判斷顯示和移除懸浮框,懸浮框的實現主要是經過WindowManager這個類來實現的,調用這個類的addView方法用於添加一個懸浮框,removeView用於移除懸浮框。
經過上述代碼就實現了美團,大衆點評的這種效果,在運行項目以前咱們必須在AndroidManifest.xml中加入<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
咱們運行下項目看下效果吧
好了,今天的講解到此結束,有疑問的朋友請在下面留言
項目源碼,點擊下載
PS:你們有興趣的話能夠看看Android 仿美團網,大衆點評購買框懸浮效果之修改版