成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

怎么在Android應(yīng)用中利用scrollToTop實(shí)現(xiàn)一個(gè)點(diǎn)擊回到頂部功能

本篇文章給大家分享的是有關(guān)怎么在Android應(yīng)用中利用 scrollToTop實(shí)現(xiàn)一個(gè)點(diǎn)擊回到頂部功能,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

從策劃到設(shè)計(jì)制作,每一步都追求做到細(xì)膩,制作可持續(xù)發(fā)展的企業(yè)網(wǎng)站。為客戶提供成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站策劃、網(wǎng)頁設(shè)計(jì)、申請(qǐng)域名、網(wǎng)頁空間、網(wǎng)絡(luò)營銷、VI設(shè)計(jì)、 網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,以客戶的口碑塑造優(yōu)易品牌,攜手廣大客戶,共同發(fā)展進(jìn)步。

實(shí)現(xiàn)方法

布局代碼:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 tools:context="com.znke.pulltorefresh_top.MainActivity"> 
 
 <!--<com.znke.pulltorefresh_top.tool.ToTopScrollView .../>--> 
 <ScrollView 
  android:id="@+id/scrollView" 
  android:layout_width="match_parent" 
  android:layout_height="wrap_content" 
  android:layout_below="@+id/tv_top" 
  android:scrollbars="none"> 
 
  <LinearLayout 
   android:layout_width="match_parent" 
   android:layout_height="wrap_content" 
   android:orientation="vertical"> 
 
   <TextView 
    android:layout_width="match_parent" 
    android:layout_height="50dp" 
    android:gravity="center" 
    android:text="111111111111" 
    android:textSize="20sp" /> 
 
   ........... 
 
   <View 
    android:layout_width="match_parent" 
    android:layout_height="2dp" 
    android:background="#AAAAAA" /> 
 
   <TextView 
    android:layout_width="match_parent" 
    android:layout_height="80dp" 
    android:gravity="center" 
    android:text="12000000000000" 
    android:textSize="20sp" /> 
  </LinearLayout> 
 </ScrollView> 
 
 <com.znke.pulltorefresh_top.tool.ToTopImageView 
  android:id="@+id/imageView_to_top" 
  android:layout_width="50dp" 
  android:layout_height="50dp" 
  android:layout_alignParentBottom="true" 
  android:layout_alignParentRight="true" 
  android:layout_marginBottom="5dp" 
  android:layout_marginRight="5dp" 
  android:background="@drawable/to_top" /> 
</RelativeLayout>

然后在activity中設(shè)置下面事件不就完了嘛?。?!

mScrollView.setOnScrollChangeListener();

很遺憾,報(bào)錯(cuò)。alt+enter搞定錯(cuò)誤不就完了嘛!很遺憾,運(yùn)行繼續(xù)報(bào)錯(cuò),報(bào)空指針,神奇吧,找不出來。翻閱資料后發(fā)現(xiàn),scrollview的onScrollChanged方法是受保護(hù)的。故按照網(wǎng)上的資料,自定義ScrollView類,暴露出onScrollChanged方法:

public class ToTopScrollView extends ScrollView { 
 private OnMyScrollListener onMyScrollListener; 
 
 public void setOnMyScrollListener(OnMyScrollListener onMyScrollListener) { 
  this.onMyScrollListener = onMyScrollListener; 
 } 
 
 ... 
 
 @Override 
 protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
  super.onScrollChanged(l, t, oldl, oldt); 
  if(onMyScrollListener != null) 
   onMyScrollListener.onScrollChanged(l,t,oldl,oldt); 
 } 
 
 public interface OnMyScrollListener{ 
  void onScrollChanged(int x, int y, int oldx, int oldy); 
 } 
}

然后在activity中設(shè)置setOnMyScrollListener()方法,就可以監(jiān)控scrollview的狀態(tài)了。剩下的就是自定義imageview的邏輯了。

可是,自定義ToTopImageView里面怎么弄呢?它需要有一個(gè)高度臨界值,與activity傳遞scrollview的scrollY值比較,來判定ToTopImageView是否顯示。代碼簡(jiǎn)單,搞定。

只是這樣有個(gè)小問題,onScrollChanged方法是監(jiān)控滾動(dòng)狀態(tài)的,沒有說停止。如果在里面判斷超過臨界值就顯示與隱藏imageview,那么會(huì)一直設(shè)置imageview。這樣肯定不是最佳的方法。如果能在滾動(dòng)停止時(shí)再判定是否需要顯示與隱藏imageview就好了。此時(shí)我還沒有想太多,動(dòng)手簡(jiǎn)單實(shí)現(xiàn)了剛才的分析。

實(shí)現(xiàn)后,感覺挺爽。然而在準(zhǔn)備加到項(xiàng)目中時(shí)發(fā)現(xiàn),我們項(xiàng)目用了PullToRefresh刷新代碼庫,也簡(jiǎn)單,把自定義的Scrollview替換就可以了。運(yùn)行,糟糕,沒有效果,然后調(diào)試,事件沒有處罰,可能是PullToRefresh庫把事件屏蔽了,咋辦?找onTouchListener監(jiān)聽方法唄。

于是改用了測(cè)試:

mScrollView.setOnTouchListener()

我去,沒有調(diào)傭,把pullToRefreshScrollView里面各種監(jiān)聽方法都試遍了,沒用。他只提供了頂部和底部的上拉、下拉刷新監(jiān)聽,毛用。

于是查看其源碼,發(fā)現(xiàn)把事件攔截了。而且pullToRefreshScrollView根本就不是scrollview,看源碼:

  @Override 
protected ScrollView createRefreshableView(Context context, AttributeSet attrs) { 
 ScrollView scrollView; 
 if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 
  scrollView = new InternalScrollViewSDK9(context, attrs); 
 } else { 
  scrollView = new ScrollView(context, attrs); 
 } 
 
 scrollView.setId(R.id.scrollview); 
 return scrollView; 
}

他里面提供了一個(gè)方法可以或得到Scrollview:

final ScrollView scrollView = mScrollView.getRefreshableView();

回想起了以前項(xiàng)目也這么用過,只是當(dāng)時(shí)不明白這句話干啥的,白寫。

然后就用上面這種方法得到scrollview,再設(shè)置onscrollchanged方法監(jiān)聽滑動(dòng)。運(yùn)行報(bào)錯(cuò),同樣無效。于是只能換onTouchListener監(jiān)聽了。

但是這樣問題來了,我們只能監(jiān)聽到手勢(shì),即何時(shí)按下、移動(dòng)和彈起。當(dāng)快速滑動(dòng)手指彈起后,scrollview還在滾動(dòng)的,什么時(shí)候去拿到它的scrollY值呢?犯愁了。

此時(shí)不得不用最開始分析的方法,在自定義imageview里面定義線程,掃描當(dāng)前scrollY和上一次保存的對(duì)比,不一樣即說明仍在滾動(dòng),一樣即表明scrollview滾動(dòng)停止了。

什么時(shí)候開啟線程呢?在onTouch回調(diào)中down、move或者up時(shí)調(diào)用。

試想下:

如果在down中調(diào)用時(shí),用戶只在scrollview上點(diǎn)擊或短距離滑動(dòng),imageview里面要不停地開啟線程?浪費(fèi)資源。

如果在up中調(diào)用時(shí),當(dāng)用戶按著屏幕一口氣滑過臨界值,還不松手呢?還不顯示imageview嗎?也行,個(gè)人覺得不太好。
于是,我選擇在move中調(diào)用imageview地線程。有人會(huì)想,這樣會(huì)不會(huì)啟動(dòng)N多個(gè)線程呢?move一直在移動(dòng)呢?!霸趇amgeview判斷下線程的狀態(tài)即可,如果已經(jīng)啟動(dòng)了,就不啟動(dòng)唄”?;蛟S這么寫不太好,但我認(rèn)為是實(shí)時(shí)的,用戶體驗(yàn)好。

看代碼:

/** 
  * 獲取待監(jiān)控的view對(duì)象 
  * 實(shí)時(shí)調(diào)起線程,監(jiān)控是否scroll停止,來判斷是否需要顯示imageView 
  * @param targetView 需要監(jiān)控的對(duì)象 
  */ 
 public void tellMe(View targetView) { 
  if (targetView == null) 
   throw new IllegalArgumentException("please set targetView who to scrollTo"); 
  if (this.targetView == null) 
   this.targetView = targetView; 
  if (!isStarting) { 
   new Thread(scanThread).start(); 
  } 
 }

此處注意,我偷懶了,沒有單獨(dú)設(shè)置方法傳遞需要滾動(dòng)的scrollview,在此處引進(jìn)來了。線程加了判斷。此處不要傳遞scrollview的scrollY值進(jìn)來。比喻當(dāng)你手指離開屏幕后,之前傳遞進(jìn)來的scrollY就已經(jīng)過時(shí)了,scrollview仍在滑動(dòng)。在消息回調(diào)里面實(shí)時(shí)獲取再判斷

private class MyCallback implements Runnable { 
  @Override 
  public void run() { 
   /** 
    * 獲取實(shí)時(shí)的卷動(dòng)值,不要傳遞scroll值給我 
    */ 
   endScrollX = targetView.getScrollX(); 
   int scrollY = targetView.getScrollY(); 
   if (endScrollY != scrollY) { 
    endScrollY = scrollY; 
   } else { 
    if (endScrollY >= limitHeight) { 
     if (!thisStateVisible) 
      visible(); 
    } else { 
     if (thisStateVisible) 
      gone(); 
    } 
    /** 
     * 已判定,卷動(dòng)停止,顯示或隱藏當(dāng)前view已完成 
     * 退出監(jiān)控scroll線程 
     */ 
    clearCallBacks(); 
   } 
  } 
 }

由于是用線程來檢測(cè)scrollview的滾動(dòng)狀態(tài),我用了延時(shí)消息。此時(shí)又有另外一個(gè)潛在bug。在自定義imageview中創(chuàng)建了handler屬于主線程,子線程中需要發(fā)延時(shí)消息。如果延時(shí)消息發(fā)出后,activity退出了呢?反復(fù)這么弄呢?有人會(huì)說沒誰會(huì)這么無聊的。但這畢竟還是潛在的OOM。于是我簡(jiǎn)單的做了線程控制和消息清除的代碼,過于簡(jiǎn)單。感謝評(píng)論。

主要思路和邏輯都分析完了,使用起來很簡(jiǎn)答,你不用關(guān)心自定義imageview里面的邏輯(除非你想改進(jìn))。

在activity中

private PullToRefreshScrollView mScrollView; 
 private ToTopImageView imageView_to_top; 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_pull_to_refresh_scroll_view); 
 
  imageView_to_top = (ToTopImageView) findViewById(R.id.imageView_to_top); 
  imageView_to_top.setLimitHeight(800); 
  mScrollView = (PullToRefreshScrollView) findViewById(R.id.scrollView); 
  final ScrollView scrollView = mScrollView.getRefreshableView(); 
  //mScrollView.setOnTouchListener(); 無效 
  scrollView.setOnTouchListener(new View.OnTouchListener() { 
   @Override 
   public boolean onTouch(View v, MotionEvent event) { 
    switch (event.getAction()){ 
     case MotionEvent.ACTION_MOVE: 
      imageView_to_top.tellMe(scrollView); 
      break; 
    } 
    return false; 
   } 
  }); 
 } 
 
 @Override 
 protected void onDestroy() { 
  imageView_to_top.clearCallBacks(); 
  super.onDestroy(); 
 }

頁面上,在你覺得合適的位置:

<com.znke.pulltorefresh_top.tool.ToTopImageView 
  android:id="@+id/imageView_to_top" 
  android:layout_width="50dp" 
  android:layout_height="50dp" 
  android:layout_alignParentBottom="true" 
  android:layout_alignParentRight="true" 
  android:layout_marginBottom="5dp" 
  android:layout_marginRight="5dp" 
  android:background="@drawable/to_top" />

以上就是怎么在Android應(yīng)用中利用 scrollToTop實(shí)現(xiàn)一個(gè)點(diǎn)擊回到頂部功能,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站名稱:怎么在Android應(yīng)用中利用scrollToTop實(shí)現(xiàn)一個(gè)點(diǎn)擊回到頂部功能
URL標(biāo)題:http://jinyejixie.com/article0/ggeeoo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、自適應(yīng)網(wǎng)站、定制網(wǎng)站、微信小程序、企業(yè)網(wǎng)站制作、營銷型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
双牌县| 麦盖提县| 都安| 聂荣县| 宿迁市| 全州县| 洪洞县| 重庆市| 休宁县| 茶陵县| 文昌市| 喀喇沁旗| 中江县| 青铜峡市| 出国| 徐汇区| 万源市| 泸州市| 读书| 深州市| 普洱| 资源县| 尤溪县| 六安市| 苍南县| 屏东县| 金阳县| 汤阴县| 池州市| 旺苍县| 靖宇县| 新化县| 旬阳县| 安图县| 正安县| 四子王旗| 皋兰县| 台安县| 渑池县| 吐鲁番市| 巴林左旗|