总结一下我的应用程序片段,我有一个RecyclerView
,它的大小是动态的,并且相对于ViewModel
变量(当此变量更改时,RecyclerView的项目列表分别增大或缩小)。
每行都有几个按钮。每个按钮上都有一个OnClickListener
。 (单击后,按钮消失)。
问题: 单击一个按钮时,不仅该按钮消失,而且每增加7的倍数(索引方式)也消失。
例如:即使您只单击了第1行,您在第1行中按了一个按钮,第8、15和22行也发生了完全相同的事情。
我当前正在通过片段的onViewCreated
方法将侦听器传递给适配器中的私有侦听器变量(在构造函数中设置侦听器)。
我将展示我的片段和适配器的相关部分:
片段:
public class MyFragment extends Fragment {
private MyModel model;
private ArrayList<Data> dataList;
private int numberOfDataItems;
private RecyclerView content;
private RecycleAdapter adapter;
private View.OnClickListener onItemClickLIstener = new View.OnClickListener() {
@Override
public void onClick(View view) {
RecyclerAdapter.ViewHolder viewHolder = (RecyclerAdapter.ViewHolder) view.getTag();
// This is the buggy bit
viewHolder.myButton.setVisibility(View.GONE);
int position = viewHolder.getAdapterPosition();
Data data = dataList.get(position);
// TODO: eventually do some logic here with the data
}
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
content = view.findViewById(R.id.content);
model.createDataList(numberOfDataItems);
dataList = model.getDataList();
adapter = new RecycleAdapter(dataList);
content.setAdapter(adapter);
content.setLayoutManager(new LinearLayoutManager(getContext()));
adapter.setOnItemClickListener(onItemClickListener);
}
}
适配器:
public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {
private List<Data> dataList;
private View.OnClickListener onItemClickListener;
public class ViewHolder extends RecyclerView.ViewHolder {
public Button myButton;
public ViewHolder(View itemView) {
super(itemView);
myButton = itemView.findViewById(R.id.myButton);
myButton.setTag(this);
myButton.setOnClickListener(onItemClickListener);
}
}
@Override
public RecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context conext = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View DataView = inflater.inflate(R.layout.data_layout, parent, false);
return new ViewHolder(dataView);
}
@Override
public void onBindViewHolder(@NonNull RecycleAdapter.ViewHolder viewHolder, int position) {
Data data = dataList.get(position);
// Do stuff with data
myButton.setText(data);
}
public void setOnItemClickListener(View.OnClickListener itemClickListener) {
onItemClickListener = itemClickListener;
}
}
答案 0 :(得分:2)
请使用以下代码获取确切位置, setTag();到视图,然后在单击时使用getTag()获得该标签值; 以获得完美的位置。
myViewHolder.ivVoiceThumb.setTag(pos);
myViewHolder.ivVoiceThumb.setOnClickListener(view -> {
int getPos = (int)view.getTag();
});
答案 1 :(得分:2)
您正在将viewHolder
传递给onClick侦听器
myButton.setTag(this); // this = viewHolder
viewHolder是可回收的视图。因此,您不能将此视图视为唯一的项目视图。 请记住,已经创建了一个viewHolder以供其他项目重用。这就是为什么您看到自己的行为反映在其他项目上的原因。
解决方案:
设置为标签,而不是viewHolder
,而是项目的位置。
然后,在Data
结构中,应添加变量以记住应显示或不显示哪些按钮。
class Data {
...
String text;
boolean btnVisible;
}
在View.OnClickListener
中,您应该设置这些变量值。
private View.OnClickListener onItemClickLIstener = new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = (int)view.getTag();
Data data = dataList.get(position);
data.btnVisible = false;
adapter.notifyDataSetChanged();
// TODO: eventually do some logic here with the data
}
}
然后,在onBindViewHolder
中,应根据Data
结构中的变量设置按钮文本和按钮可见性状态。
@Override
public void onBindViewHolder(@NonNull RecycleAdapter.ViewHolder viewHolder, int position) {
Data data = dataList.get(position);
// Do stuff with data
myButton.setText(data.text);
myButton.setVisibility(?data.btnVisible:VISIBLE:GONE);
}