android之listview懸浮topBar效果
雖然listview是過去式,但由于項目中還是有用listview,百度一番都是scrollview中的懸浮bar,沒有看到有l(wèi)istview的懸浮bar,所以自己寫一個懸浮bar;參照夏大神的scrollview的懸浮demo
效果如下:
自定義的Listview和scrollView沒什么區(qū)別都是重寫onScrollChange()然后在里邊調用自己實現(xiàn)的接口,是對外提供的接口吧,這里沒有封裝,需要的可以自己將其封裝,然后在自己項目中使用。
重點的方法:
onScrollChanged()方法:是在ListView和ScrollView在滾動時會回調的方法并且能獲取到當前最新的top left和上一次的top 和left
getViewTreeObservew().addOnGlobalLayoutLister():這是View都有的方法,可以監(jiān)控改view的變化(如顯示、隱藏)都會回調以及在view被繪制時會被回調。
思路如下:
一、可以使用getViewTreeObservew().addOnGlobalLayoutLister():方法在第一次進入到這個頁面后將懸浮的bar與目標view繪制重合。防止顯示隱藏會有一閃的情況
二、在onScrollChaged()方法中回調自定義的接口onScrollListener的方法onScroll()在這里通過layout()方法不斷重新繪制懸浮bar的位置。
基本就如此
package com.example.zwr.listviewfloatbardemo; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.ImageView; import android.widget.LinearLayout; /** * @author zhongwr */ public class MainActivity extends Activity implements FloatListView.OnScrollListener { protected static final String TAG = "FloatListView"; /** * 自定義的listview */ private FloatListView lvFloat; /** * listview中的headView中要懸浮的view */ private LinearLayout mFloatTargetLayout; /** * 懸浮的view,跟headView的要一致 */ private LinearLayout mFloatTopLayout; private View head; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvFloat = (FloatListView) findViewById(R.id.scrollView); head = getLayoutInflater().inflate(R.layout.buy_layout_head, null); lvFloat.addHeaderView(head); mFloatTargetLayout = (LinearLayout) findViewById(R.id.buy); mFloatTopLayout = (LinearLayout) findViewById(R.id.top_buy_layout); lvFloat.setOnScrollListener(this); // 當布局的狀態(tài)或者控件的可見性發(fā)生改變回調的接口:當布局都繪制好后會執(zhí)行一次 findViewById(R.id.parent_layout).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 這一步很重要,一開始讓目標懸浮的view和要懸浮的view重合一起,之后懸浮view跟隨一起目標view一起移動 onScroll(lvFloat.getScrollY()); } }); lvFloat.setAdapter(new DataListAdapter(this)); } @Override public void onScroll(int scrollY) { // SrcollView和這個Listview不同之處:scrolly是scrollview.getTop(),parent的坐標沒變,只是手指向上滾動時就是scrollview滾出屏幕,但是top還是距離parent的距離,所以那里用max取最大值 //listview手指向上滑動屏幕時會導致headRoot的top為負值,因為head是滾出屏幕的head部分并不是listview中item重用機制 int headTop = head.getTop(); if (headTop <= 0 && Math.abs(headTop) <= mFloatTargetLayout.getTop() && scrollY >= 0) {//手指向上滑動屏幕 mFloatTopLayout.layout(0, mFloatTargetLayout.getTop() + headTop, mFloatTopLayout.getWidth(), mFloatTargetLayout.getTop() + headTop + mFloatTopLayout.getHeight()); } else if (headTop == 0) {//當手指從上往下滑動屏幕到達最頂端時,但還有一段可滑行的距離放手后又回到起始位置,跟系統(tǒng)有關 //此時這個listview的Top是負值所以要減去-scrolly:注這個scrollY=listview.getTop();讓懸浮的Title跟隨實際的title一起浮動 mFloatTopLayout.layout(0, mFloatTargetLayout.getTop() - scrollY, mFloatTopLayout.getWidth(), mFloatTargetLayout.getTop() - scrollY + mFloatTopLayout.getHeight()); } else if (headTop < 0) {//由于手指向上滑動屏幕的很快會導致title懸浮不到頂部,所以要強制其在頂部 mFloatTopLayout.layout(0, 0, mFloatTopLayout.getWidth(), mFloatTopLayout.getHeight()); } //這種方式會導致閃跳的現(xiàn)象,可以通過動畫來實現(xiàn) } }
主要是onScroll()方法的邏輯:
可以看看夏大神的實現(xiàn)
public void onScroll(int scrollY) { int mBuyLayout2ParentTop = Math.max(scrollY, mBuyLayout.getTop()); mTopBuyLayout.layout(0, mBuyLayout2ParentTop, mTopBuyLayout.getWidth(), mBuyLayout2ParentTop + mTopBuyLayout.getHeight()); }
他這里是直接使用scrollY(其實是scrollview的最新top值)和目標view的top值去最大,因為ScrollView是滑出屏幕的,但是其parent的位置沒變,所以scrollview的top會越來越大而且是正值。所以可以通過這種方式來繪制懸浮的bar。
但是Listview的機制不一樣,滑動出屏幕時item由于是重用機制,所以listView中的top并沒有改變;巧的是head的機制有點像Scrollview滑出的機制,但是又不一樣得到的head的top值是負值,猜測相對坐標由于listView這個父布局沒動但是head已經滑出屏幕所以是負值。根據這個值處理我們想要的結果,剩下的onScroll()方法的注釋寫的很清楚了。
自定義的listView代碼如下
package com.example.zwr.listviewfloatbardemo; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.widget.ListView; /** * * @author zhongwr * */ public class FloatListView extends ListView { private static final String TAG = "FloatListView"; private OnScrollListener onScrollListener; public FloatListView(Context context) { this(context, null); } public FloatListView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FloatListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * 設置滾動接口 * @param onScrollListener */ public void setOnScrollListener(OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { // Log.d(TAG, "w = "+w); // Log.d(TAG, "h = "+h); super.onSizeChanged(w, h, oldw, oldh); } /** * 滾動時會執(zhí)行 * @param l 新的getLeft * @param t 新的getTop * @param oldl * @param oldt */ @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); // Log.d(TAG, "onScrollChanged l = " + l + " t = " + t); // Log.d(TAG, "onScrollChanged oldl = " + oldl + " oldt = " + oldt); if (onScrollListener != null) { onScrollListener.onScroll(t); } } /** * * 滾動的回調接口 * * @author xiaanming * */ public interface OnScrollListener{ /** * 回調方法, 返回MyScrollView滑動的Y方向距離 * @param scrollY * 、 */ public void onScroll(int scrollY); } }
沒什么邏輯,就是重寫了onSizeChaged()方法,然后在里邊寫了調用接口的回調。
就是這么簡單??!
demo如下:listview懸浮topBar
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android TextView實現(xiàn)跑馬燈效果的方法
這篇文章主要介紹了Android TextView跑馬燈效果實現(xiàn)方法,涉及Android布局文件中相關屬性的設置技巧,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-01-01Android RecyclerView添加上拉加載更多效果
這篇文章主要為大家詳細介紹了Android RecyclerView添加上拉加載更多效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02詳談Android中onTouch與onClick事件的關系(必看)
下面小編就為大家?guī)硪黄斦凙ndroid中onTouch與onClick事件的關系(必看)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03android 獲取手機GSM/CDMA信號信息,并獲得基站信息的方法
下面小編就為大家?guī)硪黄猘ndroid 獲取手機GSM/CDMA信號信息,并獲得基站信息的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11Android編程中activity啟動時出現(xiàn)白屏、黑屏問題的解決方法
這篇文章主要介紹了Android編程中activity啟動時出現(xiàn)白屏、黑屏問題的解決方法,涉及Android針對activity啟動設置的技巧,需要的朋友可以參考下2015-12-12Android下拉刷新控件SwipeRefreshLayout源碼解析
這篇文章主要為大家詳細解析Android下拉刷新控件SwipeRefreshLayout源碼,感興趣的小伙伴們可以參考一下2016-07-07