標籤:android style blog http color io os 使用 ar
如美團網,福士點評購買框懸浮效果,使用者在向上滑動介面時,購買按鈕始終在介面上,使用者體驗很好,很人性化。下面具體看看代碼是怎麼實現的:
主介面布局檔案main.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>
立即搶購懸浮框布局檔案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>
自訂ScrollView控制項MyScrollView類
package com.greentree.meituanxuanfudemo;import android.content.Context;import android.util.AttributeSet;import android.widget.ScrollView;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 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); }}
主介面MainActivity
package com.greentree.meituanxuanfudemo;import com.greentree.meituanxuanfudemo.MyScrollView.OnScrollListener;import android.app.Activity;import android.os.Bundle;import android.view.ViewTreeObserver.OnGlobalLayoutListener;import android.widget.LinearLayout;public class MainActivity extends Activity implements OnScrollListener { /** * 自訂的MyScrollView */ private MyScrollView myScrollView; /** * 在MyScrollView裡面的購買布局 */ private LinearLayout mBuyLayout; /** * 位於頂部的購買布局 */ private LinearLayout mTopBuyLayout; @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不是相對於父布局的,這點要注意下,這樣子也能實現效果,不過相對於此,要複雜的多,所以我們遇到類似的功能直接使用這種就行了,簡潔明了,好了,你是不迫不及待的想看下效果,那我們接下來就運行下程式吧
項目源碼 點擊下載
demo是根據原博主博文寫的,圖片都是的,所以介面會比較難看,請大家不要注意這些細節~!
本文出自xiaanming的部落格(http://blog.csdn.net/xiaanming/article/details/17761431)
Android 仿美團網,福士點評購買框懸浮效果