java - ListView 中的切换监听器给出错误的结果

标签 java android

这是我的数组适配器。它为列表中的每个开关按钮分配一个监听器,该监听器取决于数据库给定的 ID(使用 devices.id 传递)。但出于某种原因,开关监听器正在从开关获取正确的状态。

出于调试目的,无论状态如何,我都使用相同的更改监听器。因此,无论我打开还是关闭它,它都运行相同的功能。

我的问题是有时当我打开第一个开关时,第 7 个开关会打开,而当我打开第 2 个开关时,第 8 个开关会打开。我做错了什么,但我真的想不通。第 6、7 和 8 个开关无法正常工作。

你可以在 LCD 上看到,当我按顺序打开开关时,它必须给我输出“12345678”。但它不是。相反,它给出了“12345112”。

编辑:Emil Adz 给出的答案有效。给我输出“12345678”。但我有一个问题。如果我打开 switch1,向下滚动直到它不可见,然后向上滚动,开关重置为 OFF。为什么会这样?

Wireless Controller Screenshot Wireless Controller Screenshot LCD Output

public class DevListAdapter extends ArrayAdapter<Devices>{

    Context context; 
    int layoutResourceId;    
    Devices data[] = null;
    private TextView txt = null;
    
    public DevListAdapter(Context context, int layoutResourceId, Devices[] data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.d("WCAM","GetView");
        View row = convertView;
        DeviceHolder holder = null;
        Devices devices = data[position];
        String id = devices.id;

        Log.d("WCAM","Inflator");
        if(row == null)
        {
            Log.d("WCAM","True");
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new DeviceHolder();
            holder.devTxt = (TextView)row.findViewById(R.id.devdesc);
            holder.nameTxt = (TextView)row.findViewById(R.id.devname);
            holder.toggleSwitch = (Switch)row.findViewById(R.id.toggleswitch);
            holder.txt = (TextView) row.findViewById(R.id.debug);
            final int i;
            
            if(id.matches("1")) {
                i = 0x31;
            }
            else if(id.matches("2")) {
                i = 0x32;
            }
            else if(id.matches("3")) {
                i = 0x33;
            }
            else if(id.matches("4")) {
                i = 0x34;
            }
            else if(id.matches("5")) {
                i = 0x35;
            }
            else if(id.matches("6")) {
                i = 0x36;
            }
            else if(id.matches("7")) {
                i = 0x37;
            }
            else {
                i = 0x38;
            }
            holder.toggleSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    Control._service.write(i);
                }
             });
            
            row.setTag(holder);
        }
        else
        {
            Log.d("WCAM","False");
            holder = (DeviceHolder)row.getTag();
        }
        
        holder.devTxt.setText(devices.dev);
        holder.nameTxt.setText(devices.name);
        holder.txt.setText(id);
        
        return row;
    }
    
    static class DeviceHolder
    {
        TextView devTxt;
        TextView txt;
        TextView nameTxt;
        Switch toggleSwitch;
    }
}

devices 是 Devices.java 的一个对象

public class Devices {
    public String dev;
    public String name;
    public String id;
    public Devices(){
        super();
    }
    
    public Devices(String _id, String dev, String name) {
        super();
        this.dev = dev;
        this.name = name;
        this.id = _id;
    }
}

最佳答案

像这样尝试:

public class DevListAdapter extends ArrayAdapter<Devices>{

Context context; 
int layoutResourceId;    
Devices data[] = null;
private TextView txt = null;

public DevListAdapter(Context context, int layoutResourceId, Devices[] data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Log.d("WCAM","GetView");
    DeviceHolder holder = null;
    Devices devices = data[position];
    String id = devices.id;

    Log.d("WCAM","Inflator");
        Log.d("WCAM","True");
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new DeviceHolder();
        holder.devTxt = (TextView)row.findViewById(R.id.devdesc);
        holder.nameTxt = (TextView)row.findViewById(R.id.devname);
        holder.toggleSwitch = (Switch)row.findViewById(R.id.toggleswitch);
        holder.txt = (TextView) row.findViewById(R.id.debug);
        final int i;

        if(id.matches("1")) {
            i = 0x31;
        }
        else if(id.matches("2")) {
            i = 0x32;
        }
        else if(id.matches("3")) {
            i = 0x33;
        }
        else if(id.matches("4")) {
            i = 0x34;
        }
        else if(id.matches("5")) {
            i = 0x35;
        }
        else if(id.matches("6")) {
            i = 0x36;
        }
        else if(id.matches("7")) {
            i = 0x37;
        }
        else {
            i = 0x38;
        }
        holder.toggleSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                Control._service.write(i);
            }
         });

    holder.devTxt.setText(devices.dev);
    holder.nameTxt.setText(devices.name);
    holder.txt.setText(id);

    return row;
}

基本上出于某种原因我多次遇到这个问题。当您使用 convertView 时,所有列表都会变得疯狂。请注意它会产生性能这一事实,但我没有找到解决此问题的合适方法。更重要的是,当列表不是那么大时,它不会有太大变化。

更新: 首先看一下本指南:

Multi-clickable ListView

与那里的复选框状态一样,您将看到:

    //setting data into the the ViewHolder.
    holder.title.setText(RowData.getName());
    holder.checked.setChecked(RowData.isChecked());

    //return the row view.
    return convertView;

所以在你的情况下,在这段代码之后:

    holder.devTxt.setText(devices.dev);
    holder.nameTxt.setText(devices.name);
    holder.txt.setText(id);

你应该添加如下内容:

   holder.toggleSwitch.setChecked(devices.isChecked());

并在您的 onCheckedChanged 中保持状态更改。

关于java - ListView 中的切换监听器给出错误的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16387267/

相关文章:

java - Tomcat 6.0 大文件上传(> 2 GB)

java - Android Studio 中的条件问题

java - 有没有办法概括 Apache ANT 目标?

java - 我正在将图像上传到 Firebase Storage,然后需要将图像 URL 作为文本添加到 Firebase 数据库中

java - 如何对在 Android 布局上动态添加的 View 施加权重?

android - 更改方向时如何在 ViewFlipper 中保持当前 View

java - OpenCV使用异常

java - 在Jhipster中创建新实体后,它不会在现有数据库中创建表

android - 如何在android中获取下载文件的http url?

Android 登录替代方案