listview切换开关仅在最后一行有效 [英] listview toggle switch works only last row

查看:79
本文介绍了listview切换开关仅在最后一行有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的问题是,当我切换开关时,它仅适用于listview的最后一项.我拨动哪个开关都没关系.我研究了其他提出的问题,但我无法弄清楚.

  @Override公共View getView(int position,View convertView,ViewGroup parent){LayoutInflater inflater = LayoutInflater.from(getContext());查看customView = inflater.inflate(R.layout.row,parent,false);字符串allData = getItem(position);最终Switch状态=(Switch)customView.findViewById(R.id.switchStatus);status.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){@Overridepublic void onCheckedChanged(CompoundButton compoundButton,boolean isChecked){Toast.makeText(getContext(),"selectid",Toast.LENGTH_LONG).show();}});返回customView;} 

您可以在这里看到我的适配器处于活动状态.

 公共类adapter_test扩展了ArrayAdapter< String>.{公共adapter_allservicerecords(上下文上下文,字符串[]数据){超级(上下文,R.layout.row,数据);}@Override公共View getView(int position,View convertView,ViewGroup parent){LayoutInflater inflater = LayoutInflater.from(getContext());查看customView = inflater.inflate(R.layout.row,parent,false);字符串allData = getItem(position);尝试 {if(!all_data.isEmpty()){JSONObject jsonRowData = new JSONObject(all_data);尝试 {text.setText(jsonRowData.getString("TITLE"));} catch(Exception e){e.printStackTrace();}}} catch(Exception e){Log.e("FAILED","Json解析错误:" + e.getMessage());}返回customView;}} 

解决方案

该问题的解决方案是,您不必将数据制成字符串,而应将其更改为可以代表每一行的内容.>

例如,您可以将此类设置为代表您的行:

  class Item {字符串数据;布尔切换;公共项目(字符串数据){this.data =数据;}public void setToggled(boolean toggle){切换=切换;}} 

您的数据源现在不能为字符串,因此您应该将列表作为列表,并且可以通过传递新的Item("STRING DATA HERE")轻松地将字符串添加到列表中.将数据添加到列表时.因此,而不是

  String allData = getItem(position); 

您将使用

  Item item = getItem(position); 

然后在getView上看起来像这样:

  @Override公共View getView(int position,View convertView,ViewGroup parent){LayoutInflater inflater = LayoutInflater.from(getContext());视图 customView = inflater.inflate(R.layout.row, parent, false);项目item = getItem(position);最终Switch状态=(Switch)customView.findViewById(R.id.switchStatus);status.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){@Overridepublic void onCheckedChanged(CompoundButton compoundButton,boolean isChecked){//在这里,我们更改项目的值,该项目引用由getItems()返回的数组中的特定索引item.setToggled(isChecked);Toast.makeText(getContext(),"selectid",Toast.LENGTH_LONG).show();}});//在这里,我们得到开关的最新值是status.setChecked(item.toggled);返回customView;} 

请确保还将数据源也更改为表示某种类似于列表"或您决定使用的类似内容的数据结构/列表.

奖金提示:建议使用ViewHolder来保存您的View并有效回收实例.

  class ViewHolder {开关状态查看customView;} 

然后可以轻松地在getView()部分中使用它.实际上,您不必创建视图的新实例,因为convertView或方法的第二个参数表示可以被重用或在为null时实例化的视图.

异构列表可以指定其视图类型的数量,因此该视图始终是正确的类型,因此建议您使用它.

  @Overridepublic View getView(int position,View convertView,ViewGroup parent){LayoutInflater inflater = LayoutInflater.from(getContext());ViewHolder持有者= null;项目item = getItem(position);if(convertView == null){//实例化(如果尚未实例化)convertView = inflater.inflate(R.layout.supplies_list_item,null);owner.statusSwitch =(Switch)convertView.findViewById(R.id.switchStatus);}别的 {持有人=(ViewHolder)convertView.getTag();}//您可以在此处设置值/监听器holder.statusSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){@Overridepublic void onCheckedChanged(CompoundButton compoundButton,boolean isChecked){item.setToggled(isChecked);Toast.makeText(getContext(),"selectid",Toast.LENGTH_LONG).show();}});holder.statusSwitch.setChecked(item.toggled);返回convertView;} 

i'm facing a problem which is, when i toggle switch it's works for only last item of listview. It doesn't matter which switch i toggle. I research other asked questions but i couldn't figure it out.

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View customView = inflater.inflate(R.layout.row, parent, false);
    String allData = getItem(position);


    final Switch status = (Switch) customView.findViewById(R.id.switchStatus);


    status.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
            Toast.makeText(getContext(),"selectid",Toast.LENGTH_LONG).show();

        }
    });

    return customView;

}

You can see my adapter activiy in here.

public class adapter_test extends ArrayAdapter<String> {



    public adapter_allservicerecords(Context context, String[] data){
        super(context, R.layout.row, data);
    }

    @Override
public View getView(int position, View convertView, ViewGroup parent)
{
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View customView = inflater.inflate(R.layout.row, parent, false);
    String allData = getItem(position);



        try {
            if(!all_data.isEmpty()) {
                JSONObject jsonRowData = new JSONObject(all_data);
                try {
                    text.setText(jsonRowData.getString("TITLE"));


                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            Log.e("FAILED", "Json parsing error: " + e.getMessage());
        }

    return customView;

    }
}

解决方案

The solution to the problem is you have to instead of making your data as a String, you should instead change it into something that would represent each row.

For example you can set this class to represent your row:

class Item {
    String data;
    boolean toggled;

    public Item(String data) {
       this.data = data;
    }

    public void setToggled(boolean toggle) {
        toggled = toggle;
    }
}

Your data source now must not be Strings, so you should instead have your List as List and you can easily add your strings to the list by passing on new Item("THE STRING DATA HERE"); when adding data to the list. So instead of

String allData = getItem(position); 

you would use

Item item = getItem(position);

then on the getView would look something like this:

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View customView = inflater.inflate(R.layout.row, parent, false);
    Item item = getItem(position);


    final Switch status = (Switch) customView.findViewById(R.id.switchStatus);

    status.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
            // here we change the value of the item which is referring to the specific index in the array returned by getItems()
            item.setToggled(isChecked);
            Toast.makeText(getContext(),"selectid",Toast.LENGTH_LONG).show();

        }
    });

    // here we get what the latest value of the switch is
    status.setChecked(item.toggled);
    return customView;

}

Make sure you also change your data source into a data structure/list that represents somewhat like List or anything similar on which you decide to use.

BONUS TIP: It is recommended to use a ViewHolder to hold your View and for efficient recycling of instances.

class ViewHolder {
    Switch statusSwitch;
    View customView;
}

Then to use that in the getView() part you can easily. You actually don't have to create a new instance of the view since convertView or the second parameter of the method represents the view that could be reused or instantiated if null.

Heterogeneous lists can specify their number of view types, so that this View is always of the right type, so you are recommended to use that.

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = LayoutInflater.from(getContext());
    ViewHolder holder = null;
    Item item = getItem(position);
    if (convertView == null) { // instantiate if not yet instantiated
        convertView = inflater.inflate(R.layout.supplies_list_item, null);
        holder.statusSwitch = (Switch) convertView.findViewById(R.id.switchStatus);
    }
    else {
        holder = (ViewHolder) convertView.getTag();
    }
    // you could set the values/ listeners  here
    holder.statusSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
            item.setToggled(isChecked);
            Toast.makeText(getContext(),"selectid",Toast.LENGTH_LONG).show();

        }
    });
    holder.statusSwitch.setChecked(item.toggled);

    return convertView;
}

这篇关于listview切换开关仅在最后一行有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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