2023年6月28日发(作者:)
AndroidRecyclerView滚动到中间位置的⽅法⽰例最近看到QQ⾳乐的歌词每次滑动后都可以滚回到中间位置。觉得甚是神奇,打开开发者模式显⽰布局,发现歌词部分不是采⽤ android 控件的写的,应该是前端写的。于是,我想,能不能⽤ recyclerView 实现这个⾃动回滚到中间位置呢。功夫不负有⼼⼈,查找了⼀些资料之后,终于搞定了。下⾯由我细细讲来。⽬标点击某个条⽬,在经过4s⽆任何操作之后,该条⽬滚动到中间位置显⽰。点击后,⽤户在滑动,等⽤户不操作后再开始延时。⽤户多次点击,记最后⼀次点击位置。分析⾸先先考虑,滚动到指定位置是如何操作的?// 滚动到指定位置ToPosition(position);// 平滑滚动到指定位置ScrollToPosition(position);有没有滚动到制定像素位置呢?// scrollBy(x, y)这个⽅法是⾃⼰去控制移动的距离,单位是像素,所以在使⽤scrollBy(x, y)需要⾃⼰去计算移动的⾼度或宽度。By(x, y)可是,问题是滚动到中间位置啊?这个怎么办呢?这样⼦⾏不⾏呢?ToPosition(0);By(0,400);先滚动到制定位置,在滚动⼀段距离不就好了?运⾏发现,这两⾏代码只执⾏第⼀⾏,第⼆⾏⽆效。debug 调试看了下,还是没有弄懂,实现太复杂。那就是说这样是不⾏的,那有没有其他办法呢?RecyclerView 有⼀个滚动监听⽅法:crollListener(new llListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { llStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { lled(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(); balVisibleRect(rect); reHeight = - - vHeight;当运⾏ scrollToPosition 后,点击条⽬就会出现在视野当中,这时候,计算出相应的位移即可。需要注意⼀点的是,当点击条⽬在视野内的时候,是不会运⾏ scrollToPosition ⽅法的。 int top = ldAt(position - firstPosition).getTop();int half = reHeight / 2; By(0, top - half);最后就是延时的设定,采⽤Handler 进⾏延时。代码核⼼代码如下:public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private RecyclerView mRecyclerView; private LinearLayoutManager mLayoutManager; private r 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) { te(savedInstanceState); setContentView(ty_main); handler = new Handler(); mRecyclerView = (RecyclerView) findViewById(_recycler_view); //创建默认的线性LayoutManager mLayoutManager = new LinearLayoutManager(this); oMeasureEnabled(true); outManager(mLayoutManager); //如果可以确定每个item的⾼度是固定的,设置这个选项可以提⾼性能 FixedSize(true); tedScrollingEnabled(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 { ToPosition(position); isMove = true; isClick = false; } } }; mAdapter = new MyAdapter(data, new clerViewItemClick() { @Override public void onItemClick(View v, int pos) { xt(, "第" + pos + "⾏", _SHORT).show(); position = pos; vHeight = ght(); Rect rect = new Rect(); balVisibleRect(rect); reHeight = - - vHeight; // CallbacksAndMessages(null); Callbacks(runnable); layed(runnable, 4000); isClick = true; } }); pter(mAdapter); crollListener(new llListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { llStateChanged(recyclerView, newState); Log.d(TAG, "" + newState); if (newState == _STATE_DRAGGING && !isMove) { Callbacks(runnable); } if (newState == _STATE_IDLE) { if (isClick) { layed(runnable, 4000); } } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { lled(recyclerView, dx, dy); if (isMove) { if (vHeight < 0) { isMove = false; return; } scrollToMiddle(); } } });public void scrollToMiddle() { final int firstPosition = rstVisibleItemPosition(); int top = ldAt(position - firstPosition).getTop(); Log.d(TAG, " position" + position + " " + top); int half = reHeight / 2; By(0, top - half); isMove = false; } public boolean isVisible() { final int firstPosition = rstVisibleItemPosition(); final int lastPosition = stVisibleItemPosition(); return position <= lastPosition && position >= firstPosition; } @Override protected void onDestroy() { roy(); CallbacksAndMessages(null); handler = null; }}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687956510a60736.html
评论列表(0条)