前言
RecyclerView是Android 5.0 新出的一个控件,可以完全代替之前的ListView,当然功能各方面也比较强大,今天来看看实际项目中可能会遇到的一些与RecyclerView相关的功能实现。
效果图一
条目单选并监听
代码
MainActivity
public class MainActivity extends AppCompatActivity{
private List<String> datas;
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyview);
initData();
final CustomAdapter adapter = new CustomAdapter(this,datas);
GridLayoutManager manager = new GridLayoutManager(this,2);
recyclerView.setLayoutManager(manager);
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(new CustomAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View view, String data, int position) {
//data为内容,position为点击的位置 ToastUtil.getShortToastByString(MainActivity.this,"data: "+data+",position: "+position);
}
});
}
public void initData() {
datas = new ArrayList<>();
for (int i = 'A'; i < 'K'; i++) {
datas.add(""+(char)i);
}
}
}
MainActivity布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
CustomAdapter
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private Context context;
private List<String> data;
private OnRecyclerViewItemClickListener mOnItemClickListener;
private MyViewHolder holder;
private int layoutPosition;
public interface OnRecyclerViewItemClickListener {
void onItemClick(View view , String data,int position);
}
public CustomAdapter(Context context, List<String> data){
this.context = context;
this.data = data;
}
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
this.mOnItemClickListener = listener;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = View.inflate(context, R.layout.item_view, null);
holder = new MyViewHolder(itemView);
return holder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.textView.setText(data.get(position));
holder.itemView.setTag(data.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//获取当前点击的位置
layoutPosition = holder.getLayoutPosition();
notifyDataSetChanged();
mOnItemClickListener.onItemClick(holder.itemView, (String) holder.itemView.getTag(), layoutPosition);
}
});
//更改状态
if(position == layoutPosition){
holder.textView.setBackgroundResource(R.drawable.bg_unselect);
holder.textView.setTextColor(Color.RED);
}else{
holder.textView.setBackgroundResource(R.drawable.bg_select);
holder.textView.setTextColor(Color.BLUE);
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.tv_item);
}
}
}
条目布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
>
<TextView
android:id="@+id/tv_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"
android:background="@drawable/bg_unselect"
/>
</LinearLayout>
条目选中和未选中的背景
//bg_unselect
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/holo_orange_dark"/>
<corners android:radius="8dp"/>
</shape>
//bg_select
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/holo_blue_light"/>
<corners android:radius="8dp"/>
</shape>
最后是一个连续不重复弹Toast的工具类
public class ToastUtil {
private static Context context = null;
private static Toast toast = null;
public static void getShortToast(Context context,int retId){
if (toast == null) {
toast = Toast.makeText(context, retId, Toast.LENGTH_SHORT);
} else {
toast.setText(retId);
toast.setDuration(Toast.LENGTH_SHORT);
}
toast.show();
}
public static void getShortToastByString(Context context,String hint){
if (toast == null) {
toast = Toast.makeText(context, hint, Toast.LENGTH_SHORT);
} else {
toast.setText(hint);
toast.setDuration(Toast.LENGTH_SHORT);
}
toast.show();
}
public static void getLongToast(Context context,int retId){
if (toast == null) {
toast = Toast.makeText(context, retId, Toast.LENGTH_LONG);
} else {
toast.setText(retId);
toast.setDuration(Toast.LENGTH_LONG);
}
toast.show();
}
public static void getLongToastByString(Context context, String hint){
if (toast == null) {
toast = Toast.makeText(context, hint, Toast.LENGTH_LONG);
} else {
toast.setText(hint);
toast.setDuration(Toast.LENGTH_LONG);
}
toast.show();
}
}
如果刚进来不想选中第一个条目,可以定一个标记
//更改状态
if(position == layoutPosition&&!isFirstEnter){
holder.textView.setBackgroundResource(R.drawable.bg_unselect);
holder.textView.setTextColor(Color.RED);
}else{
holder.textView.setBackgroundResource(R.drawable.bg_select);
holder.textView.setTextColor(Color.BLUE);
isFirstEnter = false;
}
效果图二
设置条目之间的间距
public class MainActivity extends AppCompatActivity{
private RecyclerView recyclerView;
private List<String> datas = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.rv_content);
initData();
RvContentAdapter adapter = new RvContentAdapter(this,datas);
GridLayoutManager manager = new GridLayoutManager(this,3);
recyclerView.setLayoutManager(manager);
SpaceItemDecoration itemDecoration = new SpaceItemDecoration(10,20);
recyclerView.addItemDecoration(itemDecoration);
recyclerView.setAdapter(adapter);
}
public void initData() {
datas = new ArrayList<>();
for (int i = 'A'; i < 'Z'; i++) {
datas.add(""+(char)i);
}
}
}
public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
private int horizontalspace;
private int verticalspace;
public SpaceItemDecoration(int horizontalspace,int verticalspace) {
this.horizontalspace = horizontalspace;
this.verticalspace = verticalspace;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
//不是第一个的格子都设一个左边和底部的间距
outRect.left = horizontalspace;
outRect.bottom = verticalspace;
// //由于每行都只有3个,所以第一个都是3的倍数,把左边距设为0
if (parent.getChildLayoutPosition(view) %3==0) {
outRect.left = 0;
}
int childCount = parent.getChildCount();
}
}
效果图三
条目多选并且监听
public class RvContentAdapter extends RecyclerView.Adapter<RvContentAdapter.MyViewHolder>{
private Context context;
private List<String> contentDatas;
public OnItemSelectedListener mListener;
private boolean[] isSelected ;
public interface OnItemSelectedListener{
void onItemSelect(int position);
}
public void setOnItemSelectedListener(OnItemSelectedListener listener){
mListener = listener;
}
public RvContentAdapter(Context context, List<String> data){
this.context = context;
this.contentDatas = data;
isSelected = new boolean[data.size()];
for (int i = 0; i < data.size(); i++) {
isSelected[i] = false;
}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(View.inflate(context,R.layout.list_item_layout,null));
}
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.tvTitle.setText(contentDatas.get(position));//标题
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
isSelected[position]=isSelected[position]==true?false:true;
notifyDataSetChanged();
mListener.onItemSelect(position);
}
});
if(isSelected[position] == true){
holder.linearLayout.setBackgroundResource(R.drawable.bg_item_select);
}else{
holder.linearLayout.setBackgroundResource(R.drawable.bg_item_unselect);
}
}
@Override
public int getItemCount() {
return contentDatas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
private final TextView tvTitle;
private final LinearLayout linearLayout;
public MyViewHolder(View itemView) {
super(itemView);
tvTitle = (TextView) itemView.findViewById(R.id.tv_item);
linearLayout = (LinearLayout) itemView.findViewById(R.id.ll_parent);
}
}
}
然后我们在Activity中调用下面的方法设置回调监听
adapter.setOnItemSelectedListener(new RvContentAdapter.OnItemSelectedListener() {
@Override
public void onItemSelect(int position) {
Toast.makeText(MainActivity.this, datas.get(position), Toast.LENGTH_SHORT).show();
}
});