如何在 ListView 中滚动时保存 CheckBox 的状态?

发布于 2025-01-07 22:30:09 字数 2226 浏览 0 评论 0原文

我已将 ListView 与自定义适配器一起使用,因此我的 ListView 包含 CheckBox,但问题是当我向下滚动时,选中的 CheckBoxes 取消选中,我该如何使用此代码执行此操作?

更新

我的自定义适配器:

    public class AppsArrayAdapter extends ArrayAdapter<String> {
    private final Context context;

    private List<Integer> checkedItems;

    private final String DefaultApps = "def_apps";

    public AppsArrayAdapter(Context context, String[] values, List<Integer> checkedItems) {//XXX
        super(context, R.layout.apps, values);
        this.context = context;
        this.checkedItems = checkedItems;//XXX
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        SharedPreferences myPrefsApps =context.getSharedPreferences("myPrefsApps", Context.MODE_PRIVATE);
        String prefNameDefaultApps = myPrefsApps.getString(DefaultApps, "");
        String prefNameDefaultAppsVer = myPrefsApps.getString(DefaultAppsVer, "");


        LayoutInflater inflater = (LayoutInflater)context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View rowView = inflater.inflate(R.layout.apps, parent, false);
        TextView text_apps = (TextView)rowView.findViewById(R.id.text_apps);
        CheckBox check = (CheckBox)rowView.findViewById(R.id.check_apps);
        text_apps.setText(prefNameDefaultApps.split("\n")[position]);

        check.setChecked(checkedItems.contains((Integer) position));
        return rowView;
    }   
}

和我的活动:

    public class AppsActivity extends ListActivity {
    private final String DefaultApps = "def_apps";

    private List<Integer> checkedItems = new ArrayList<Integer>();


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        AppsArrayAdapter adapter = new AppsArrayAdapter(this, prefNameDefaultApps.split("\n"), checkedItems);
        setListAdapter(adapter);
}
}
@Override
    public void onListItemClick(ListView l, View v, int position, long id) {
       if(checkedItems.contains((Integer) position)) checkedItems.remove((Integer) position);
       else checkedItems.add((Integer) position);
    }

I have used ListView with custom adapter, so my ListView includes CheckBox, but problem is that when I scroll down, checked CheckBoxes uncheck, how can I do it with this code?

UPDATE

My custom adapter:

    public class AppsArrayAdapter extends ArrayAdapter<String> {
    private final Context context;

    private List<Integer> checkedItems;

    private final String DefaultApps = "def_apps";

    public AppsArrayAdapter(Context context, String[] values, List<Integer> checkedItems) {//XXX
        super(context, R.layout.apps, values);
        this.context = context;
        this.checkedItems = checkedItems;//XXX
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        SharedPreferences myPrefsApps =context.getSharedPreferences("myPrefsApps", Context.MODE_PRIVATE);
        String prefNameDefaultApps = myPrefsApps.getString(DefaultApps, "");
        String prefNameDefaultAppsVer = myPrefsApps.getString(DefaultAppsVer, "");


        LayoutInflater inflater = (LayoutInflater)context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View rowView = inflater.inflate(R.layout.apps, parent, false);
        TextView text_apps = (TextView)rowView.findViewById(R.id.text_apps);
        CheckBox check = (CheckBox)rowView.findViewById(R.id.check_apps);
        text_apps.setText(prefNameDefaultApps.split("\n")[position]);

        check.setChecked(checkedItems.contains((Integer) position));
        return rowView;
    }   
}

And my Activity:

    public class AppsActivity extends ListActivity {
    private final String DefaultApps = "def_apps";

    private List<Integer> checkedItems = new ArrayList<Integer>();


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        AppsArrayAdapter adapter = new AppsArrayAdapter(this, prefNameDefaultApps.split("\n"), checkedItems);
        setListAdapter(adapter);
}
}
@Override
    public void onListItemClick(ListView l, View v, int position, long id) {
       if(checkedItems.contains((Integer) position)) checkedItems.remove((Integer) position);
       else checkedItems.add((Integer) position);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

记忆で 2025-01-14 22:30:10

是否有标准解决方案,但这应该可以解决问题

public class AppsArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private List<Integer> checkedItems;//Here we save the position of the selected items.

private final String DefaultApps = "def_apps";
//This will be invoked when one of the CheckBoxes gets clicked. It will update the checkedItems list.
private View.OnClickListener onClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Integer position = (Integer) v.getTag();
        if(checkedItems.contains(position)) checkedItems.remove(position);
        else checkedItems.add(position);
    }
};

public AppsArrayAdapter(Context context, String[] values, List<Integer> checkedItems) {//XXX
    super(context, R.layout.apps, values);
    this.context = context;
    this.checkedItems = checkedItems;//XXX
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    SharedPreferences myPrefsApps =context.getSharedPreferences("myPrefsApps", Context.MODE_PRIVATE);
    String prefNameDefaultApps = myPrefsApps.getString(DefaultApps, "");

    //You shouldn't inflate the View everytime getView() is called,
    /*LayoutInflater inflater = (LayoutInflater)context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View rowView = inflater.inflate(R.layout.apps, parent, false);*/
    //rather let the superclass handle it as it's more efficient.
    View rowView = super.getView(position, convertView, parent);

    TextView text_apps = (TextView)rowView.findViewById(R.id.text_apps);
    CheckBox check = (CheckBox)rowView.findViewById(R.id.check_apps);
    text_apps.setText(prefNameDefaultApps.split("\n")[position]);

    check.setChecked(checkedItems.contains((Integer) position));//XXX
    check.setTag((Integer) position);//XXX
    check.setOnClickListener(onClickListener);//XXX
    return rowView;
}   

我不完全确定 Android中 checkItems = new ArrayList;.您必须在适配器构造函数中传递此列表!
如果你想检查你的ListView中的第n个项目是否被选中,只需查看n是否保存在checkedItems中,即

if(checkedItems.contains(requestedItemPosition)) {
    //Item was selected.
} else {
    //Item was not selected.
}

我真的建议你不要自己膨胀视图。

I'm not entirely sure whether there is a standard solution in Android, but this should do the trick:

public class AppsArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private List<Integer> checkedItems;//Here we save the position of the selected items.

private final String DefaultApps = "def_apps";
//This will be invoked when one of the CheckBoxes gets clicked. It will update the checkedItems list.
private View.OnClickListener onClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Integer position = (Integer) v.getTag();
        if(checkedItems.contains(position)) checkedItems.remove(position);
        else checkedItems.add(position);
    }
};

public AppsArrayAdapter(Context context, String[] values, List<Integer> checkedItems) {//XXX
    super(context, R.layout.apps, values);
    this.context = context;
    this.checkedItems = checkedItems;//XXX
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    SharedPreferences myPrefsApps =context.getSharedPreferences("myPrefsApps", Context.MODE_PRIVATE);
    String prefNameDefaultApps = myPrefsApps.getString(DefaultApps, "");

    //You shouldn't inflate the View everytime getView() is called,
    /*LayoutInflater inflater = (LayoutInflater)context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View rowView = inflater.inflate(R.layout.apps, parent, false);*/
    //rather let the superclass handle it as it's more efficient.
    View rowView = super.getView(position, convertView, parent);

    TextView text_apps = (TextView)rowView.findViewById(R.id.text_apps);
    CheckBox check = (CheckBox)rowView.findViewById(R.id.check_apps);
    text_apps.setText(prefNameDefaultApps.split("\n")[position]);

    check.setChecked(checkedItems.contains((Integer) position));//XXX
    check.setTag((Integer) position);//XXX
    check.setOnClickListener(onClickListener);//XXX
    return rowView;
}   

}

In your ListActivity, add a field private List<Integer> checkedItems = new ArrayList<Integer>;. You have to pass this List in the Adapter constructor!
If you want to check whether the nth item in your ListView was selected, just look whether n is saved in checkedItems, i.e.

if(checkedItems.contains(requestedItemPosition)) {
    //Item was selected.
} else {
    //Item was not selected.
}

I really recommend you not to inflate the views by yourself.

扶醉桌前 2025-01-14 22:30:10

试试这个:(您的自定义适配器)

 public class AppsArrayAdapter extends ArrayAdapter<String> {
private final Context context;

private List<Integer> checkedItems;

private final String DefaultApps = "def_apps";
LayoutInflater inflater;

public AppsArrayAdapter(Context context, String[] values, List<Integer> checkedItems) {//XXX
    super(context, R.layout.apps, values);
    this.context = context;
    this.checkedItems = checkedItems;//XXX
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    SharedPreferences myPrefsApps =context.getSharedPreferences("myPrefsApps", Context.MODE_PRIVATE);
    String prefNameDefaultApps = myPrefsApps.getString(DefaultApps, "");
    String prefNameDefaultAppsVer = myPrefsApps.getString(DefaultAppsVer, "");


View rowView = convertView;
ViewHolder viewH = new ViewHolder();

if ( rowView == null){
        rowView = inflater.inflate(R.layout.apps, parent, false);
        viewH.text_apps = (TextView)rowView.findViewById(R.id.text_apps);
        viewH.check = (CheckBox)rowView.findViewById(R.id.check_apps);
    rowView.setTag(viewH);
}else{
    viewH = (ViewHolder) rowView.getTag();
}

    viewH.text_apps.setText(prefNameDefaultApps.split("\n")[position]);
    viewH.check.setChecked(checkedItems.contains((Integer) position));

    return rowView;
}   

static class ViewHolder {
    public TextView text_apps;
    public CheckBox check;  

}

}

希望这有帮助:)

Try this: (your custom adapter)

 public class AppsArrayAdapter extends ArrayAdapter<String> {
private final Context context;

private List<Integer> checkedItems;

private final String DefaultApps = "def_apps";
LayoutInflater inflater;

public AppsArrayAdapter(Context context, String[] values, List<Integer> checkedItems) {//XXX
    super(context, R.layout.apps, values);
    this.context = context;
    this.checkedItems = checkedItems;//XXX
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    SharedPreferences myPrefsApps =context.getSharedPreferences("myPrefsApps", Context.MODE_PRIVATE);
    String prefNameDefaultApps = myPrefsApps.getString(DefaultApps, "");
    String prefNameDefaultAppsVer = myPrefsApps.getString(DefaultAppsVer, "");


View rowView = convertView;
ViewHolder viewH = new ViewHolder();

if ( rowView == null){
        rowView = inflater.inflate(R.layout.apps, parent, false);
        viewH.text_apps = (TextView)rowView.findViewById(R.id.text_apps);
        viewH.check = (CheckBox)rowView.findViewById(R.id.check_apps);
    rowView.setTag(viewH);
}else{
    viewH = (ViewHolder) rowView.getTag();
}

    viewH.text_apps.setText(prefNameDefaultApps.split("\n")[position]);
    viewH.check.setChecked(checkedItems.contains((Integer) position));

    return rowView;
}   

static class ViewHolder {
    public TextView text_apps;
    public CheckBox check;  

}

}

Hope this helps :)

泛泛之交 2025-01-14 22:30:10

你应该使用
MyAdapter newad=(MyAdapter)adapter.getAdapter();
newad.notifyDataSetChanged();
onitem click 方法中的这段代码
MyAdapter 是 Adapter 的类并创建像这样的新对象
在适配器类中,您应该编写一行

LayoutInflater ;
in=(LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
在适配器构造函数中简单

you should use
MyAdapter newad=(MyAdapter)adapter.getAdapter();
newad.notifyDataSetChanged();
this code in onitem click method
and MyAdapter is class of Adapter and make new object like this one
and in adapter class you should have to write a line

LayoutInflater in;
in=(LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
in adapter constructor simple

欲拥i 2025-01-14 22:30:09
// initialise the list
private List<Integer> selection = new ArrayList<Integer>();

for (String str: prefNameDefaultApps.split("\n")) {
        selection.add(0);
}


// setting the list 
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
        if(CheckBox is checked) {//(check if the checkbox is checked )
               selection.set(position, 1);
        }
        else{
               selection.set(position, 0);
        }
}

// show in the listView
@Override
public View getView(int position, View convertView, ViewGroup parent) {

        ....
        ....
        check.setChecked(selection.get(position) == 0 ? false : true);

}

这应该能让你继续下去:)

// initialise the list
private List<Integer> selection = new ArrayList<Integer>();

for (String str: prefNameDefaultApps.split("\n")) {
        selection.add(0);
}


// setting the list 
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
        if(CheckBox is checked) {//(check if the checkbox is checked )
               selection.set(position, 1);
        }
        else{
               selection.set(position, 0);
        }
}

// show in the listView
@Override
public View getView(int position, View convertView, ViewGroup parent) {

        ....
        ....
        check.setChecked(selection.get(position) == 0 ? false : true);

}

This should get you going :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文