【问题标题】:RadioGroup onCheckedChanged getting an index higher than ChildCountRadioGroup onCheckedChanged 的​​索引高于 ChildCount
【发布时间】:2015-01-28 10:58:49
【问题描述】:

我正在动态创建一个带有 RadioGroup 的 LinearLayout(扩展 LinearLayout 的自定义类)。我也在动态添加 RadioButtons。此 LinearLayout 类用​​于多个活动和片段。

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

例如,如果我创建了一个自定义 LinearLayout 并添加了四个项目,然后我创建了另一个带有其他 4 个项目的 LinearLayout(在其他 Activity 中),当我单击第一个项目(在第二个 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);

------解决方案---------------

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

【问题讨论】:

  • 你能不能调用 mConmutadorContainer.removeAllViews();在初始化和检查?
  • @EagleEye 这就是我已经在做的事情!
  • 不在 init() 中,在 initialice() 中
  • 你是对的 EagleEye,我在 init() 中试过了,但结果是一样的。

标签: android android-layout android-activity


【解决方案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

【讨论】:

    【解决方案2】:

    使用这个。

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

    【讨论】:

    • 我的问题是 pos 包含的值高于 mLayoutsDataContained.size();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 2012-04-08
    • 2016-08-14
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多