Android RecycleView使用方法的介绍

一、RecycleView的基本使用
RecycleView同ListView一样在APP页面中以列表的形式显示元素,由于提供数据的方式有很多种list,array,map或者set等,但是最终都需要将这些数据源,以统一的样式显示出来。因此在RecycleView(ListView)的使用中,有RecycleView负责显示,Adpter负责对数据进行适配操作,数据源(一般是List)部分。
1.1 gradle倒包
compile 'com.android.support:recyclerview-v7:25.2.0'
1.2 布局控件
在Activity的activity_main.xml布局文件中添加RecycleView控件
<?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/id_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
为这个RecycleView创建一个item布局文件item_recycleview.xml,并为它添加简单的元素TextView,代码如下
<?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="60dp"
android:gravity="center_vertical">
<TextView
android:id="@+id/recycle_textview"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:textSize="20sp"/>
</LinearLayout>
1.3 Adater代码和Activity代码的编写
新建一个 RecyclerView.Adapter适配器TestRecycleViewAdapter,在新建的Adapter中需要完成三个重要的操作:
1.实现一个RecycleView.ViewHolder,该ViewHolder主要用来绑定创建的item_recycleview.xml布局文件中的控件元素。
2.重写父类的onCreateViewHolder函数,该函数主要用来创建刚定义的ViewHolder的对象,可以用来显示Item元素。
3.重写父类的onBindViewHolder函数,在函数中可以设置每个Item项特有的参数信息。
public class TestRecycleViewAdapter extends RecyclerView . Adapter<TestRecycleViewAdapter . ViewHolderA> {
private Context mContext;
private List < String > mList;

public TestRecycleViewAdapter ( Context context, List < String > list) {
mContext = context;
mList = list;
}

// 创建每个显示的 Item 元素
@Override
public ViewHolderA onCreateViewHolder( ViewGroup parent, int viewType) {
// 此处动态加载 ViewHolder 的布局文件并返回 holder
View view = LayoutInflater .from(mContext).inflate( R .layout.recycleview_item, parent, false );
ViewHolderA holderA = new ViewHolderA (view);
return holderA;
}

// 设置每个显示的 Item 元素的独特的参数
@Override
public void onBindViewHolder( ViewHolderA holder, int position) {
// 此处设置 Item view 的数据
holder.mTextView.setText(mList.get(position));
}

@Override
public int getItemCount() {
// 生成的 item 的数量
return mList.size();
}

//RecyclerView 中每个 Item ViewHolder ,以及 item 内部布局控件进行 id 绑定
class ViewHolderA extends RecyclerView . ViewHolder {

TextView mTextView;
public ViewHolderA ( View itemView) {
super (itemView);
mTextView = ( TextView ) itemView.findViewById( R .id.recycle_textview);
}
}
}
在Activity中使用的代码
public class MainActivity extends AppCompatActivity {
private List<String> list; //数据源
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.activity_main_recycle_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
initData();
//实例化adapter,并传输数据给adapter
TestRecycleViewAdapter adapter = new TestRecycleViewAdapter(getApplicationContext(), list);
mRecyclerView.setAdapter(adapter);
}

/**
* 添加数据
* */
private void initData() {
list = new ArrayList<>();
for (int i = 0; i < 50; i++) {
list.add("item" + i);
}
}
}
二、RecycleView的不同风格和布局的显示
三、RecycleView的Item点击事件
RecycleView的Item点击事件的处理方式有三种:
3.1 在Adpater中实现
直接在Adapter中的onBindViewHolder()方法中实现点击事件,参考如下代码。
@Override
public void onBindViewHolder (MyViewHolder viewHolder, final int postion) {

viewHolder.textView.setText(mDatas.get(postion));
viewHolder.rootView.setOnClickListener( new OnClickListener() {
@Override
public void onClick (View arg0) {
// 点击事件
Toast.makeText(mContext, postion + "" , 1000 ).show();
}
});
}
这种方式的优点是,可以很方便的实现点击事件,代码不用很复杂;缺点也很明显,就是adapter一般只持有数据源的引用,不能实现很复杂的逻辑处理操作。
3.2 在Activity中实现
1.先在Adapter中定义一个接口。
public interface onRecyclerViewItemClick {
void onItemClick(View v, int position);
}
2. 在Adapter中定义一个刚才定义的接口变量,并定义一个函数,或者在Adapter的构造函数中接受接口的引用。
private onRecyclerViewItemClick mOnRvItemClick;

public DemoAdapter(Context ctx, String[] strings, onRecyclerViewItemClick onRvItemClick) {
mContext = ctx;
this .mOnRvItemClick = onRvItemClick;
this .strings = strings;
}
3. 在自定义的ViewHolder中实现onClickListenr接口,并设置onItemClick事件,将点击事件传到自定义的接口上去,最终传到外面的Activity调用者上去。
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
@BindView(R.id.textView)
TextView textView;

public ViewHolder(View itemView) {
super (itemView);
ButterKnife.bind( this , itemView);
itemView.setOnClickListener( this );
}

public void setData( int position) {
textView.setText("第" + position + "行");
}
//设置onItemClick事件
@Override
public void onClick(View view) {
if (mOnRvItemClick != null )
mOnRvItemClick.onItemClick(view, getAdapterPosition());
}
}
4.在Activity中实现onItemClick方法
public class MainActivity extends AppCompatActivity {

@BindView(R.id.recycler_view)
RecyclerView mRecyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind( this );
DemoAdapter myAdapter = new DemoAdapter( this , null , new DemoAdapter.onRecyclerViewItemClick() {
@Override
public void onItemClick(View v, int position) {
Snackbar.make(v, "第" + position + "行", Snackbar.LENGTH_SHORT).show();
}
} );
mRecyclerView.setLayoutManager( new LinearLayoutManager( this , LinearLayoutManager.VERTICAL, false ));
mRecyclerView.setAdapter(myAdapter);
}

}
5.为了便于查阅,整体的Adapter的代码如下。
public class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.ViewHolder> {

private onRecyclerViewItemClick mOnRvItemClick;

private Context mContext;

String[] strings;

public DemoAdapter(Context ctx, String[] strings, onRecyclerViewItemClick onRvItemClick) {
mContext = ctx;
this .mOnRvItemClick = onRvItemClick;
this .strings = strings;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main_item, parent, false );
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.setData(position);
}

@Override
public int getItemCount() {
return 20;
}


public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
@BindView(R.id.textView)
TextView textView;

public ViewHolder(View itemView) {
super (itemView);
ButterKnife.bind( this , itemView);
itemView.setOnClickListener( this );
}

public void setData( int position) {
textView.setText("第" + position + "行");
}

@Override
public void onClick(View view) {
if (mOnRvItemClick != null )
mOnRvItemClick.onItemClick(view, getAdapterPosition());
}
}

/**
* item点击接口
*/
public interface onRecyclerViewItemClick {
void onItemClick(View v, int position);
}

}
3.3 修改RecyclerView源码
这种方式一般不常见,也推荐使用。
四、RecycleView中的乱序处理
4.1问题由来
在RecycleView的使用过程中可能会出现这样,比如使用了checkbox控件,在勾选某项的checkbox之后,滑动checkbox的过程中后面的checkbox也被勾选上了,这种问题是由于RecycleView使用的复用的机制。
4.2解决办法
解决该问题的办法一般是用一个数组或者hashmap将列表中position对应Item的checkbox的状态值保存下来,并在 onBindViewHolder 绑定视图时重新更新checkbox的状态,如果在对Item的checkbox状态进行更新时,一定要对对应的数组或者map中对应的值进行更新,参见如下代码:
@Override
public void onBindViewHolder(ViewHolder holder, final int position ) {
//设置checkBox改变监听
holder.checkBox.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//用map集合保存checkbox改变的状态值
map . put ( position , isChecked);
}
});
// 用map集合保存checkbox不确定情况下的状态值
if ( map . get ( position ) == null) {
map . put ( position , false);
}
//用map中的值更新checkbox的状态
holder.checkBox.setChecked( map . get ( position ));
}
4.3 乱序问题的进一步升级和处理
如果RecycleView列表中需要删除某项Item项时,在重复删除操作之后依旧可能出现乱序的情况(具体问题描述详情参考: http://blog.csdn.net/Zackratos/article/details/52346986),该问题的处理步骤包括:
1.删除数组中对应的元素值
2.删除对应的Item项,并对整个Item列表进行调整。
五、参考博客链接如下
RecycleView的Item点击事件处理:
RecycleView的乱序处理:
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值