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

首頁 > 系統 > Android > 正文

Android RecyclerView 滾動到中間位置的方法示例

2019-10-22 18:14:08
字體:
來源:轉載
供稿:網友

最近看到QQ音樂的歌詞每次滑動后都可以滾回到中間位置。覺得甚是神奇,打開開發者模式顯示布局,發現歌詞部分不是采用 android 控件的寫的,應該是前端寫的。于是,我想,能不能用 recyclerView 實現這個自動回滾到中間位置呢。

功夫不負有心人,查找了一些資料之后,終于搞定了。

下面由我細細講來。

目標

點擊某個條目,在經過4s無任何操作之后,該條目滾動到中間位置顯示。點擊后,用戶在滑動,等用戶不操作后再開始延時。用戶多次點擊,記最后一次點擊位置。

分析

首先先考慮,滾動到指定位置是如何操作的?

// 滾動到指定位置recyclerView.scrollToPosition(position);// 平滑滾動到指定位置recyclerView.smoothScrollToPosition(position);

有沒有滾動到制定像素位置呢?

// scrollBy(x, y)這個方法是自己去控制移動的距離,單位是像素,所以在使用scrollBy(x, y)需要自己去計算移動的高度或寬度。recyclerView.scrollBy(x, y)

可是,問題是滾動到中間位置啊?這個怎么辦呢?這樣子行不行呢?

mRecyclerView.scrollToPosition(0);mRecyclerView.scrollBy(0,400);

先滾動到制定位置,在滾動一段距離不就好了?運行發現,這兩行代碼只執行第一行,第二行無效。

debug 調試看了下,還是沒有弄懂,實現太復雜。

那就是說這樣是不行的,那有沒有其他辦法呢?

RecyclerView 有一個滾動監聽方法:

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {      @Override      public void onScrollStateChanged(RecyclerView recyclerView, int newState) {        super.onScrollStateChanged(recyclerView, newState);      }      @Override      public void onScrolled(RecyclerView recyclerView, int dx, int dy) {        super.onScrolled(recyclerView, dx, dy);      }    });

onScrollStateChanged 方法對應三種狀態:靜止(SCROLL_STATE_IDLE),拖動滾動(SCROLL_STATE_DRAGGING),滑動(SCROLL_STATE_SETTLING)。

當手動緩慢滑動的時候,會觸發: onScrollStateChanged (拖動滾動) --> (n個)onScrolled -->onScrollStateChanged(靜止);

當手快速滑動的時候,會觸發: onScrollStateChanged (拖動滾動) --> (n個)onScrolled --> onScrollStateChanged (滑動) -->

(n個)onScrolled --> onScrollStateChanged (靜止);

有想法了,點擊的時候,先運行 scrollToPosition,在 onScrolled 方法里面 運行 scrollBy 方法。寫代碼,運行,通過。

下面就是中間位置的計算了。

首先計算出 recylerview 的展現高度。

 Rect rect = new Rect(); mRecyclerView.getGlobalVisibleRect(rect); reHeight = rect.bottom - rect.top - vHeight;當運行 scrollToPosition 后,點擊條目就會出現在視野當中,這時候,計算出相應的位移即可。需要注意一點的是,當點擊條目在視野內的時候,是不會運行 scrollToPosition 方法的。    int top = mRecyclerView.getChildAt(position - firstPosition).getTop();int half = reHeight / 2;    mRecyclerView.scrollBy(0, top - half);

最后就是延時的設定,采用Handler 進行延時。

代碼

核心代碼如下:

public class MainActivity extends AppCompatActivity {  private static final String TAG = "MainActivity";  private RecyclerView mRecyclerView;  private LinearLayoutManager mLayoutManager;  private RecyclerView.Adapter mAdapter;  private String[] data;  private Handler handler;  private boolean isClick = false;  private static int vHeight = -1;  private static int reHeight = -1;  private static int position = 0;  private static final int target = 10;  private static boolean isMove = false;  private Runnable runnable;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    handler = new Handler();    mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);    //創建默認的線性LayoutManager    mLayoutManager = new LinearLayoutManager(this);    mLayoutManager.setAutoMeasureEnabled(true);    mRecyclerView.setLayoutManager(mLayoutManager);    //如果可以確定每個item的高度是固定的,設置這個選項可以提高性能    mRecyclerView.setHasFixedSize(true);    mRecyclerView.setNestedScrollingEnabled(false);    data = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21"};    runnable = new Runnable() {      @Override      public void run() {        if (isVisible()) {          scrollToMiddle();        } else {          mRecyclerView.scrollToPosition(position);          isMove = true;          isClick = false;        }      }    };    mAdapter = new MyAdapter(data, new MyAdapter.onRecyclerViewItemClick() {      @Override      public void onItemClick(View v, int pos) {        Toast.makeText(MainActivity.this, "第" + pos + "行", Toast.LENGTH_SHORT).show();        position = pos;        vHeight = v.getHeight();        Rect rect = new Rect();        mRecyclerView.getGlobalVisibleRect(rect);        reHeight = rect.bottom - rect.top - vHeight;        // handler.removeCallbacksAndMessages(null);        handler.removeCallbacks(runnable);        handler.postDelayed(runnable, 4000);        isClick = true;      }    });    mRecyclerView.setAdapter(mAdapter);    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {      @Override      public void onScrollStateChanged(RecyclerView recyclerView, int newState) {        super.onScrollStateChanged(recyclerView, newState);        Log.d(TAG, "" + newState);        if (newState == RecyclerView.SCROLL_STATE_DRAGGING && !isMove) {          handler.removeCallbacks(runnable);        }        if (newState == RecyclerView.SCROLL_STATE_IDLE) {          if (isClick) {            handler.postDelayed(runnable, 4000);          }        }      }      @Override      public void onScrolled(RecyclerView recyclerView, int dx, int dy) {        super.onScrolled(recyclerView, dx, dy);        if (isMove) {          if (vHeight < 0) {            isMove = false;            return;          }          scrollToMiddle();        }      }    });public void scrollToMiddle() {    final int firstPosition = mLayoutManager.findFirstVisibleItemPosition();    int top = mRecyclerView.getChildAt(position - firstPosition).getTop();    Log.d(TAG, " position" + position + " " + top);    int half = reHeight / 2;    mRecyclerView.scrollBy(0, top - half);    isMove = false;  }  public boolean isVisible() {    final int firstPosition = mLayoutManager.findFirstVisibleItemPosition();    final int lastPosition = mLayoutManager.findLastVisibleItemPosition();    return position <= lastPosition && position >= firstPosition;  }  @Override  protected void onDestroy() {    super.onDestroy();    handler.removeCallbacksAndMessages(null);    handler = null;  }}

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


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 肇庆市| 友谊县| 桃江县| 威海市| 延津县| 沙湾县| 化德县| 越西县| 方正县| 洞头县| 新河县| 铁岭县| 绍兴县| 临清市| 祁连县| 呼图壁县| 民乐县| 灵山县| 高密市| 马边| 开封市| 庄浪县| 邮箱| 鄄城县| 苍梧县| 娱乐| 浑源县| 临泉县| 万源市| 墨脱县| 嵩明县| 静宁县| 马山县| 鹤山市| 兴文县| 阿拉尔市| 石家庄市| 福鼎市| 遵义县| 大荔县| 扶风县|