AndroidRecyclerView滚动到中间位置的方法示例
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
AndroidRecyclerView滚动到中间位置的⽅法⽰例
最近看到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(yout.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;
}
}
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。