在ListView中获取切换状态

时间:2014-01-08 18:36:45

标签: android listview switch-statement

在我的应用程序中我希望用户做出多个选择,为此我在ListView中显示一些Switch和一个确认按钮。

问题是,当我在Button onClickListener()函数中插入db中的值时,我可以从开关中检索文本,但不检索它们的状态(在示例中,始终输出true)

btn.setOnClickListener( new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            ListAdapter adapter = list.getAdapter();
            MyDatabase db = new MyDatabase(cntx);
            db.open();
            for(int n=0;n<adapter.getCount();n++)
            {
                View rowview = adapter.getView(n, null, null);
                Switch swtc = (Switch) rowview.findViewById(R.id.switch1);
                String[] args = {(String)swtc.getText()};
                if(swtc.isChecked())
                {
                    Log.i("update", args[0]+" going to be true");
                }
                else
                {
                    Log.i("update", args[0]+" going to be false");

                }
                int a = db.updateAlert(swtc.isChecked(), MyDatabase.Tab_Cal_Set.Cal+"=?", args);
                Toast.makeText(cntx, "affected: "+Integer.toString(a), Toast.LENGTH_LONG).show();
            }
            db.close();

        }
    });

PS:adapter是我为ListView创建的arrayadapter,cntx是应用程序的上下文,MyDatabase是我的自定义类,用于管理Sqlite数据库。希望你能帮帮我

arrayadapter的代码:

 public class NotificationElementList extends ArrayAdapter<String>{

private final Activity context;

private final List<String> titles;
private final List<String> imgs;
private final List<Boolean> alert;


public NotificationElementList(Activity context, List<String> titles, List<String> imgs, List<Boolean> alert) {

    super(context, R.layout.list_single, titles);
    this.context = context;
    this.titles = titles;
    this.imgs = imgs;
    this.alert = alert;

    }

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

    LayoutInflater inflater = context.getLayoutInflater();

    View rowView= inflater.inflate(R.layout.notification_list_element, null, true);

    Switch switch_text = (Switch) rowView.findViewById(R.id.switch1);
    switch_text.setChecked(alert.get(position));
    switch_text.setText(titles.get(position));

    return rowView;
    }

}

2 个答案:

答案 0 :(得分:1)

由于您未向ArrayAdapter.getView方法提供convertView参数,因此它始终会为您创建新的视图层次结构。因此,您将始终看到您的开关小部件的状态已初始化为 alert.get(position)

其中一个潜在的解决方案是将OnCheckedChangeListener设置为切换窗口小部件,并在交换机状态发生变化时更新模型。例如像这样

@Override
public View getView(final int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    View rowView = inflater.inflate(R.layout.notification_list_element, null, true);

    Switch s = (Switch) rowView.findViewById(R.id.switch1);
    s.setChecked(alert.get(position));
    s.setText(titles.get(position));
    s.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            alert.set(position, isChecked);
        }
    });

    return rowView;
}

这样做将允许您直接从模型获取状态,而不是尝试从按钮单击事件处理程序中的切换小部件获取状态。而不是这样做

View rowview = adapter.getView(n, null, null);
Switch swtc = (Switch) rowview.findViewById(R.id.switch1);     
db.updateAlert(swtc.isChecked(), MyDatabase.Tab_Cal_Set.Cal+"=?", args);

你会做

 db.updateAlert(alert.get(n), MyDatabase.Tab_Cal_Set.Cal+"=?", args);

此外,我建议您更新适配器以使用view holder pattern以获得更好的性能。

答案 1 :(得分:0)

您不应该调用适配器getView方法。它由ListView内部使用 其目的是向ListView说明如何填充其内容。

如果alert list用于保存Switch已检查状态,则可以使用它。

btn.setOnClickListener( new View.OnClickListener() {

    @Override
    public void onClick(View v) {

        MyDatabase db = new MyDatabase(cntx);
        db.open();
        for(int n=0;n<alert.size();n++)
        {
            String[] args = {titles.get(n)};
            if(alert.get(n))
            {
                Log.i("update", args[0]+" going to be true");
            }
            else
            {
                Log.i("update", args[0]+" going to be false");

            }
            int a = db.updateAlert(alert.get(n), MyDatabase.Tab_Cal_Set.Cal+"=?", args);
            Toast.makeText(cntx, "affected: "+Integer.toString(a), Toast.LENGTH_LONG).show();
        }
        db.close();

    }
});