最近在做项目的时候,设计小哥给到了如下需求:
image.png
看上去简单,xml写起来:
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="xxx" />
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="xxx" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="xxx" />
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="xxx" />
</LinearLayout>
</RadioGroup>
然而悲伤的事情来了,RadioGroup失去了它的单选功能,有且只有同一行的RadioButton可以单选。这是怎么回事呢?看看RadioGroup源码:
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if (child instanceof RadioButton) {
final RadioButton button = (RadioButton) child;
if (button.isChecked()) {
mProtectFromCheckedChange = true;
if (mCheckedId != -1) {
setCheckedStateForView(mCheckedId, false);
}
mProtectFromCheckedChange = false;
setCheckedId(button.getId());
}
}
super.addView(child, index, params);
}
这里仅仅判断了RadioButton!这限制就大了。
当然解决方案也有多种:
1.重写RadioGroup,在子View的操作上做文章。
2.布局不变,动态的判断点击的RadioButton来清除其它的RadioGroup。
3.使用RecyclerView来刷新整个列表
我使用到的方法就是第三种,原因在于RecyclerView通过GridLayoutManager可以动态的变换整个列表的列数(非常实用),而且不用去写RadioGroup里面的布局结构,只需要根据传入的List即可轻松实现。
话不多说,快看看代码吧
布局:
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/radio_rv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RadioGroup>
是不是很简单啊
RecyclerView rv = UiUtils.find(view, R.id.radio_rv);
RadioRecycleAdapter radioAdapter = new RadioRecycleAdapter(mApplication, valueList);
radioAdapter.setOnItemClickListener((holder, pos) -> {
//TODO
});
rv.setLayoutManager(new GridLayoutManager(mApplication, 2));
rv.setAdapter(radioAdapter);
rv.addItemDecoration(new SpaceItemDecoration(49));
public class RadioRecycleAdapter extends RecyclerView.Adapter<RadioRecycleAdapter.MyViewHolder> {
private Context mContext;
private List<String> mDatas;
private int mSelectedItem = -1;
public interface OnItemClickListener {
void onItemClick(String holder, int pos);
}
private OnItemClickListener mListener;
public void setOnItemClickListener(OnItemClickListener listener) {
this.mListener = listener;
}
public RadioRecycleAdapter(Context mContext, List<String> datas) {
this.mContext = mContext;
this.mDatas = datas;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_radio, parent, false));
return holder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.radioButton.setText(mDatas.get(position));
holder.radioButton.setChecked(position == mSelectedItem);
holder.radioButton.setTag(position);
holder.radioButton.setOnClickListener(v -> {
mSelectedItem = (int) v.getTag();
notifyItemRangeChanged(0, mDatas.size());
if (mListener != null) {
mListener.onItemClick(mDatas.get(holder.getLayoutPosition()), holder.getLayoutPosition());
}
});
}
@Override
public int getItemCount() {
return mDatas.size();
}
public void addData(String data, int pos) {
mDatas.add(pos, data);
notifyItemInserted(pos);
}
public void removeData(int pos) {
mDatas.remove(pos);
notifyDataSetChanged();
notifyItemRemoved(pos);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
RadioButton radioButton;
public MyViewHolder(View itemView) {
super(itemView);
radioButton = (RadioButton) itemView.findViewById(R.id.radio_rb);
}
}
}
效果可以看最上面的图片。Over
网友评论