2

当我的 ListView 有更多可以出现在屏幕上的项目时,我遇到了问题;换句话说,当它滚动时。问题是,当我单击其中一个切换按钮时,它会更改 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;

}

}
4

1 回答 1

0

您的问题是由于ListView(and RecyclerView) 中的 Views 的回收,您会遇到以下情况:

  1. 您将ImageView一行中的可见性设置为不可见ToggleButton
  2. 您的行被滚动到视线之外,因此被回收。
  3. 回收的视图仍然具有ImageView可见性设置为View.INVISIBLE
  4. 您将新值分配给该行但不更改可见性

为了解决这个问题,你应该有一个ListHashMap或任何类似的轨道,它ToggleButton被选中并且ImageView是可见的。(你可以用这个职位做到这一点)

然后在你的public View getView(int position, View convertView, ViewGroup parent)方法中检查这个位置的(行)图像是否应该可见,并相应地设置viewHolder.btnCam.setVisibility()ToggleButton

编辑

将此成员变量添加到您的适配器
HashMap<Integer,Boolean> toggleButtonStateTracker = new HashMap<>;

在你的 getView 添加这个

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

最后添加这个 tgIrregular

viewHolder.tgIrregular.setOnCheckedChangedListener(new CompoundButton.OnCheckedChangeListener() {
  @Override
  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    toggleButtonStateTracker.put(getAdapterPosition, isChecked);
  }
});
于 2016-01-07T16:00:07.337 回答