RadioGroup onCheckedChanged获得的索引高于ChildCount

时间:2015-01-28 10:58:49

标签: android android-layout android-activity

我在其中创建了一个LinearLayout(一个扩展LinearLayout的自定义类),其中包含一个RadioGroup。我也正在添加RadioButtons。此LinearLayout类用于多个活动和片段。

奇怪的行为是我第二次添加LinearLayout,当调用OnCheckedChanged时,得到一个在我当前的RadioGroup中不存在的索引。我似乎每次创建一个新的LinearLayout实例时,RadioGroup都认为以前添加的RadioButtons仍然存在。

例如,如果我创建一个自定义LinearLayout并添加四个项目,之后我创建另一个LinearLayout(在其他Activity中)与其他4个项目,当我点击第一个项目(在第二个Activity上)时,我得到点击项目位置为5。

这是我的自定义LinearLayout类:

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);

----------------- SOLUTION ---------------------------

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);
                }
            }
        }
    });

2 个答案:

答案 0 :(得分:1)

您必须误读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

答案 1 :(得分:0)

使用此功能。

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);
                        }
                    }