在写RecyclerVIew的适配器时,我们都要重写一个方法onBindViewHolder,这个方法在何时会执行呢?只要有一个item进入了手机界面(只要有item进入了手机界面,那么就会被加载),那么这个方法就会执行,对于的position就是这个item的下标。
比如现在有界面中14个测试item
?我们在onBindViewHolder方法中通过Log.d输出以下内容
Log.d("onBindViewHolder","item"+position);
可以看到确实输出了14个item,我们继续将界面上滑,
又有两个item进入了界面,有如下输出:
还有一个方法叫做notifyDataSetChanged(),一旦适配器调用这个方法,就会通知item项已经更新,那么有多少个item被加载了,onBindViewHolder方法就会重新执行多少次。这也就是相当于调用一次notifyDataSetChanged()方法,就可以通过onBindViewHolder方法去遍历所有已被加载的item。
而点击修改item样式的思路就是先找到被点击的item,然后修改它的样式,而其他的就修改为未被点击的样式,这样将上一个被点击的item的样式也修改过来了。
但是如何让onBindViewHolder方法知道当前点击的时哪个item呢?我们知道每一个item都会有一个position,为item设置点击事件?,然后通过接口回调的方式可以将所点击的item的position从onBindViewHolder方法拿到适配器实例化所在类中使用。
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.getPosition(position); // 这个listener是自定义的回调接口
}
});
}
adapter.setOnItemClickListener(new TestRecyclerViewAdapter.OnItemClickListener() {
@Override
public void getPosition(int position) {
// 这里可以使用了。
}
});
?而在点击完成后,在再次onBindViewHolder执行方法的时候,想让onBindViewHolder方法知道这个position是哪个item的,我们可以在适配器设置一个变量mPosition,然后为这个变量创建设置set和获取get方法。
private int mPosition;
public int getPosition(){
return mPosition;
}
public void setPosition(int mPosition) {
this.mPosition = mPosition;
}
然后点击的时候就可以通过实例化对象调用设置变量方法来将position传递到适配器中去,然后在item的点击事件的onlick方法中通过获取方法拿到这个position。至此,在方法中可以知道当前点击的是哪个item了,进而在方法中判断当前变量到的item的position和点击的item的position是否相同,然后执行相应的修改即可。
完整代码如下:
适配器代码:
package com.example.scrolllayoutapplication;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class TestRecyclerViewAdapter extends RecyclerView.Adapter<TestRecyclerViewAdapter.ViewHolder> {
private List<String> mList;
private Context context;
private OnItemClickListener listener;
private static int cnt = 0;
public TestRecyclerViewAdapter(List<String> mList, Context context){
this.mList = mList;
this.context = context;
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView tv;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
}
}
// 回调接口
public interface OnItemClickListener{
void getPosition(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.test_click,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.getPosition(position);
}
});
// 判断当前遍历的item的position和点击的item的position是否相同
// 相同则要修改为选中的样式
if(position == getPosition()) {
holder.tv.setBackgroundResource(R.color.black);
}
else {
holder.tv.setBackgroundResource(R.color.white);
}
}
@Override
public int getItemCount() {
return mList.size();
}
private int mPosition;// 当前点击的item的position
public int getPosition(){
return mPosition;
}
public void setPosition(int mPosition) {
this.mPosition = mPosition;
}
}
测试入口类代码:
package com.example.scrolllayoutapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
public class MainActivity6 extends AppCompatActivity {
private List<String>mList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main6);
for(int i = 0; i < 100; i++) {
mList.add("1");
}
RecyclerView ry = (RecyclerView) findViewById(R.id.ry);
TestRecyclerViewAdapter adapter = new TestRecyclerViewAdapter(mList,this);
ry.setAdapter(adapter);
ry.setLayoutManager(new LinearLayoutManager(this));
adapter.setOnItemClickListener(new TestRecyclerViewAdapter.OnItemClickListener() {
@Override
public void getPosition(int position) {
// 设置当前点击的item的position
adapter.setPosition(position);
// 通知适配器去修改,然后就会去执行onBindViewHolder方法
adapter.notifyDataSetChanged();
}
});
}
}
|