自定义 ListView 中具有三个 RadioButtons 的自定义行

Posted

技术标签:

【中文标题】自定义 ListView 中具有三个 RadioButtons 的自定义行【英文标题】:Custom row with Three RadioButtons in a custom ListView 【发布时间】:2014-10-01 06:27:32 【问题描述】:

我有一个自定义行,其中包含 3 个单选按钮。

如果我检查了一些单选按钮,然后滚动我的列表视图会丢失单选按钮的引用,并且当我回来时,单选按钮不会被选中。 要么 当我滚动最后一个单选按钮时被选中(但我没有点击这一行的单选按钮)

这里是代码

适配器


public View getView(int position, View row, ViewGroup parent) 

        Holder holder;
        if (row == null) 
            holder = new Holder();
            row = LayoutInflater.from(activity).inflate(R.layout.linha_ficha,parent,false);
            holder.tv_linhaFicha_NumItem = (TextView) row.findViewById(R.id.tv_linhaFicha_NumItem);
            holder.tv_linhaFicha_Pergunta = (TextView) row.findViewById(R.id.tv_linhaFicha_Pergunta);
            holder.tv_linhaFicha_Tolerancia = (TextView) row.findViewById(R.id.tv_linhaFicha_Tolerancia);
            holder.tv_linhaFicha_DataAprovado = (TextView) row.findViewById(R.id.tv_linhaFicha_DataAprovado);
            holder.tv_linhaFicha_DataReprovado = (TextView) row.findViewById(R.id.tv_linhaFicha_DataReprovado);
            holder.tv_linhaFicha_Responsavel = (TextView) row.findViewById(R.id.tv_linhaFicha_Responsavel);
            holder.rb_linhaFicha_O = (RadioButton) row.findViewById(R.id.rb_linhaFicha_O);
            holder.rb_linhaFicha_O.setOnClickListener(this);
            holder.rb_linhaFicha_O.setOnCheckedChangeListener(this);
            holder.rb_linhaFicha_X = (RadioButton) row.findViewById(R.id.rb_linhaFicha_X);
            holder.rb_linhaFicha_X.setOnCheckedChangeListener(this);
            holder.rb_linhaFicha_Reinspecao = (RadioButton) row.findViewById(R.id.rb_linhaFicha_Reinspecao);
            holder.rb_linhaFicha_Reinspecao.setOnClickListener(this);
            holder.rb_linhaFicha_Reinspecao.setOnCheckedChangeListener(this);
            row.setTag(holder);
         else 
            holder = (Holder) row.getTag();
        

        itensCondicoes = (Fvs_ItemCondicao) getItem(position);

        holder.tv_linhaFicha_NumItem.setText(itensCondicoes.getNumItem());
        holder.tv_linhaFicha_Pergunta.setText(itensCondicoes.getNome());
        holder.tv_linhaFicha_Tolerancia.setText(itensCondicoes.getTolerancia());
        holder.tv_linhaFicha_DataAprovado.setText(itensCondicoes.getDataAprovado());
        holder.tv_linhaFicha_DataReprovado.setText(itensCondicoes.getDataReprovado());
        holder.tv_linhaFicha_Responsavel.setText(itensCondicoes.getNomeUsuario());

        if (itensCondicoes.getResposta().length() > 0) 
            if (itensCondicoes.getResposta().equals("o")) 
                holder.rb_linhaFicha_X.setButtonDrawable(R.drawable.bt_x);
                holder.rb_linhaFicha_O.setButtonDrawable(R.drawable.bt_o_atv);
                holder.rb_linhaFicha_Reinspecao.setButtonDrawable(R.drawable.bt_reinspecao_inativo);
                setEnabledCheck(holder,false,true,false);
            

            if (itensCondicoes.getResposta().equals("x")) 
                holder.rb_linhaFicha_X.setButtonDrawable(R.drawable.bt_x_atv);
                holder.rb_linhaFicha_O.setButtonDrawable(R.drawable.bt_o);
                holder.rb_linhaFicha_Reinspecao.setButtonDrawable(R.drawable.bt_reinspecao_inativo);
                setEnabledCheck(holder,false,false,false);
            

            if (itensCondicoes.getResposta().equals("ox")) 
                holder.rb_linhaFicha_X.setButtonDrawable(R.drawable.bt_x);
                holder.rb_linhaFicha_O.setButtonDrawable(R.drawable.bt_o);
                holder.rb_linhaFicha_Reinspecao.setButtonDrawable(R.drawable.bt_reinspecao_ativo);
                setEnabledCheck(holder,false,false,true);
            
         else 
            setEnabledCheck(holder, true, true, false);
        

        holder.itensCondicoes = itensCondicoes;

        return row;
    

OnCheckedChanged


public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
        Holder tempHolder = ((Holder)((View)buttonView.getParent().getParent()).getTag());

        if (tempHolder != null) 
            if (buttonView.getId() == R.id.rb_linhaFicha_X) 
                if (tempHolder.getItensCondicoes().getStatus() == 1) 
                    if (isChecked) 
                        tempHolder.rb_linhaFicha_X.setButtonDrawable(R.drawable.bt_x_atv);
                        setConformidadeRegras(tempHolder);
                     else 
                        tempHolder.rb_linhaFicha_X.setButtonDrawable(R.drawable.bt_x);
                    
                
            

            if (buttonView.getId() == R.id.rb_linhaFicha_O) 
                if (tempHolder.getItensCondicoes().getStatus() == 1) 
                    if (isChecked) 
                        tempHolder.rb_linhaFicha_O.setButtonDrawable(R.drawable.bt_o_atv);
                        setNaoConformidadeRegras(tempHolder);
                     else 
                        tempHolder.rb_linhaFicha_O.setButtonDrawable(R.drawable.bt_o);
                    
                
            
        
    

这是自定义行

【问题讨论】:

【参考方案1】:

那是因为适配器正在重用视图。您可以禁用该功能(强烈不推荐),也可以保存列表中每个项目的复选框状态。

首先,我建议您创建一个自定义类来保存单个项目的 3 种状态:

public class CheckboxStates 
    boolean check1, check2, check3;

    CheckboxStates(boolean b1, boolean b2, boolean b3) 
        check1 = b1;
        check2 = b2;
        check3 = b3;
    


List<CheckboxStates> checkboxStates = new ArrayList<CheckboxStates>();

现在,一旦您计算了 ListView 项的数量(可能在适配器构造函数中),您就可以将状态初始化为 [false, false, false](如果这是默认值)。

for (int i=0; i<itemCount; i++) 
    checkboxStates.add(new CheckboxStates(false, false, false));

您终于可以读取/设置getView() 中的值了:

// Get states for this list item
CheckboxStates states = checkboxStates.get(position);

// Get/set the values
states.check1 = false;
states.check2 = true;
states.check3 = false;

【讨论】:

【参考方案2】:

您需要存储复选框的状态,因为视图将被重用,并且您不能依赖单选框存储的隐式状态。

将此添加到由 getItem 返回的类中,并在单击单选按钮时将状态存储到该类。

【讨论】:

以上是关于自定义 ListView 中具有三个 RadioButtons 的自定义行的主要内容,如果未能解决你的问题,请参考以下文章

所有图像都具有相同大小的自定义 ListView

Kotlin 实现三级菜单列表(左右滑动)+自定义ViewPager+三个ListView列表的功能

具有自定义适配器的 ListView 中的 SearchView

将自定义 ListView 项传递给 Android 中的其他活动

如何在自定义 ListView 适配器中处理 RadioGroup 的 onCheckedChangeListener

将自定义ListView项目传递给Android中的其他活动