感谢 https://blog.csdn.net/My_Luna/article/details/50261925 Android之双击回到顶部
感谢 https://www.jianshu.com/p/3acc395ae933 RecycleView4种定位滚动方式演示
如果是操作ListView请直接看第一个链接里的内容
0.先看效果
TIM图片20180427103010.gif1.定义双击事件接口
/**
* @author wfy
* 单击双击事件接口
*/
public interface OnDoubleClickListener {
public void OnSingleClick(View v);
public void OnDoubleClick(View v);
}
2.定义DoubleClick类
它提供一个静态方法给一个view注册双击事件,具体看注释
/**
* @author wfy
* 消息列表+好友动态的双击回到顶部
*/
public class DoubleClick {
public static void registerDoubleClickListener(View view, final OnDoubleClickListener listener){
if(listener==null) return;
view.setOnClickListener(new View.OnClickListener() {
//双击间隔时间350毫秒
private static final int DOUBLE_CLICK_TIME = 350;
private boolean flag = true;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
listener.OnSingleClick((View)msg.obj);
}
};
//等待双击
public void onClick(final View v) {
if(flag){
flag = false;//与执行双击事件
new Thread(){
public void run() {
try {
Thread.sleep(DOUBLE_CLICK_TIME);
//此时线程沉睡 而flag被修改为false 在DOUBLE_CLICK_TIME内点击则 进入else
} catch (InterruptedException e) {
e.printStackTrace();
} //等待双击时间,否则执行单击事件
if(!flag){
//睡醒了看一看flag被人动过没,没有人动,则认作单击事件
//因此不建议用此方法执行单击事件 因为会等待睡醒,有点击延迟的存在
//没有人动,自己把它改成true,以接受下次点击
flag = true;
Message msg = handler.obtainMessage();
msg.obj = v;
//发个消息,让执行单击
handler.sendMessage(msg);
}
}
}.start();
}else{
flag = true;
listener.OnDoubleClick(v); //执行双击
}
}
});
}
}
3.给你要双击的组件注册双击事件
此处以Button为例
Button button=new Button(this);
DoubleClick.registerDoubleClickListener(button, new OnDoubleClickListener() {
@Override
public void OnSingleClick(View v) {
// TODO Auto-generated method stub
}
@Override
public void OnDoubleClick(View v) {
// TODO Auto-generated method stub
GoTopTask task=new GoTopTask();
task.execute(firstposition);
}
});
4.获取RecyclerView当前所在的item的position
也就是给第3步中给firstposition赋值
task.execute(firstposition);
那么如何获得RecyclerView当前所在的item的position呢?
//监听RecyclerView滚动位置firstPosition,并将firstPosition值传递给GoTopTask任务
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();
if(lm instanceof LinearLayoutManager){
LinearLayoutManager linearManager = (LinearLayoutManager) lm;
//获取第一个可见view的位置
int firstItemPosition = linearManager.findFirstVisibleItemPosition();
firstPosition = firstItemPosition;
}
}
});
5.GoTopTask异步任务
最后要在这个任务中执行滚动的效果,但是RecyclerView有四种滚动效果(见文章开头链接),具体用哪一个需要考虑一下。
- 如果当前item数量较少(也就是往下滑了很少内容)的话,可以直接使用RecyclerView的
smoothScrollToPosition()
方法,该方法自带滚动效果,可以从当前位置滚动到指定位置。 - 如果当前item数量较多(也就是往下滑了好多内容)的话,那么使用以上方法就会把每个item都滚动完才能到顶部,肯定会消耗大量等待时间,影响用户体验。
- RecyclerView的
scrollToPosition()
方法可以直接跳到指定位置。 - 所以,当前item数量较多时,我们首先采用RecyclerView的
scrollToPosition()
方法先跳到指定位置(这里我设置了STARTPOSITION10,根据每条item条目内容高度,自己设定合理的值),然后再利用RecyclerView的smoothScrollToPosition()
方法滚动到顶部,用户体验比较好。
这是一个内部类
/*===================新增====================*/
/**
* method desc. : 传递当前RecyclerView的Item值,回滚到顶部
* 修改休眠值可以改变滚动时间
* params :
* return :
*/
protected class GoTopTask extends AsyncTask<Integer, Integer, String> {
private RecyclerView recyclerView;
private static final int STARTPOSITION = 10;//开始滑动的位置
public GoTopTask(View view) {
recyclerView = (RecyclerView) view;
}
@Override
protected void onPreExecute() {
//回到顶部时间置0 此处的时间不是狭义上的时间
super.onPreExecute();
}
@Override
protected String doInBackground(Integer... params) {
// TODO Auto-generated method stub
for(int i=params[0];i>=0;i--){
//返回顶部时间耗费15个item还没回去,则直接去顶部
//目的:要产生滚动的假象,但也不能耗时过多
if(i > STARTPOSITION){
publishProgress(STARTPOSITION);
i = STARTPOSITION;
}else {
publishProgress(i);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public void onProgressUpdate(Integer... values) {
//recyclerView.smoothScrollToPosition(values[0]);
if(values[0] == STARTPOSITION){
recyclerView.scrollToPosition(values[0]);
}else {
recyclerView.smoothScrollToPosition(values[0]);
}
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
@Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
}
}
有问题留言。
以上。
网友评论