带有切换按钮的Android ListView

时间:2016-01-04 19:00:56

标签: android listview android-togglebutton

当我的ListView有更多可以出现在屏幕上的itens时,我遇到了问题;换句话说,当它滚动时。问题是,当我点击其中一个切换按钮时,它会改变ImageView的可见性。但是,当我点击它时,它会更改超过相应点击的可见性。

我正在使用适配器来显示列表。

我添加了以下代码:

public class CriteriosAdapter extends ArrayAdapter<Criterio> {

private Context context;

public CriteriosAdapter(Context context, List<Criterio> objects) {
    super(context, 0, objects);
    this.context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final Criterio criterio = getItem(position);
    final CriterioViewHolder viewHolder;

    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_row, parent, false);

        viewHolder = new CriterioViewHolder();
        viewHolder.txtCriterio = (TextView)convertView.findViewById(R.id.txtCriterio);
        viewHolder.tgIrregular = (ToggleButton)convertView.findViewById(R.id.tgIrregular);
        viewHolder.btnCam = (ImageView) convertView.findViewById(R.id.btnCam);

        convertView.setTag(viewHolder);
    }
    else {
        viewHolder = (CriterioViewHolder)convertView.getTag();
    }

    viewHolder.txtCriterio.setText(criterio.nome);
    viewHolder.txtCriterio.setTextColor(context.getColor(R.color.white));
    viewHolder.tgIrregular.setChecked(false);

    viewHolder.tgIrregular.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (viewHolder.tgIrregular.isChecked()) {
                viewHolder.btnCam.setVisibility(View.VISIBLE);
            } else {
                viewHolder.btnCam.setVisibility(View.INVISIBLE);
            }
        }
    });

    viewHolder.btnCam.setOnClickListener(new View.OnClickListener() {
        public void onClick(View arg0) {
            FragmentActivity activity = (FragmentActivity)(context);
            android.support.v4.app.FragmentManager fm = activity.getSupportFragmentManager();
            FotosFragment alertDialog = new FotosFragment();
            alertDialog.show(fm, "fragment_alert");
        }
    });

    return convertView;
}

class CriterioViewHolder {

    TextView txtCriterio;
    ToggleButton tgIrregular;

    ImageView btnCam;

}

}

有人可以帮我吗?

谢谢。

修改

我按照你的描述添加了所有内容。但是,我在5个片段中使用该适配器,如果我转到另一个片段,然后返回或滚动列表,它仍然会丢失该值。

我使用了criterio.getHash,因为它对所有人都是独一无二的。并且位置,可以在其他片段中重复,并使其变得奇怪。

public class CriteriosAdapter extends ArrayAdapter<Criterio> {

private Context context;
public static Map<String, Criterio> irregularidades = new HashMap<String, Criterio>();
HashMap<String, Boolean> toggleButtonStateTracker = new HashMap<>();

public CriteriosAdapter(Context context, List<Criterio> objects) {
    super(context, 0, objects);
    this.context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final Criterio criterio = getItem(position);
    final CriterioViewHolder viewHolder;

    if (!toggleButtonStateTracker.containsKey(criterio.getHash())){
        toggleButtonStateTracker.put(criterio.getHash(),false);
    }

    Log.e("Toggle Track:", toggleButtonStateTracker.toString());

    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_row, parent, false);

        viewHolder = new CriterioViewHolder();
        viewHolder.txtCriterio = (TextView)convertView.findViewById(R.id.txtCriterio);
        viewHolder.tgIrregular = (ToggleButton)convertView.findViewById(R.id.tgIrregular);
        viewHolder.btnCam = (ImageView) convertView.findViewById(R.id.btnCam);

        convertView.setTag(viewHolder);
    }
    else {
        viewHolder = (CriterioViewHolder)convertView.getTag();
    }

    viewHolder.txtCriterio.setText(criterio.nome);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        viewHolder.txtCriterio.setTextColor(context.getColor(R.color.white));
    } else {
        viewHolder.txtCriterio.setTextColor(context.getResources().getColor(R.color.white));
    }

    viewHolder.tgIrregular.setId(criterio.id);

    final boolean isChecked = toggleButtonStateTracker.get(criterio.getHash());
    viewHolder.tgIrregular.setChecked(isChecked);

    viewHolder.btnCam.setTag(criterio.hash);

    if (isChecked) {
        viewHolder.btnCam.setVisibility(View.VISIBLE);
    } else {
        viewHolder.btnCam.setVisibility(View.INVISIBLE);
    }

    viewHolder.tgIrregular.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            toggleButtonStateTracker.put(criterio.getHash(), isChecked);
            if (isChecked) {
                viewHolder.btnCam.setVisibility(View.VISIBLE);
                irregularidades.put(criterio.getHash(), criterio);
            } else {
                viewHolder.btnCam.setVisibility(View.INVISIBLE);
                irregularidades.remove(criterio.getHash());
            }
        }
    });

    viewHolder.btnCam.setOnClickListener(new View.OnClickListener() {
        public void onClick(View arg0) {
            FragmentActivity activity = (FragmentActivity) (context);
            android.support.v4.app.FragmentManager fm = activity.getSupportFragmentManager();
            FotosFragment alertDialog = new FotosFragment();

            Bundle args = new Bundle();
            args.putString("criterioTag", criterio.getHash());
            alertDialog.setArguments(args);

            alertDialog.setCancelable(false);
            alertDialog.show(fm, "fragment_alert");
        }
    });

    return convertView;
}

class CriterioViewHolder {

    TextView txtCriterio;
    ToggleButton tgIrregular;
    ImageView btnCam;

}

}

1 个答案:

答案 0 :(得分:0)

您的问题是由于ListView(和RecyclerView)中的观看次数的回收,以下情况发生在您身上:

  1. 您将ImageView中的ToggleButton的可见性设置为ImageView
  2. 不可见
  3. 您的行被滚动到视线之外,因此被回收。
  4. 循环播放的视图仍有View.INVISIBLE,其可见度设置为List
  5. 您将新值分配给该行,但不会更改可见性
  6. 要解决此问题,您应该拥有HashMapToggleButton或类似的内容,并跟踪哪些ImageView已选中且public View getView(int position, View convertView, ViewGroup parent)可见。 (你可以用这个位置做到这一点)

    然后,在viewHolder.btnCam.setVisibility()方法中,检查此位置的(行)图像是否应该可见,并使用ToggleButtonHashMap<Integer,Boolean> toggleButtonStateTracker = new HashMap<>;进行相应设置。

    修改

    将此成员变量添加到适配器
    if (! toggleButtonStateTracker.containsKey(position)){ // Now the HashMap definitely contains the key toggleButtonStateTracker.put(position,false); } boolean isChecked = toggleButtonStateTracker.get(position); viewHolder.tgIrregular.setChecked(isChecked); if (isChecked){ // if your toggle Button is checked, the btnCam should be invisible viewHolder.btnCam.setVisibility(View.INVISIBLE); } else { viewHolder.btnCam.setVisibility(View.VISIBLE); }

    在你的getView中添加这个

    viewHolder.tgIrregular.setOnCheckedChangedListener(new CompoundButton.OnCheckedChangeListener() {
      @Override
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        toggleButtonStateTracker.put(getAdapterPosition, isChecked);
      }
    });
    

    最后添加这个tgIrregular

    textBox1