RadioGroup onCheckedChanged 获得高于 ChildCount 的索引
RadioGroup onCheckedChanged getting an index higher than ChildCount
我正在动态创建一个 LinearLayout(一个扩展 LinearLayout 的自定义 Class),其中包含一个 RadioGroup。我也在动态添加 RadioButtons。此 LinearLayout class 用于多个 Activity 和 Fragments。
奇怪的是,当我第二次添加 LinearLayout 时,当调用 OnCheckedChanged 时,获取的索引在我当前的 RadioGroup 中不存在。似乎每次我创建 LinearLayout 的新实例时,RadioGroup 都认为之前添加的 RadioButtons 仍然存在。
例如,如果我创建一个自定义 LinearLayout 并添加四个项目,然后我创建另一个带有其他 4 个项目的 LinearLayout(在其他 Activity 中),当我单击第一个项目(在second Activity), 我得到一个 5 作为点击的项目位置。
这是我自定义的 LinearLayout class:
public class AgrupacionConmutadorLayout extends LinearLayout{
private static final String TAG = "AgrupacionConmutadorLayout";
private int[] mColorFromLevel = {R.color.inspeccion_aparato_agrupacion_color_level_1, R.color.inspeccion_aparato_agrupacion_color_level_2,
R.color.inspeccion_aparato_agrupacion_color_level_3, R.color.inspeccion_aparato_agrupacion_color_level_4, R.color.inspeccion_aparato_agrupacion_color_level_5};
private Context mContext;
private LinearLayout dataContainer;
private TextView mTitle;
private RelativeLayout mSubAgrupacionesContainer;
private LinearLayout mDataAndSubAgrupacionesContainer;
private RadioGroup mConmutadorContainer;
private ArrayList<View> mLayoutsDataContained = new ArrayList<View>();
private int mLevel;
private LinearLayout mTitleContainer;
private InspeccionesFormWidgetReceiver mModificationReceiver;
private boolean isEdicion;
public AgrupacionConmutadorLayout(Context context) {
super(context);
this.mContext = context;
init(null, 0);
}
public AgrupacionConmutadorLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
init(attrs, 0);
}
public AgrupacionConmutadorLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mContext = context;
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
dataContainer = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.ins_agrupacion_conmutador_container, this);
mTitle = (TextView) dataContainer.findViewById(R.id.ins_agrupacion_container_title);
mSubAgrupacionesContainer = (RelativeLayout) findViewById(R.id.rl_ins_subagrupacion_container);
mConmutadorContainer = (RadioGroup) findViewById(R.id.ins_agrupacion_conmutador_radio_group);
mDataAndSubAgrupacionesContainer = (LinearLayout) findViewById(R.id.ll_ins_data_and_subagrupacion_container);
mTitleContainer = (LinearLayout) findViewById(R.id.ll_ins_agrupacion_container_title);
mConmutadorContainer.removeAllViews();
mConmutadorContainer.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int pos) {
Log.d(TAG, "onCheckedChanged Clicked pos: " + pos);
Log.d(TAG, "onCheckedChanged RadioGroup size: " + radioGroup.getChildCount());
Log.d(TAG, "onCheckedChanged " + mLayoutsDataContained.size());
//OnCheckedChanged comienza a devolver en 1, al ArrayList en 0
for (int i = 1; i < mLayoutsDataContained.size() + 1; i++) {
if (i == pos) {
mLayoutsDataContained.get(i - 1).setVisibility(View.VISIBLE);
} else {
mLayoutsDataContained.get(i - 1).setVisibility(View.GONE);
}
}
}
});
}
public void initialice(AgrupacionSios agrupacionSios, InspeccionesFormWidgetReceiver modificationReceiver, boolean isEdicion) {
this.mModificationReceiver = modificationReceiver;
this.isEdicion = isEdicion;
mTitle.setText(agrupacionSios.getTitle());
mTitle.setTextColor(mContext.getResources().getColor(mColorFromLevel[agrupacionSios.getLevel()]));
if (agrupacionSios.isOcultarContenedor()) mTitleContainer.setVisibility(View.GONE);
if (agrupacionSios.getNumOfSons() > 0) {
drawSubAgrupaciones(agrupacionSios);
}
this.refreshDrawableState();
}
private void drawSubAgrupaciones(AgrupacionSios agrupacionSios) {
ViewGroup.LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
ArrayList<AgrupacionSios> agrupaciones = agrupacionSios.getAgrupacionesHijos();
Iterator itAgr = agrupaciones.iterator();
while (itAgr.hasNext()) {
AgrupacionSios agrupacionHija = (AgrupacionSios) itAgr.next();
if (agrupacionHija.getNumOfLevels() > 0 || agrupacionHija.getNumOfSons() > 0) {
switch (agrupacionHija.getTipoSubAgrupaciones()) {
case CONMUTADOR:
AgrupacionConmutadorLayout v = new AgrupacionConmutadorLayout(mContext);
v.initialice(agrupacionHija, mModificationReceiver, isEdicion);
mSubAgrupacionesContainer.addView(v, layoutParams);
mLayoutsDataContained.add(v);
break;
case COLUMNAS:
AgrupacionColumnasLayout vCol = new AgrupacionColumnasLayout(mContext);
vCol.initialice(agrupacionHija, mModificationReceiver, isEdicion);
mSubAgrupacionesContainer.addView(vCol, layoutParams);
mLayoutsDataContained.add(vCol);
break;
default:
AgrupacionGenericaLayout vGen = new AgrupacionGenericaLayout(mContext);
vGen.isSonOfConmutador(true);
vGen.initialice(agrupacionHija, mModificationReceiver, isEdicion);
mSubAgrupacionesContainer.addView(vGen, layoutParams);
mLayoutsDataContained.add(vGen);
break;
}
}
//Añadimos el botón de conmutación correspondiente a la subagrupación.
addAgrupacionToConmutadorContainer(agrupacionHija);
}
mConmutadorContainer.check(1);
}
public void setBackgroundColor(int color) {
setBackgroundResource(color);
}
private void addAgrupacionToConmutadorContainer(AgrupacionSios mAgrupacion) {
ViewGroup.LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
RadioButton b = new RadioButton(mContext);
b.setLayoutParams(layoutParams);
b.setText(mAgrupacion.getTitle());
b.setButtonDrawable(android.R.color.transparent);
b.setBackground(mContext.getResources().getDrawable(R.drawable.ins_conmutador_radio_background));
b.setPadding(20,5,20,5);
RadioGroup.LayoutParams params
= new RadioGroup.LayoutParams(mContext, null);
params.setMargins(10, 0, 10, 0);
b.setLayoutParams(params);
mConmutadorContainer.addView(b);
}
}
这就是我在活动和片段上创建 AgrupacionConmutadorLayout 的方式:
AgrupacionConmutadorLayout vConm = new AgrupacionConmutadorLayout(this);
vConm.initialice(agrupacion, this, isEdicion);
vConm.setVisibility(View.VISIBLE);
mAgrupacionesContainer.addView(vConm, layoutParams);
----------------解决方案------------------------
Marius 的回答是关键,我点击的是 RadioButton id,而不是他在 RadioGroup 中的位置。
终于用标签搞定了。我将其顺序设置为每个 RadioButton 作为标签:
private void addAgrupacionToConmutadorContainer(AgrupacionSios mAgrupacion) {
ViewGroup.LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
RadioButton b = new RadioButton(mContext);
b.setLayoutParams(layoutParams);
b.setText(mAgrupacion.getTitle());
b.setButtonDrawable(android.R.color.transparent);
b.setBackground(mContext.getResources().getDrawable(R.drawable.ins_conmutador_radio_background));
b.setPadding(20, 5, 20, 5);
RadioGroup.LayoutParams params
= new RadioGroup.LayoutParams(mContext, null);
params.setMargins(10, 0, 10, 0);
b.setLayoutParams(params);
b.setTag(mConmutadorContainer.getChildCount());
mConmutadorContainer.addView(b);
}
然后我在 OnCheckedChangeListener 中得到了那个标签:
mConmutadorContainer.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int clickedId) {
View radioButtonClicked = radioGroup.findViewById(clickedId);
if (radioButtonClicked != null) {
Integer pos = (Integer) radioButtonClicked.getTag();
Log.d(TAG, "onCheckedChanged RadioGroup clicked position: " + pos);
for (int i = 0; i < mLayoutsDataContained.size(); i++) {
View view = mLayoutsDataContained.get(i);
if (pos.intValue() == i) {
view.setVisibility(View.VISIBLE);
} else view.setVisibility(View.GONE);
}
}
}
});
使用这个。
for (int i = 0; i < mLayoutsDataContained.size(); i++) {
if (i == pos) {
mLayoutsDataContained.get(i - 1).setVisibility(View.VISIBLE);
} else {
mLayoutsDataContained.get(i - 1).setVisibility(View.GONE);
}
}
你肯定看错了API。第二个参数不是位置。这是按钮的ID。您的问题有多种解决方案。
添加 id,基于位置:
//not recommended way, as activity.findViewById uses this id, I GUESS something wrong may happen
private int currId;
...
b.setId(currId);
currId++;
container.addView(b);
添加标签:
//recommended
b.setTag(mAgrupacion);
container.addView(b);
//then...
AgrupacionSios tag = (AgrupacionSios) b.getTag();
//do action based on tag information
我正在动态创建一个 LinearLayout(一个扩展 LinearLayout 的自定义 Class),其中包含一个 RadioGroup。我也在动态添加 RadioButtons。此 LinearLayout class 用于多个 Activity 和 Fragments。
奇怪的是,当我第二次添加 LinearLayout 时,当调用 OnCheckedChanged 时,获取的索引在我当前的 RadioGroup 中不存在。似乎每次我创建 LinearLayout 的新实例时,RadioGroup 都认为之前添加的 RadioButtons 仍然存在。
例如,如果我创建一个自定义 LinearLayout 并添加四个项目,然后我创建另一个带有其他 4 个项目的 LinearLayout(在其他 Activity 中),当我单击第一个项目(在second Activity), 我得到一个 5 作为点击的项目位置。
这是我自定义的 LinearLayout class:
public class AgrupacionConmutadorLayout extends LinearLayout{
private static final String TAG = "AgrupacionConmutadorLayout";
private int[] mColorFromLevel = {R.color.inspeccion_aparato_agrupacion_color_level_1, R.color.inspeccion_aparato_agrupacion_color_level_2,
R.color.inspeccion_aparato_agrupacion_color_level_3, R.color.inspeccion_aparato_agrupacion_color_level_4, R.color.inspeccion_aparato_agrupacion_color_level_5};
private Context mContext;
private LinearLayout dataContainer;
private TextView mTitle;
private RelativeLayout mSubAgrupacionesContainer;
private LinearLayout mDataAndSubAgrupacionesContainer;
private RadioGroup mConmutadorContainer;
private ArrayList<View> mLayoutsDataContained = new ArrayList<View>();
private int mLevel;
private LinearLayout mTitleContainer;
private InspeccionesFormWidgetReceiver mModificationReceiver;
private boolean isEdicion;
public AgrupacionConmutadorLayout(Context context) {
super(context);
this.mContext = context;
init(null, 0);
}
public AgrupacionConmutadorLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
init(attrs, 0);
}
public AgrupacionConmutadorLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mContext = context;
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
dataContainer = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.ins_agrupacion_conmutador_container, this);
mTitle = (TextView) dataContainer.findViewById(R.id.ins_agrupacion_container_title);
mSubAgrupacionesContainer = (RelativeLayout) findViewById(R.id.rl_ins_subagrupacion_container);
mConmutadorContainer = (RadioGroup) findViewById(R.id.ins_agrupacion_conmutador_radio_group);
mDataAndSubAgrupacionesContainer = (LinearLayout) findViewById(R.id.ll_ins_data_and_subagrupacion_container);
mTitleContainer = (LinearLayout) findViewById(R.id.ll_ins_agrupacion_container_title);
mConmutadorContainer.removeAllViews();
mConmutadorContainer.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int pos) {
Log.d(TAG, "onCheckedChanged Clicked pos: " + pos);
Log.d(TAG, "onCheckedChanged RadioGroup size: " + radioGroup.getChildCount());
Log.d(TAG, "onCheckedChanged " + mLayoutsDataContained.size());
//OnCheckedChanged comienza a devolver en 1, al ArrayList en 0
for (int i = 1; i < mLayoutsDataContained.size() + 1; i++) {
if (i == pos) {
mLayoutsDataContained.get(i - 1).setVisibility(View.VISIBLE);
} else {
mLayoutsDataContained.get(i - 1).setVisibility(View.GONE);
}
}
}
});
}
public void initialice(AgrupacionSios agrupacionSios, InspeccionesFormWidgetReceiver modificationReceiver, boolean isEdicion) {
this.mModificationReceiver = modificationReceiver;
this.isEdicion = isEdicion;
mTitle.setText(agrupacionSios.getTitle());
mTitle.setTextColor(mContext.getResources().getColor(mColorFromLevel[agrupacionSios.getLevel()]));
if (agrupacionSios.isOcultarContenedor()) mTitleContainer.setVisibility(View.GONE);
if (agrupacionSios.getNumOfSons() > 0) {
drawSubAgrupaciones(agrupacionSios);
}
this.refreshDrawableState();
}
private void drawSubAgrupaciones(AgrupacionSios agrupacionSios) {
ViewGroup.LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
ArrayList<AgrupacionSios> agrupaciones = agrupacionSios.getAgrupacionesHijos();
Iterator itAgr = agrupaciones.iterator();
while (itAgr.hasNext()) {
AgrupacionSios agrupacionHija = (AgrupacionSios) itAgr.next();
if (agrupacionHija.getNumOfLevels() > 0 || agrupacionHija.getNumOfSons() > 0) {
switch (agrupacionHija.getTipoSubAgrupaciones()) {
case CONMUTADOR:
AgrupacionConmutadorLayout v = new AgrupacionConmutadorLayout(mContext);
v.initialice(agrupacionHija, mModificationReceiver, isEdicion);
mSubAgrupacionesContainer.addView(v, layoutParams);
mLayoutsDataContained.add(v);
break;
case COLUMNAS:
AgrupacionColumnasLayout vCol = new AgrupacionColumnasLayout(mContext);
vCol.initialice(agrupacionHija, mModificationReceiver, isEdicion);
mSubAgrupacionesContainer.addView(vCol, layoutParams);
mLayoutsDataContained.add(vCol);
break;
default:
AgrupacionGenericaLayout vGen = new AgrupacionGenericaLayout(mContext);
vGen.isSonOfConmutador(true);
vGen.initialice(agrupacionHija, mModificationReceiver, isEdicion);
mSubAgrupacionesContainer.addView(vGen, layoutParams);
mLayoutsDataContained.add(vGen);
break;
}
}
//Añadimos el botón de conmutación correspondiente a la subagrupación.
addAgrupacionToConmutadorContainer(agrupacionHija);
}
mConmutadorContainer.check(1);
}
public void setBackgroundColor(int color) {
setBackgroundResource(color);
}
private void addAgrupacionToConmutadorContainer(AgrupacionSios mAgrupacion) {
ViewGroup.LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
RadioButton b = new RadioButton(mContext);
b.setLayoutParams(layoutParams);
b.setText(mAgrupacion.getTitle());
b.setButtonDrawable(android.R.color.transparent);
b.setBackground(mContext.getResources().getDrawable(R.drawable.ins_conmutador_radio_background));
b.setPadding(20,5,20,5);
RadioGroup.LayoutParams params
= new RadioGroup.LayoutParams(mContext, null);
params.setMargins(10, 0, 10, 0);
b.setLayoutParams(params);
mConmutadorContainer.addView(b);
}
}
这就是我在活动和片段上创建 AgrupacionConmutadorLayout 的方式:
AgrupacionConmutadorLayout vConm = new AgrupacionConmutadorLayout(this);
vConm.initialice(agrupacion, this, isEdicion);
vConm.setVisibility(View.VISIBLE);
mAgrupacionesContainer.addView(vConm, layoutParams);
----------------解决方案------------------------
Marius 的回答是关键,我点击的是 RadioButton id,而不是他在 RadioGroup 中的位置。
终于用标签搞定了。我将其顺序设置为每个 RadioButton 作为标签:
private void addAgrupacionToConmutadorContainer(AgrupacionSios mAgrupacion) {
ViewGroup.LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
RadioButton b = new RadioButton(mContext);
b.setLayoutParams(layoutParams);
b.setText(mAgrupacion.getTitle());
b.setButtonDrawable(android.R.color.transparent);
b.setBackground(mContext.getResources().getDrawable(R.drawable.ins_conmutador_radio_background));
b.setPadding(20, 5, 20, 5);
RadioGroup.LayoutParams params
= new RadioGroup.LayoutParams(mContext, null);
params.setMargins(10, 0, 10, 0);
b.setLayoutParams(params);
b.setTag(mConmutadorContainer.getChildCount());
mConmutadorContainer.addView(b);
}
然后我在 OnCheckedChangeListener 中得到了那个标签:
mConmutadorContainer.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int clickedId) {
View radioButtonClicked = radioGroup.findViewById(clickedId);
if (radioButtonClicked != null) {
Integer pos = (Integer) radioButtonClicked.getTag();
Log.d(TAG, "onCheckedChanged RadioGroup clicked position: " + pos);
for (int i = 0; i < mLayoutsDataContained.size(); i++) {
View view = mLayoutsDataContained.get(i);
if (pos.intValue() == i) {
view.setVisibility(View.VISIBLE);
} else view.setVisibility(View.GONE);
}
}
}
});
使用这个。
for (int i = 0; i < mLayoutsDataContained.size(); i++) {
if (i == pos) {
mLayoutsDataContained.get(i - 1).setVisibility(View.VISIBLE);
} else {
mLayoutsDataContained.get(i - 1).setVisibility(View.GONE);
}
}
你肯定看错了API。第二个参数不是位置。这是按钮的ID。您的问题有多种解决方案。
添加 id,基于位置:
//not recommended way, as activity.findViewById uses this id, I GUESS something wrong may happen
private int currId;
...
b.setId(currId);
currId++;
container.addView(b);
添加标签:
//recommended
b.setTag(mAgrupacion);
container.addView(b);
//then...
AgrupacionSios tag = (AgrupacionSios) b.getTag();
//do action based on tag information