Android仿美團(tuán)網(wǎng)、大眾點(diǎn)評(píng)購(gòu)買(mǎi)框懸浮效果修改版
我之前寫(xiě)了一篇關(guān)于美團(tuán)網(wǎng),大眾點(diǎn)評(píng)的購(gòu)買(mǎi)框效果的文章Android對(duì)ScrollView滾動(dòng)監(jiān)聽(tīng),實(shí)現(xiàn)美團(tuán)、大眾點(diǎn)評(píng)的購(gòu)買(mǎi)懸浮效果,我自己感覺(jué)效果并不是很好,如果快速滑動(dòng)界面,顯示懸浮框的時(shí)候會(huì)出現(xiàn)一卡的現(xiàn)象,有些朋友說(shuō)有時(shí)候會(huì)出現(xiàn)兩個(gè)布局的情況,特別是對(duì)ScrollView滾動(dòng)的Y值得監(jiān)聽(tīng),我還使用了Handler來(lái)獲取,還有朋友給我介紹了Scrolling Tricks這個(gè)東西,我下載試了下,確實(shí)美團(tuán)網(wǎng),大眾點(diǎn)評(píng)的購(gòu)買(mǎi)框用的是這種效果,但是Scrolling Tricks只能在API11以上使用,這個(gè)有點(diǎn)小悲劇,然后我做了下修改,并將實(shí)現(xiàn)思路分享給大家,實(shí)現(xiàn)起來(lái)很簡(jiǎn)單
首先還是要先對(duì)ScrollView進(jìn)行滾動(dòng)監(jiān)聽(tīng),直接在onScrollChanged()方法中就能獲取滾動(dòng)的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); } /** * 設(shè)置滾動(dòng)接口 * @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); } } /** * * 滾動(dòng)的回調(diào)接口 * * @author xiaanming * */ public interface OnScrollListener{ /** * 回調(diào)方法, 返回MyScrollView滑動(dòng)的Y方向距離 * @param scrollY * 、 */ public void onScroll(int scrollY); } }
接下來(lái)看看主界面的布局文件
<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>
下面是布局的效果圖:
從主界面的布局你可以看出,我們?cè)谏厦娣胖昧艘粋€(gè)購(gòu)買(mǎi)的布局,可能你會(huì)想,先讓上面的布局隱藏起來(lái),等下面的布局滑動(dòng)上來(lái)就將其顯示出來(lái),如果這樣子就跟我之前寫(xiě)的那篇文章差不多,效果不是很棒,所以這篇修改版的肯定不是這樣子的,我們還是先看主界面的代碼吧
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里面的購(gòu)買(mǎi)布局 */ private LinearLayout mBuyLayout; /** * 位于頂部的購(gòu)買(mǎi)布局 */ 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); //當(dāng)布局的狀態(tài)或者控件的可見(jiàn)性發(fā)生改變回調(diào)的接口 findViewById(R.id.parent_layout).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //這一步很重要,使得上面的購(gòu)買(mǎi)布局和下面的購(gòu)買(mǎi)布局重合 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()); } }
主界面就短短的幾行代碼,可能看完這些代碼你還是沒(méi)有明白到底是怎么做到的,沒(méi)關(guān)系,我給大家說(shuō)說(shuō),其實(shí)我們是讓上面的購(gòu)買(mǎi)布局和下面的購(gòu)買(mǎi)布局重合起來(lái)了,layout()這個(gè)方法是確定View的大小和位置的,然后將其繪制出來(lái),里面的四個(gè)參數(shù)分別是View的四個(gè)點(diǎn)的坐標(biāo),他的坐標(biāo)不是相對(duì)屏幕的原點(diǎn),而且相對(duì)于他的父布局來(lái)說(shuō)的。
我們?cè)谥黜?yè)面最外層的ViewGroup添加了布局狀態(tài)改變的監(jiān)聽(tīng)器,當(dāng)繪制完了屏幕會(huì)回調(diào)到方法onGlobalLayout()中,我們?cè)趏nGlobalLayout()方法中手動(dòng)調(diào)用了下onScroll()方法,剛開(kāi)始myScrollView.getScrollY()等于0,所以說(shuō)當(dāng)scrollY小于mBuyLayout.getTop()的時(shí)候,上面的購(gòu)買(mǎi)布局的上邊緣到myScrollView的上邊緣的距離等于mBuyLayout.getTop()(即下面布局的上邊緣到myScrollView的上邊緣)所以剛開(kāi)始上面的購(gòu)買(mǎi)布局和下面的購(gòu)買(mǎi)布局重合了。
當(dāng)myScrollView向上滾動(dòng),而上面購(gòu)買(mǎi)布局的上邊緣始終要和myScrollView的上邊緣保持mBuyLayout.getTop()這個(gè)距離,所以上面的購(gòu)買(mǎi)布局也跟著向上滾動(dòng),當(dāng)scrollY大于mBuyLayout.getTop()的時(shí)候,表示購(gòu)買(mǎi)布局上邊緣滑動(dòng)到了導(dǎo)航欄布局,所以此時(shí)購(gòu)買(mǎi)布局的上邊緣與myScrollView的上邊緣始終要保持scrollY這個(gè)距離,所以購(gòu)買(mǎi)布局才會(huì)一直在導(dǎo)航欄下面,就好像粘住了一樣,不知道你了解了沒(méi)有?好了,不過(guò)根據(jù)這種思路你也可以剛開(kāi)始使用一個(gè)懸浮框來(lái)覆蓋在下面的購(gòu)買(mǎi)布局上面,然后onScroll()方法中更新懸浮框的位置,不過(guò)懸浮框的x,y不是相對(duì)于父布局的,這點(diǎn)要注意下,這樣子也能實(shí)現(xiàn)效果,不過(guò)相對(duì)于此,要復(fù)雜的多,所以我們遇到類(lèi)似的功能直接使用這種就行了,簡(jiǎn)潔明了,好了,你是不迫不及待的想看下效果,那我們接下來(lái)就運(yùn)行下程序吧。
運(yùn)行程序你會(huì)發(fā)現(xiàn),無(wú)論我們?cè)趺椿瑒?dòng),都不會(huì)出現(xiàn)之前那篇文章的那些情況,很流暢吧,這跟美團(tuán),大眾點(diǎn)評(píng)的效果完全一致,好了,修改版的講解就到這里結(jié)束了,有問(wèn)題的請(qǐng)?jiān)谙旅媪粞裕視?huì)為大家解答的!
項(xiàng)目源碼,點(diǎn)擊下載
含有多個(gè)購(gòu)買(mǎi)布局的效果,下一個(gè)購(gòu)買(mǎi)布局會(huì)將上一個(gè)購(gòu)買(mǎi)布局頂上去,使用方法也很簡(jiǎn)單,只需要將你需要設(shè)置的布局設(shè)置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>
這樣子這個(gè)布局滾動(dòng)到了頂部就會(huì)粘在頂部,大家可以下載試試!
推薦大家下載下面的代碼:多個(gè)購(gòu)買(mǎi)布局效果源碼,點(diǎn)擊下載
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)美團(tuán)、大眾點(diǎn)評(píng)的購(gòu)買(mǎi)懸浮效果(ScrollView滾動(dòng)監(jiān)聽(tīng))
- Android 實(shí)現(xiàn)控件懸浮效果實(shí)例代碼
- Android滑動(dòng)組件懸浮固定在頂部效果
- 詳解android使用ItemDecoration 懸浮導(dǎo)航欄效果
- Android 沉浸式狀態(tài)欄及懸浮效果
- Android Listview多tab上滑懸浮效果
- Android實(shí)現(xiàn)帶磁性的懸浮窗體效果
- Android實(shí)現(xiàn)桌面懸浮窗、蒙板效果實(shí)例代碼
- 模仿美團(tuán)點(diǎn)評(píng)的Android應(yīng)用中價(jià)格和購(gòu)買(mǎi)欄懸浮固定的效果
- Android利用懸浮按鈕實(shí)現(xiàn)翻頁(yè)效果
相關(guān)文章
Android程序自動(dòng)更新功能模塊的實(shí)現(xiàn)方法【附完整demo源碼下載】
這篇文章主要介紹了Android程序自動(dòng)更新功能模塊的實(shí)現(xiàn)方法,具備完整的自動(dòng)檢測(cè)更新及下載、安裝等功能,并附帶完整的demo源碼供大家下載參考,需要的朋友可以參考下2016-08-08詳解Android studio ndk配置cmake開(kāi)發(fā)native C
這篇文章主要介紹了詳解Android studio ndk配置cmake開(kāi)發(fā)native C,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09Android Studio控制臺(tái)出現(xiàn)中文亂碼(方框)問(wèn)題解決辦法
這篇文章主要介紹了Android Studio控制臺(tái)出現(xiàn)中文亂碼(方框)問(wèn)題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-06-06Android手機(jī)開(kāi)發(fā)設(shè)計(jì)之記事本功能
這篇文章主要為大家詳細(xì)介紹了Android手機(jī)開(kāi)發(fā)設(shè)計(jì)之記事本功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Android自定義控件RatingBar調(diào)整字體大小
這篇文章主要為大家詳細(xì)介紹了Android自定義控件RatingBar調(diào)整字體大小的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03關(guān)于Android 6.0權(quán)限的動(dòng)態(tài)適配詳解
Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用戶(hù)體驗(yàn), 同時(shí)也為程序員帶來(lái)新的負(fù)擔(dān). 動(dòng)態(tài)權(quán)限管理就是這樣, 一方面讓用戶(hù)更加容易的控制自己的隱私, 一方面需要重新適配應(yīng)用權(quán)限,本文介紹了關(guān)于Android 6.0權(quán)限動(dòng)態(tài)適配的相關(guān)資料,需要的朋友可以參考下。2017-11-11Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解
今天小編就為大家分享一篇關(guān)于Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03