国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

android之listview懸浮topBar效果

2019-12-12 03:33:47
字體:
來源:轉載
供稿:網友

雖然listview是過去式,但由于項目中還是有用listview,百度一番都是scrollview中的懸浮bar,沒有看到有listview的懸浮bar,所以自己寫一個懸浮bar;參照夏大神的scrollview的懸浮demo

效果如下:

自定義的Listview和scrollView沒什么區別都是重寫onScrollChange()然后在里邊調用自己實現的接口,是對外提供的接口吧,這里沒有封裝,需要的可以自己將其封裝,然后在自己項目中使用。

重點的方法:
onScrollChanged()方法:是在ListView和ScrollView在滾動時會回調的方法并且能獲取到當前最新的top left和上一次的top 和left
getViewTreeObservew().addOnGlobalLayoutLister():這是View都有的方法,可以監控改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);    // 當布局的狀態或者控件的可見性發生改變回調的接口:當布局都繪制好后會執行一次    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) {//當手指從上往下滑動屏幕到達最頂端時,但還有一段可滑行的距離放手后又回到起始位置,跟系統有關      //此時這個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());    }    //這種方式會導致閃跳的現象,可以通過動畫來實現  }}

主要是onScroll()方法的邏輯:

可以看看夏大神的實現

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);  }  /**  * 滾動時會執行  * @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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 田林县| 石楼县| 高唐县| 托克托县| 焦作市| 贵溪市| 张家界市| 阜平县| 富阳市| 太谷县| 常州市| 新巴尔虎左旗| 古交市| 泾川县| 千阳县| 建平县| 新龙县| 连城县| 日土县| 博客| 阿坝县| 富川| 乌拉特后旗| 浦县| 广东省| 安徽省| 乌海市| 玉门市| 阳朔县| 钟祥市| 昌邑市| 东乡族自治县| 土默特右旗| 长沙市| 石景山区| 栾川县| 烟台市| 松原市| 松原市| 凌海市| 南皮县|