RecyclerView点击,移动到中间位置
这篇博客介绍怎样给RecyclerView添加点击事件,点击某一条item,被点击的item能移动到中间位置。
例如我们点击靠右边的03-28那一个item,这个item会自动滑到中间位置,效果如下:
具体实现过程是怎么样的呢?(RecyclerView的使用前面的博客已介绍过,这里就不再赘述了。)
首先,我们在RecyclerView的adapter里,自定义一个接口OnItemClickListener,onBindViewHolder()方法中,给item添加点击事件。示例代码如下:
package com.li.recyclerviewdemo;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.ViewHolder> {
private Context context;
private List<TestBeans> datas;
private RvAdapter.OnItemClickListener onItemClickListener;
//用来标记点击的item位置,方便设置背景颜色
private List<Integer> posList = new ArrayList<Integer>();
public RvAdapter(Context context, List<TestBeans> datas) {
super();
this.context = context;
this.datas = datas;
}
public void setOnItemClickListener(RvAdapter.OnItemClickListener listener){
this.onItemClickListener = listener;
}
@Override
public int getItemCount() {
return datas == null ? 0 : datas.size();
}
@Override
public void onBindViewHolder(final ViewHolder holder, int pos) {
TestBeans bean = datas.get(pos);
holder.tvDate.setText(bean.getDateMd());
holder.tvDay.setText(bean.getDateDay());
holder.tvPrice.setText(bean.getPrice());
//设置点击事件的回调
holder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(onItemClickListener != null){
int position = holder.getPosition();
onItemClickListener.onItemClick(holder.itemView, position);
//标记点击的item位置
posList.clear();
posList.add(position);
}
}
});
if(posList.contains(pos)){
holder.itemView.setBackgroundColor(context.getResources().getColor(R.color.green));
}else{
holder.itemView.setBackgroundColor(context.getResources().getColor(R.color.grey));
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
View v = LayoutInflater.from(arg0.getContext()).inflate(
R.layout.rv_adapter_item, arg0, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvDate;
TextView tvDay;
TextView tvPrice;
public ViewHolder(View itemView) {
super(itemView);
tvDate = (TextView) itemView.findViewById(R.id.tvDate);
tvDay = (TextView) itemView.findViewById(R.id.tvDay);
tvPrice = (TextView) itemView.findViewById(R.id.tvPrice);
}
}
/**
* 自定义的点击事件接口
* @author lish
*/
public interface OnItemClickListener{
void onItemClick(View view, int position);
// void onItemLongClick(View view, int position); //长按
}
}
MainActivity.java 中,adapter添加点击事件,然后被点击的item移动到中间位置。
adapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this, "-->" + position, Toast.LENGTH_SHORT).show();
moveToMiddle(view);
adapter.notifyDataSetChanged();
}
});
View移动的方法:
/**
* 滚动到中间位置
* @param clkView 被点击的View
*/
public void moveToMiddle(View clkView){
int itemWidth = clkView.getWidth();
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int scrollWidth = clkView.getLeft() - (screenWidth / 2 - itemWidth / 2);
rvView.scrollBy(scrollWidth, 0);
}
移动到中间位置基本原理:先计算出屏幕宽度screenWidth,被点击View的宽度itemWidth,被点击View距离左边的距离为clkView.getLeft(),需要移动的宽度是 clkView.getLeft() - (screenWidth / 2 - itemWidth / 2);
这些距离计算,在纸上画一下就比较清晰了,我画了一下,有点难看,但是能说明问题,不清楚的多想想。
完整示例代码如下:
package com.li.recyclerviewdemo;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import com.li.recyclerviewdemo.RvAdapter.OnItemClickListener;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
private RecyclerView rvView;
private LinearLayoutManager layoutManager;
private RvAdapter adapter;
private List<TestBeans> beanList = new ArrayList<TestBeans>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getDatas();
initView();
}
private void initView() {
rvView = (RecyclerView) findViewById(R.id.rvView);
layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
rvView.setLayoutManager(layoutManager);
adapter = new RvAdapter(this, beanList);
rvView.setAdapter(adapter);
adapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this, "-->" + position, Toast.LENGTH_SHORT).show();
moveToMiddle(view);
adapter.notifyDataSetChanged();
}
});
}
/**
* 滚动到中间位置
* @param clkView 被点击的View
*/
public void moveToMiddle(View clkView){
int itemWidth = clkView.getWidth();
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int scrollWidth = clkView.getLeft() - (screenWidth / 2 - itemWidth / 2);
rvView.scrollBy(scrollWidth, 0);
}
private void getDatas() {
Calendar cal = Calendar.getInstance(Locale.CHINA);
SimpleDateFormat sdfMd = new SimpleDateFormat("MM-dd");
String[] dayNames = getResources().getStringArray(R.array.week_day);
for (int i = 0; i < 15; i++) {
cal.add(Calendar.DAY_OF_MONTH, 1);
Date date = cal.getTime();
String dateMd = sdfMd.format(date);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (dayOfWeek < 0) {
dayOfWeek = 0;
}
String day = dayNames[dayOfWeek];
TestBeans bean = new TestBeans();
bean.setDateMd(dateMd);
bean.setDateDay(day);
bean.setPrice("¥" + (i+1) * 100);
beanList.add(bean);
}
}
}