Android:需要在自定义适配器列表视图中保存复选框状态

Posted

技术标签:

【中文标题】Android:需要在自定义适配器列表视图中保存复选框状态【英文标题】:Android: Need to save checkbox state in a custom adapter listview 【发布时间】:2015-06-17 08:19:56 【问题描述】:

我需要能够保存复选框的状态。当应用程序关闭时,它应该保存已选中的复选框,当应用程序重新打开时,应在启动时选中已选中的复选框。它使用自定义适配器列表视图。感谢您的宝贵时间。

主要活动

public class MainActivity extends Activity 

MyCustomAdapter dataAdapter = null;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Generate list View from ArrayList
    displayListView();





private void displayListView() 

    //Array list of countries
    ArrayList<Country> countryList = new ArrayList<Country>();
    Country country = new Country("","Challenge 1",false);
    countryList.add(country);
    country = new Country("ALB","Albania",false);
    countryList.add(country);
    country = new Country("DZA","Algeria",false);
    countryList.add(country);
    country = new Country("ASM","American Samoa",false);
    countryList.add(country);
    country = new Country("AND","Andorra",false);
    countryList.add(country);
    country = new Country("AGO","Angola",false);
    countryList.add(country);
    country = new Country("AIA","Anguilla",false);
    countryList.add(country);

    //create an ArrayAdaptar from the String Array
    dataAdapter = new MyCustomAdapter(this,
            R.layout.country_info, countryList);
    ListView listView = (ListView) findViewById(R.id.listView1);
    // Assign adapter to ListView
    listView.setAdapter(dataAdapter);


    listView.setOnItemClickListener(new OnItemClickListener() 
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) 
            // When clicked, show a toast with the TextView text
            Country country = (Country) parent.getItemAtPosition(position);
            Toast.makeText(getApplicationContext(),
                    "Clicked on Row: " + country.getName(),
                    Toast.LENGTH_LONG).show();
        
    );



private class MyCustomAdapter extends ArrayAdapter<Country> 

    private ArrayList<Country> countryList;

    public MyCustomAdapter(Context context, int textViewResourceId,
                           ArrayList<Country> countryList) 
        super(context, textViewResourceId, countryList);
        this.countryList = new ArrayList<Country>();
        this.countryList.addAll(countryList);
    

    private class ViewHolder 
        TextView code;
        CheckBox name;
    

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

        ViewHolder holder = null;
        Log.v("ConvertView", String.valueOf(position));

        if (convertView == null) 
            LayoutInflater vi = (LayoutInflater)getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            convertView = vi.inflate(R.layout.country_info, null);

            holder = new ViewHolder();
            holder.code = (TextView) convertView.findViewById(R.id.code);
            holder.name = (CheckBox) convertView.findViewById(R.id.checkBox1);
            convertView.setTag(holder);

            holder.name.setOnClickListener( new View.OnClickListener() 
                public void onClick(View v) 
                    CheckBox cb = (CheckBox) v ;
                    Country country = (Country) cb.getTag();
                    Toast.makeText(getApplicationContext(),
                            "Clicked on Checkbox: " + cb.getText() +
                                    " is " + cb.isChecked(),
                            Toast.LENGTH_LONG).show();
                    country.setSelected(cb.isChecked());
                
            );
        
        else 
            holder = (ViewHolder) convertView.getTag();
        

        Country country = countryList.get(position);
        holder.code.setText(" (" +  country.getCode() + ")");
        holder.name.setText(country.getName());
        holder.name.setChecked(country.isSelected());
        holder.name.setTag(country);

        return convertView;

    


Country.Java

public class Country 

String code = null;
String name = null;
boolean selected = false;

public Country(String code, String name, boolean selected) 
    super();
    this.code = code;
    this.name = name;
    this.selected = selected;


public String getCode() 
    return code;

public void setCode(String code) 
    this.code = code;

public String getName() 
    return name;

public void setName(String name) 
    this.name = name;


public boolean isSelected() 
    return selected;

public void setSelected(boolean selected) 
    this.selected = selected;

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >

<TextView android:layout_
    android:layout_ android:padding="10dp"
    android:text="@string/some_text" android:textSize="20sp" />


<ListView android:id="@+id/listView1" android:layout_
    android:layout_ />

country_info.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical"
android:padding="6dip" >

<CheckBox
    android:id="@+id/checkBox1"
    android:layout_
    android:layout_
    android:layout_alignParentLeft="true"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:text="CheckBox" />

<TextView
    android:id="@+id/code"
    android:layout_
    android:layout_
    android:layout_alignBaseline="@+id/checkBox1"
    android:layout_alignBottom="@+id/checkBox1"
    android:layout_toRightOf="@+id/checkBox1"
    android:text="TextView" />

编辑

我将加载首选项放在 getView() 方法中,但一个问题是 sharedPreferences 参数中的“this”带有下划线。此外,我将 savePreferences() 方法和 onPause() 方法放在代码末尾,但 holder.name 似乎不起作用。

public class MainActivity extends Activity 

MyCustomAdapter dataAdapter = null;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Generate list View from ArrayList
    displayListView();









private void displayListView() 

    //Array list of countries
    ArrayList<Country> countryList = new ArrayList<Country>();
    Country country = new Country("","Challenge 1",false);
    countryList.add(country);
    country = new Country("ALB","Albania",false);
    countryList.add(country);
    country = new Country("DZA","Algeria",false);
    countryList.add(country);
    country = new Country("ASM","American Samoa",false);
    countryList.add(country);
    country = new Country("AND","Andorra",false);
    countryList.add(country);
    country = new Country("AGO","Angola",false);
    countryList.add(country);
    country = new Country("AIA","Anguilla",false);
    countryList.add(country);

    //create an ArrayAdaptar from the String Array
    dataAdapter = new MyCustomAdapter(this,
            R.layout.country_info, countryList);
    ListView listView = (ListView) findViewById(R.id.listView1);
    // Assign adapter to ListView
    listView.setAdapter(dataAdapter);


    listView.setOnItemClickListener(new OnItemClickListener() 
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) 
            // When clicked, show a toast with the TextView text
            Country country = (Country) parent.getItemAtPosition(position);
            Toast.makeText(getApplicationContext(),
                    "Clicked on Row: " + country.getName(),
                    Toast.LENGTH_LONG).show();
        
    );



private class MyCustomAdapter extends ArrayAdapter<Country> 

    private ArrayList<Country> countryList;

    public MyCustomAdapter(Context context, int textViewResourceId,
                           ArrayList<Country> countryList) 
        super(context, textViewResourceId, countryList);
        this.countryList = new ArrayList<Country>();
        this.countryList.addAll(countryList);
    

    private class ViewHolder 
        TextView code;
        CheckBox name;
    

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

        ViewHolder holder = null;
        Log.v("ConvertView", String.valueOf(position));

        if (convertView == null) 
            LayoutInflater vi = (LayoutInflater)getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            convertView = vi.inflate(R.layout.country_info, null);

            holder = new ViewHolder();
            holder.code = (TextView) convertView.findViewById(R.id.code);
            holder.name = (CheckBox) convertView.findViewById(R.id.checkBox1);
            convertView.setTag(holder);



            SharedPreferences sharedPreferences = PreferenceManager
                    .getDefaultSharedPreferences(this);
            boolean checkBoxValue = sharedPreferences.getBoolean("CheckBox_Value", false);
            if (checkBoxValue) 
                holder.name.setChecked(true);
             else 
                holder.name.setChecked(false);
            




            holder.name.setOnClickListener( new View.OnClickListener() 
                public void onClick(View v) 
                    CheckBox cb = (CheckBox) v ;
                    Country country = (Country) cb.getTag();
                    Toast.makeText(getApplicationContext(),
                            "Clicked on Checkbox: " + cb.getText() +
                                    " is " + cb.isChecked(),
                            Toast.LENGTH_LONG).show();
                    country.setSelected(cb.isChecked());
                
            );
        
        else 
            holder = (ViewHolder) convertView.getTag();
        

        Country country = countryList.get(position);
        holder.code.setText(" (" +  country.getCode() + ")");
        holder.name.setText(country.getName());
        holder.name.setChecked(country.isSelected());
        holder.name.setTag(country);

        return convertView;

    



private void savePreferences(String key, boolean value) 
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putBoolean(key, value);
    editor.commit();


@Override
public void onPause()
    super.onPause();
    savePreferences("CheckBox_Value", holder.name.isChecked());

【问题讨论】:

【参考方案1】:

您可以使用Android Shared Preferences 来保存复选框状态:

编辑:

要分离关注点,您应该在模型中保留持久性逻辑:

导入 android.content.Context; 导入 android.content.SharedPreferences;

public class Country 

private static final String PREFERENCES_NAMESPACE = "checkboxes_states";

String code = null;
String name = null;
boolean selected = false;
private SharedPreferences mSettings;
private SharedPreferences.Editor mEditor;

public Country(Context context, String code, String name, boolean selected) 
    super();
    this.code = code;
    this.name = name;
    mSettings = context.getSharedPreferences(PREFERENCES_NAMESPACE, 0);
    mEditor = mSettings.edit();
    setSelected(mSettings.getBoolean(code, selected));


public String getCode() 
    return code;


public void setCode(String code) 
    this.code = code;


public String getName() 
    return name;


public void setName(String name) 
    this.name = name;


public boolean isSelected() 
    return selected;


public void setSelected(boolean selected) 
    if(this.selected != selected)  // update if changed
        mEditor.putBoolean(getCode(), selected);
        mEditor.commit();
        this.selected = selected;
    


在初始化 Country 对象时不要忘记传递应用上下文。

【讨论】:

感谢您的评论,但这不仅适用于常规列表视图复选框,也不适用于自定义适配器,如果它可以用于我的情况,我应该把这段代码放在哪里? 在加载自定义适配器视图时的getView方法中,实例化复选框,并放置一个事件监听器以在更改时保存状态 我仍然无法实现它,如果我应该实现它,请您为这部分编写示例代码。非常感谢。 @SoheilAtashpanjeh 你能用你对 SharedPreferences 所做的更改来编辑问题吗? 查看我的更改@SoheilAtashpanjeh

以上是关于Android:需要在自定义适配器列表视图中保存复选框状态的主要内容,如果未能解决你的问题,请参考以下文章

listview 项目未在自定义适配器的 getview 方法中显示分配的值

在自定义适配器中隐藏软键盘

如何在自定义适配器上实现 onClickListener?

如何在自定义适配器中搜索?

当按下 menuItem 以在 android 中显示用于列表视图的自定义适配器时,应用程序崩溃

如何在自定义 ListView 中获取 EditText 的所有值