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-09
Android Studio控制臺(tái)出現(xiàn)中文亂碼(方框)問(wèn)題解決辦法
這篇文章主要介紹了Android Studio控制臺(tái)出現(xiàn)中文亂碼(方框)問(wèn)題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-06-06
Android手機(jī)開(kāi)發(fā)設(shè)計(jì)之記事本功能
這篇文章主要為大家詳細(xì)介紹了Android手機(jī)開(kāi)發(fā)設(shè)計(jì)之記事本功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Android自定義控件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-11
Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解
今天小編就為大家分享一篇關(guān)于Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03

