Android的ListView控件与切换按钮 [英] Android ListView with toggle button

查看:264
本文介绍了Android的ListView控件与切换按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,当我的ListView具有可以在屏幕上会出现更多的itens一个问题;换言之,当它到达滚动。问题是,当我在切换按钮一按,这是改变的ImageView的知名度。然而,当我点击它,它正在改变比相应的点击更多的知名度。

我使用的适配器以显示列表itens。

我添加下面的code:

 公共类CriteriosAdapter扩展ArrayAdapter<&搜索标准GT; {私人上下文的背景下;公共CriteriosAdapter(上下文的背景下,列表与LT;搜索标准>对象){
    超(背景下,0,对象);
    this.context =背景;
}@覆盖
公共查看getView(INT位置,查看convertView,父母的ViewGroup){
    最终的搜索标准搜索标准=的getItem(位置);
    最后CriterioViewHolder viewHolder;    如果(convertView == NULL){
        convertView = LayoutInflater.from(的getContext())膨胀(R.layout.fragment_row,父母,假的)。        viewHolder =新CriterioViewHolder();
        viewHolder.txtCriterio =(TextView中)convertView.findViewById(R.id.txtCriterio);
        viewHolder.tgIrregular =(切换按钮)convertView.findViewById(R.id.tgIrregular);
        viewHolder.btnCam =(ImageView的)convertView.findViewById(R.id.btnCam);        convertView.setTag(viewHolder);
    }
    其他{
        viewHolder =(CriterioViewHolder)convertView.getTag();
    }    viewHolder.txtCriterio.setText(criterio.nome);
    viewHolder.txtCriterio.setTextColor(context.getColor(R.color.white));
    viewHolder.tgIrregular.setChecked(假);    viewHolder.tgIrregular.setOnClickListener(新View.OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            如果(viewHolder.tgIrregular.isChecked()){
                viewHolder.btnCam.setVisibility(View.VISIBLE);
            }其他{
                viewHolder.btnCam.setVisibility(View.INVISIBLE);
            }
        }
    });    viewHolder.btnCam.setOnClickListener(新View.OnClickListener(){
        公共无效的onClick(查看为arg0){
            FragmentActivity活性=(FragmentActivity)(上下文);
            android.support.v4.app.FragmentManager FM = activity.getSupportFragmentManager();
            FotosFragment alertDialog =新FotosFragment();
            alertDialog.show(FM,fragment_alert);
        }
    });    返回convertView;
}类CriterioViewHolder {    TextView的txtCriterio;
    切换按钮tgIrregular;    ImageView的btnCam;}}

有人能帮助我吗?

感谢您。

修改

我说的一切,你描述。但是,我用适配器5片段,如果我去了一个,回来或滚动列表,它仍然失去了价值。

我用criterio.getHash,因为它是所有独特。和位置,可以在其他片段重复,并使其不可思议。

 公共类CriteriosAdapter扩展ArrayAdapter<&搜索标准GT; {私人上下文的背景下;
公共静态地图<字符串搜索标准> irregularidades =新的HashMap<字符串搜索标准>();
HashMap的<字符串,布尔值> toggleButtonStateTracker =新的HashMap<>();公共CriteriosAdapter(上下文的背景下,列表与LT;搜索标准>对象){
    超(背景下,0,对象);
    this.context =背景;
}@覆盖
公共查看getView(INT位置,查看convertView,父母的ViewGroup){
    最终的搜索标准搜索标准=的getItem(位置);
    最后CriterioViewHolder viewHolder;    如果(!toggleButtonStateTracker.containsKey(criterio.getHash())){
        toggleButtonStateTracker.put(criterio.getHash(),FALSE);
    }    Log.e(切换曲目:toggleButtonStateTracker.toString());    如果(convertView == NULL){
        convertView = LayoutInflater.from(的getContext())膨胀(R.layout.fragment_row,父母,假的)。        viewHolder =新CriterioViewHolder();
        viewHolder.txtCriterio =(TextView中)convertView.findViewById(R.id.txtCriterio);
        viewHolder.tgIrregular =(切换按钮)convertView.findViewById(R.id.tgIrregular);
        viewHolder.btnCam =(ImageView的)convertView.findViewById(R.id.btnCam);        convertView.setTag(viewHolder);
    }
    其他{
        viewHolder =(CriterioViewHolder)convertView.getTag();
    }    viewHolder.txtCriterio.setText(criterio.nome);
    如果(Build.VERSION.SDK_INT> = Build.VERSION_ codeS.M){
        viewHolder.txtCriterio.setTextColor(context.getColor(R.color.white));
    }其他{
        viewHolder.txtCriterio.setTextColor(context.getResources()的getColor(R.color.white));
    }    viewHolder.tgIrregular.setId(criterio.id);    最终布尔器isChecked = toggleButtonStateTracker.get(criterio.getHash());
    viewHolder.tgIrregular.setChecked(器isChecked);    viewHolder.btnCam.setTag(criterio.hash);    如果(器isChecked){
        viewHolder.btnCam.setVisibility(View.VISIBLE);
    }其他{
        viewHolder.btnCam.setVisibility(View.INVISIBLE);
    }    viewHolder.tgIrregular.setOnCheckedChangeListener(新CompoundButton.OnCheckedChangeListener(){
        @覆盖
        公共无效onCheckedChanged(CompoundButton buttonView,布尔器isChecked){
            toggleButtonStateTracker.put(criterio.getHash(),器isChecked);
            如果(器isChecked){
                viewHolder.btnCam.setVisibility(View.VISIBLE);
                irregularidades.put(criterio.getHash(),搜索标准);
            }其他{
                viewHolder.btnCam.setVisibility(View.INVISIBLE);
                irregularidades.remove(criterio.getHash());
            }
        }
    });    viewHolder.btnCam.setOnClickListener(新View.OnClickListener(){
        公共无效的onClick(查看为arg0){
            FragmentActivity活性=(FragmentActivity)(上下文);
            android.support.v4.app.FragmentManager FM = activity.getSupportFragmentManager();
            FotosFragment alertDialog =新FotosFragment();            捆绑ARGS =新包();
            args.putString(criterioTag,criterio.getHash());
            alertDialog.setArguments(参数);            alertDialog.setCancelable(假);
            alertDialog.show(FM,fragment_alert);
        }
    });    返回convertView;
}类CriterioViewHolder {    TextView的txtCriterio;
    切换按钮tgIrregular;
    ImageView的btnCam;}}


解决方案

您的问题是,由于意见在的ListView 回收(和 RecyclerView )下发生在你身上:


  1. 您设置的可视性的ImageView 一排隐形与切换按钮

  2. 您的行获取滚动的视线之外,因此得到回收。

  3. 循环使用的观点仍具有的ImageView 与visilibility设置为 View.INVISIBLE

  4. 您指定新值的行,但不改变能见度

要解决这个问题,你应该有一个列表的HashMap 或任何类似,并跟踪其切换按钮检查和的ImageView 可见。 (你可以做到这一点的位置)

然后在你的公共查看getView(INT位置,查看convertView,一个ViewGroup父)方法,你检查这posision的(行)形象应该是可见或不可见,并设置因此与 viewHolder.btnCam.setVisibility()切换按钮为好。

修改

这个成员变量添加到您的适配器结果
的HashMap<整数,布尔> toggleButtonStateTracker =新的HashMap<取代;

在您getView添加此

 如果(!toggleButtonStateTracker.containsKey(位置)){
  //现在HashMap中肯定包含密钥
  toggleButtonStateTracker.put(位置,FALSE);
}布尔=器isChecked toggleButtonStateTracker.get(位置);
viewHolder.tgIrregular.setChecked(器isChecked);
如果(器isChecked){
  //如果切换按钮被选中时,btnCam应该是不可见
  viewHolder.btnCam.setVisibility(View.INVISIBLE);
}其他{
  viewHolder.btnCam.setVisibility(View.VISIBLE);
}

最后添加此tgIrregular

  viewHolder.tgIrregular.setOnCheckedChangedListener(新CompoundButton.OnCheckedChangeListener(){
  @覆盖
  公共无效onCheckedChanged(CompoundButton buttonView,布尔器isChecked){
    toggleButtonStateTracker.put(getAdapterPosition,器isChecked);
  }
});

I'm having a problem when my ListView has more itens that can appear on the screen; in other words, when it gets scroll. The problem is, when I click in one of the toggle buttons, it's change the visibility of the ImageView. However, when I click on it, it is changing the visibility of more than the respective clicked.

I'm using an adapter to display the list itens.

I added the code below:

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;

}

}

Could someone help me with it?

Thank you.

EDIT

I added everything as you describe. However, I use that adapter in 5 fragments, if I go to another, and come back or scroll the list, it still lost the value.

I used criterio.getHash, because it is unique for all. And position, can repeat in other fragment, and make it weird.

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;

}

}

解决方案

Your issue is due to the recycling of Views in ListView (and RecyclerView) The following happens to you:

  1. You set visibility of an ImageView in one row to invisible with your ToggleButton
  2. Your row gets scrolled out of sight and therefore gets recycled.
  3. The recycled view still has an ImageView with visilibility set to View.INVISIBLE
  4. You assign your new values to the row but don't change the visibility

To solve this you should have a List, HashMap or anything similar and track which ToggleButton is checked and which ImageView is visible. (You can do that with the position)

Then in your public View getView(int position, View convertView, ViewGroup parent) method you check if this posision's (rows) image should be visible or not and set it accordingly with viewHolder.btnCam.setVisibility() and the ToggleButton as well.

EDIT

Add this member variable to your adapter
HashMap<Integer,Boolean> toggleButtonStateTracker = new HashMap<>;

In your getView add this

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

And finally add this tgIrregular

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

这篇关于Android的ListView控件与切换按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆