安卓(android)仿電商app商品詳情頁按鈕浮動效果
1、效果圖如下:
這效果用戶體驗(yàn)還是很酷炫,今天我們就來講解如何實(shí)現(xiàn)這個效果。
2、分析
為了方便理解,作圖分析
如圖所示,整個頁面分為四個部分:
1、懸浮內(nèi)容,floatView
2、頂部內(nèi)容,headView
3、中間內(nèi)容,與懸浮內(nèi)容相同,middleView
4、商品詳情展示頁面,detailView
因?yàn)轫撁鎯?nèi)容高度會超出屏幕,所以用Scrollview
實(shí)現(xiàn)滾動,懸浮view
與scrollview
同級,都在一個幀布局或者相對布局中。
當(dāng)y方向的滾動距離小于中間的內(nèi)容middleView
到頂部的距離時,middleView
理所當(dāng)然的會隨這頁面向上滑動而消失,我們顯示懸浮view
,從而實(shí)現(xiàn)middleView
一直卡在頂部的效果。
當(dāng)y方向滾動距離大于中間的內(nèi)容middleView
容到頂部的距離時,懸浮view
隱藏即可。
通過分析,我們發(fā)現(xiàn)只要知道scrollview
的滾動距離和middleView
到頂部的高度即可。至此將復(fù)雜的交互特效變成了倆個簡單的api。
3、第一種方法實(shí)現(xiàn)
3.1 獲取middleView的到父容器頂部的距離
tv_title.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mTitleTopAndHeight = tv_title.getTop(); tv_title.getViewTreeObserver().removeGlobalOnLayoutListener(this); } });
在activity的oncreate()
中直接通過view的getTop()
方法獲取到view的高度會返回0,這是因?yàn)榇藭rview還沒有繪制到界面,所以我們采用上面的方法給view設(shè)置監(jiān)聽獲取,由于可能發(fā)生多次繪制,所以最后記得移除監(jiān)聽事件。
以下代碼同樣可以獲?。?/strong>
tv_title.post(new Runnable() { @Override public void run() { mTitleTopAndHeight = tv_title.getTop(); } });
利用post
方法將操作放到隊列中,等系統(tǒng)布局完成后執(zhí)行隊列中的事件,同樣可以獲取到正確的view
的top
值。
3.2 獲取垂直方向滾動距離
在Scrollview
的父類View
中有個內(nèi)容變化的方法onScrollChanged(),
雖然該方法是protect
的外部不可調(diào)用,但是在內(nèi)部,當(dāng)scrollview
滾動時就會執(zhí)行該方法,所以我們自定義一個MyScrollView
在onScrollChanged()
通過回調(diào)將滾動的距離傳遞給外部。
自定義scrollview完整代碼如下:
public class MyScrollView extends ScrollView { private OnScrollListener mOnScrollListener; /** * 是否用戶手指觸摸滑動 */ private boolean mIsTouch = false; public MyScrollView(Context context) { this(context, null); } public MyScrollView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (mOnScrollListener != null) { mOnScrollListener.onScroll(t, mIsTouch ? OnScrollListener.SCROLL_STATE_TOUCH_SCROLL : OnScrollListener.SCROLL_STATE_FLING); } } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: mIsTouch = true; break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mIsTouch = false; break; } return super.onTouchEvent(ev); } public void setOnScrollListener(OnScrollListener onScrollListener) { mOnScrollListener = onScrollListener; } public interface OnScrollListener { /** * 用戶手指拖動滾動 */ int SCROLL_STATE_TOUCH_SCROLL = 0x0; /** * 慣性滑行滾動 */ int SCROLL_STATE_FLING = 0x1; /** * 滾動時的回調(diào) * * @param scrollY Y方向滾動的距離 * @param scroll_state 當(dāng)前滾動狀態(tài):自由滾動或者手勢拖動滾動 */ void onScroll(int scrollY, int scroll_state); } }
3.3 使用
在acitivity
中給scrollview
設(shè)置自定義滾動監(jiān)聽事件即可
mScrollView.setOnScrollListener(new MyScrollView.OnScrollListener() { @Override public void onScroll(int scrollY, int state) { Log.d("onScroll: ", scrollY + "" + "----------- state:" + state); if (scrollY <= mTitleTopAndHeight) { tv_float.setVisibility(View.INVISIBLE); } else { tv_float.setVisibility(View.VISIBLE); } } });
這樣,通過垂直方法的滾動值來控制floatView
的顯示隱藏,
tv_float.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { mScrollView.onTouchEvent(event); return false; } });
給懸浮view
設(shè)置觸摸監(jiān)聽,將用戶手勢傳遞給scrollView
,這樣用戶滑動懸浮view
時,內(nèi)容區(qū)域也可以跟隨滾動。
下面是布局代碼
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.qike.scrolltitle.MyScrollView android:id="@+id/sv_main" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="200dp" android:gravity="center" android:text="商品圖片"/> <TextView android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="40dp" android:background="#a3c" android:gravity="center" android:text="標(biāo)題view"/> <TextView android:layout_width="match_parent" android:layout_height="600dp" android:background="#a2bb" android:gravity="center" android:text="詳情頁面"/> </LinearLayout> </com.example.qike.scrolltitle.MyScrollView> <TextView android:id="@+id/tv_float" android:layout_width="match_parent" android:layout_height="40dp" android:background="#a3c" android:gravity="center" android:text="標(biāo)題view" android:visibility="invisible"/> </RelativeLayout>
4、第二種方式
本方法與第一種方式的區(qū)別就是獲取滾動位置的方法不同,該方法更簡單一些:
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { int scrollY = mScrollView.getScrollY(); if (scrollY <= mTitleTopAndHeight) { tv_float.setVisibility(View.INVISIBLE); } else { tv_float.setVisibility(View.VISIBLE); } } });
可能有讀者要問,既然有這種簡單的方法直接設(shè)置監(jiān)聽,為什么還介紹第一種方法。細(xì)心的你可能已經(jīng)發(fā)現(xiàn),在第一種方法中,我在自定義的監(jiān)聽事件中,還回調(diào)了代表當(dāng)前回調(diào)狀態(tài)的參數(shù)statue
,因?yàn)楹芏郺pp,在用戶手動拖動滾動跟慣性滾動的處理是不能的。比如淘寶商品詳情頁面,當(dāng)達(dá)到邊界值中間view
的top
值時,只有用戶手動拖動一段距離后才會拉出底部的詳情類容,而慣性滑動的話只會停在那里。
5、總結(jié)
以上就是關(guān)于安卓實(shí)現(xiàn)按鈕隨著上下滾動而懸浮頂在固定位置的方法,希望本文的內(nèi)容對大家開發(fā)Android能有所幫助。
相關(guān)文章
Android計時器chronometer使用實(shí)例講解
這篇文章主要為大家詳細(xì)介紹了Android計時器chronometer使用實(shí)例,介紹了Android計時器chronometer基本使用方法,感興趣的小伙伴們可以參考一下2016-04-04Android實(shí)現(xiàn)帶附件的郵件發(fā)送功能
這篇文章主要介紹了Android實(shí)現(xiàn)帶附件的郵件發(fā)送功能的相關(guān)資料,android發(fā)送郵件有兩種方式,本文重點(diǎn)介紹基于JMail實(shí)現(xiàn)郵件發(fā)送功能,感興趣的小伙伴們可以參考一下2016-01-01android實(shí)現(xiàn)raw文件夾導(dǎo)入數(shù)據(jù)庫代碼
這篇文章主要介紹了android實(shí)現(xiàn)raw文件夾導(dǎo)入數(shù)據(jù)庫代碼,有需要的朋友可以參考一下2013-12-12Android打包篇:Android Studio將代碼打包成jar包教程
這篇文章主要介紹了Android打包篇:Android Studio將代碼打包成jar包教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03Android App開發(fā)中使用RecyclerView替代ListView的實(shí)踐
RecyclerView是Android L即5.0版本以來新加入的一個組件,主要用來實(shí)現(xiàn)item的瀑布式排列,因而被人們廣泛認(rèn)為用來替代ListView,這里我們就來看一下Android App開發(fā)中使用RecyclerView替代ListView的實(shí)踐:2016-06-06android中colors.xml顏色設(shè)置資源文件的方法
這篇文章主要介紹了android中colors.xml顏色設(shè)置資源文件,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03Android中獲取sha1證書指紋數(shù)據(jù)的方法
大家都知道在Android開發(fā)中,經(jīng)常要獲取sha1證書指紋,所以這篇文章主要介紹在Android中如何使用命令獲取sha1證書指紋數(shù)據(jù)的方法,有需要的可以參考借鑒。2016-09-09Android動態(tài)表格的實(shí)現(xiàn)代碼(內(nèi)容、樣式可擴(kuò)縮)
這篇文章主要介紹了Android動態(tài)表格的實(shí)現(xiàn)代碼(內(nèi)容、樣式可擴(kuò)縮),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09比較完整的android MP3 LRC歌詞滾動高亮顯示(附源碼)
比較完整的android MP3 LRC歌詞滾動高亮顯示(附源碼)。需要的朋友可以過來參考下,希望對大家有所幫助2013-11-11