在我的应用程序中我希望用户做出多个选择,为此我在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数据库。希望你能帮帮我
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;
}
}
答案 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();
}
});