单击一个后禁用回收器视图中的所有其他切换按钮
Disable all other toggle buttons in recycler view after one is clicked
我正在使用 recyclerView 构建一个切换按钮列表(如小键盘),我想实现:
- 当用户 'turns on' 单击一个按钮时,'turns off' 所有其他按钮
我尝试在视图持有者 class 中添加一个 onClickListener
,然后调用 notifyDataSetChanged()
以便调用 onBindViewHolder(final ViewHolder holder, int position)
,然后更改按钮的状态.
但是它不起作用,点击的按钮并没有改变它的状态。
ViewHolder
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ToggleButton button;
String id;
public ViewHolder(View itemView) {
super(itemView);
button = (ToggleButton) itemView.findViewById(R.id.toggle);
button.setOnclickListener(this);
}
@Override
public void onClick(View view) {
((ToggleButton) view).setChecked(true);
int pos = getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
selected = pos; //store the position of the user clicked button
notifyDataSetChanged();
}
}
我的适配器中的 onBindViewHolder() class
public void onBindViewHolder(final ViewHolder holder, int position) {
String data = mData.get(position);
holder.id = data;
holder.button.setText(data);
holder.button.setTextOn(data);
holder.button.setTextOff(data);
if (position != selected) { //if the button is not the user chosen one
if (holder.button.isChecked()) { // and it's in 'ON' state
holder.button.toggle(); // toggle it to switch 'OFF'
}
}
尝试设置 OnCheckedChangeListener
而不是“OnclickListener”
`button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// The toggle is enabled
} else {
// The toggle is disabled
}
}
});`
Android 文档:https://developer.android.com/guide/topics/ui/controls/togglebutton.html
在 onBindView 和 onClick 方法中设置点击监听器,
首先"turn off"所有切换按钮通过在列表模型中设置一个参数
然后 "turn on" 如果未选中,则选中。
@Override
public void onClick(View view) {
// clear all model values to isSelected false in the list
}
有几件事你做错了。 ViewHolder
应该只包含视图而不是点击处理程序或字符串等(线索在名称中)。当您将 ViewHolder 绑定到您的数据时,您可以添加处理程序并操作视图 class.
据我所知,您需要一个简单的切换按钮列表。当一个按钮打开时,其他按钮应该关闭。我在下面为您创建的测试适配器证明了这一点。
理想情况下,您会避免 notifyDataSetChanged
并使用基于行的版本,但是每次按下切换时,它都会影响其他每一行,在这种情况下您实际上没有选择,除非您保留所选行的轨道。
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.VH> {
public static class MyData {
public boolean Selected = false;
public String Text;
public MyData(String text) {
Text = text;
}
}
public List<MyData> items = new ArrayList<>();
public TestAdapter() {
this.items.add(new MyData("Item 1"));
this.items.add(new MyData("Item 2"));
this.items.add(new MyData("Item 3"));
}
@Override
public TestAdapter.VH onCreateViewHolder(ViewGroup parent, int viewType) {
return new VH((
LayoutInflater.from(parent.getContext())
.inflate(R.layout.test_layout, parent, false))
);
}
@Override
public void onBindViewHolder(TestAdapter.VH holder, int position) {
final MyData itm = items.get(position);
holder.button.setChecked(itm.Selected);
holder.text.setText(itm.Text);
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for (MyData x: items){
x.Selected=false;
}
itm.Selected = true;
notifyDataSetChanged();
}
});
}
@Override
public int getItemCount() {
return items.size();
}
public class VH extends RecyclerView.ViewHolder {
ToggleButton button;
TextView text;
public VH(View itemView) {
super(itemView);
button = itemView.findViewById(R.id.toggle);
text = itemView.findViewById(R.id.text1);
}
}
}
test_layout.xml
<?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="wrap_content"
android:orientation="horizontal">
<ToggleButton
android:id="@+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
我正在使用 recyclerView 构建一个切换按钮列表(如小键盘),我想实现:
- 当用户 'turns on' 单击一个按钮时,'turns off' 所有其他按钮
我尝试在视图持有者 class 中添加一个 onClickListener
,然后调用 notifyDataSetChanged()
以便调用 onBindViewHolder(final ViewHolder holder, int position)
,然后更改按钮的状态.
但是它不起作用,点击的按钮并没有改变它的状态。
ViewHolder
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ToggleButton button;
String id;
public ViewHolder(View itemView) {
super(itemView);
button = (ToggleButton) itemView.findViewById(R.id.toggle);
button.setOnclickListener(this);
}
@Override
public void onClick(View view) {
((ToggleButton) view).setChecked(true);
int pos = getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
selected = pos; //store the position of the user clicked button
notifyDataSetChanged();
}
}
我的适配器中的 onBindViewHolder() class
public void onBindViewHolder(final ViewHolder holder, int position) {
String data = mData.get(position);
holder.id = data;
holder.button.setText(data);
holder.button.setTextOn(data);
holder.button.setTextOff(data);
if (position != selected) { //if the button is not the user chosen one
if (holder.button.isChecked()) { // and it's in 'ON' state
holder.button.toggle(); // toggle it to switch 'OFF'
}
}
尝试设置 OnCheckedChangeListener
而不是“OnclickListener”
`button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// The toggle is enabled
} else {
// The toggle is disabled
}
}
});`
Android 文档:https://developer.android.com/guide/topics/ui/controls/togglebutton.html
在 onBindView 和 onClick 方法中设置点击监听器, 首先"turn off"所有切换按钮通过在列表模型中设置一个参数 然后 "turn on" 如果未选中,则选中。
@Override
public void onClick(View view) {
// clear all model values to isSelected false in the list
}
有几件事你做错了。 ViewHolder
应该只包含视图而不是点击处理程序或字符串等(线索在名称中)。当您将 ViewHolder 绑定到您的数据时,您可以添加处理程序并操作视图 class.
据我所知,您需要一个简单的切换按钮列表。当一个按钮打开时,其他按钮应该关闭。我在下面为您创建的测试适配器证明了这一点。
理想情况下,您会避免 notifyDataSetChanged
并使用基于行的版本,但是每次按下切换时,它都会影响其他每一行,在这种情况下您实际上没有选择,除非您保留所选行的轨道。
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.VH> {
public static class MyData {
public boolean Selected = false;
public String Text;
public MyData(String text) {
Text = text;
}
}
public List<MyData> items = new ArrayList<>();
public TestAdapter() {
this.items.add(new MyData("Item 1"));
this.items.add(new MyData("Item 2"));
this.items.add(new MyData("Item 3"));
}
@Override
public TestAdapter.VH onCreateViewHolder(ViewGroup parent, int viewType) {
return new VH((
LayoutInflater.from(parent.getContext())
.inflate(R.layout.test_layout, parent, false))
);
}
@Override
public void onBindViewHolder(TestAdapter.VH holder, int position) {
final MyData itm = items.get(position);
holder.button.setChecked(itm.Selected);
holder.text.setText(itm.Text);
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for (MyData x: items){
x.Selected=false;
}
itm.Selected = true;
notifyDataSetChanged();
}
});
}
@Override
public int getItemCount() {
return items.size();
}
public class VH extends RecyclerView.ViewHolder {
ToggleButton button;
TextView text;
public VH(View itemView) {
super(itemView);
button = itemView.findViewById(R.id.toggle);
text = itemView.findViewById(R.id.text1);
}
}
}
test_layout.xml
<?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="wrap_content"
android:orientation="horizontal">
<ToggleButton
android:id="@+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>