【问题标题】:SharedPreferences — bad reading but writing OKSharedPreferences — 读得不好但写得好
【发布时间】:2013-02-18 23:02:52
【问题描述】:

我有一个带有ListView 的应用程序,其中包含照片、文本字段和CheckBox。我想保存CheckBox 的状态。我将setOnCheckedChangeListener() 分配给CheckBox。当我点击复选框时一切正常,我在保存日志后阅读了属性。

当我打开应用程序并选择一个或多个复选框并单击“返回”按钮退出时,会出现此问题。当我打开应用程序时,复选框是错误的,如果我关闭并再次打开会发生。为了保存,我有一个唯一的变量 ID。

你能帮忙吗?

  • ItemListBaseAdapter:

    public class ItemListBaseAdapter extends BaseAdapter {
    
        private static ArrayList<ItemDetails> itemDetailsrrayList;
    
        private Integer[] imgid = { R.drawable.img1, R.drawable.img2, R.drawable.img3, R.drawable.img4, R.drawable.img5,
                R.drawable.img6 };
    
        private LayoutInflater l_Inflater;
        private Context _context;
    
        private SharedPreferences _apref;
        private Editor _editor;
        private String _NOMBREPREF = "perroo";
        private String _CADINICIO = "gatoo";
    
        public ItemListBaseAdapter(Context context, ArrayList<ItemDetails> results) {
            _context = context;
            itemDetailsrrayList = results;
            l_Inflater = LayoutInflater.from(context);
    
            _apref = _context.getSharedPreferences(_NOMBREPREF, Context.MODE_PRIVATE);
            _editor = _apref.edit();
        }
    
        public int getCount() {
            return itemDetailsrrayList.size();
        }
    
        public Object getItem(int position) {
            return itemDetailsrrayList.get(position);
        }
    
        public long getItemId(int position) {
            return position;
        }
    
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = l_Inflater.inflate(R.layout.item_details_view, null);
                holder = new ViewHolder();
                holder.txt_itemName = (TextView) convertView.findViewById(R.id.name);
                holder.txt_itemDescription = (TextView) convertView.findViewById(R.id.itemDescription);
                holder.txt_itemPrice = (TextView) convertView.findViewById(R.id.price);
                holder.itemImage = (ImageView) convertView.findViewById(R.id.photo);
                holder.ckb_degustado = (CheckBox) convertView.findViewById(R.id.checkBox1);
    
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
    
            holder.txt_itemName.setText(itemDetailsrrayList.get(position).getName());
    
            holder.txt_itemDescription.setText(itemDetailsrrayList.get(position).getItemDescription());
            holder.txt_itemPrice.setText(itemDetailsrrayList.get(position).getPrice());
    
            holder.itemImage.setImageResource(imgid[itemDetailsrrayList.get(position).getImageNumber() - 1]);
    
            boolean tmprf = readPrefsCheckbox(itemDetailsrrayList.get(position).getIduniko().toString());
            String tmpr2 = Boolean.toString(tmprf);
            holder.ckb_degustado.setChecked(tmprf);
            Log.d("DREKION", "Inicio: " + itemDetailsrrayList.get(position).getIduniko().toString() + " " + tmpr2);
    
            // Checkbox degustation clickado
            holder.ckb_degustado.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    // TODO Auto-generated method stub
                    String cad1;
                    boolean cadtmp;
                    String cadtmpp;
    
                    if (isChecked == true) {
                        cad1 = _CADINICIO + itemDetailsrrayList.get(position).getIduniko().toString();
                        Log.d("DREKION", "True: " + cad1);
                        _editor.putBoolean(cad1, true);
                        _editor.commit();
                        cadtmp = readPrefsCheckbox(itemDetailsrrayList.get(position).getIduniko().toString());
                        cadtmpp = Boolean.toString(cadtmp);
                        Log.d("DREKION", "True despues: " + cadtmpp);
                    } else {
                        cad1 = _CADINICIO + itemDetailsrrayList.get(position).getIduniko().toString();
                        Log.d("DREKION", "False: " + cad1);
                        _editor.putBoolean(cad1, false);
                        _editor.commit();
                        cadtmp = readPrefsCheckbox(itemDetailsrrayList.get(position).getIduniko().toString());
                        cadtmpp = Boolean.toString(cadtmp);
                        Log.d("DREKION", "False despues: " + cadtmpp);
                    }
                }
            });
    
            convertView.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // do something here
                    // for communication with Fragment/Activity, you can use your
                    // own listener
                    /*
                     * Toast.makeText(v.getContext(), "Has elegido : " +
                     * itemDetailsrrayList.get(position).getItemDescription() + "",
                     * Toast.LENGTH_LONG).show(); Intent intent = new
                     * Intent(v.getContext(), ItemMoreInfo.class);
                     * intent.putExtra("objetito",
                     * itemDetailsrrayList.get(position));
                     */
                    sendMessage(v, itemDetailsrrayList.get(position));
                }
            });
            return convertView;
        }
    
        private boolean readPrefsCheckbox(String _iduniko) {
    
            return _apref.getBoolean(_CADINICIO + _iduniko, false);
        }
    
        public void sendMessage(View view, ItemDetails objID) {
            Intent intent = new Intent(view.getContext(), ItemMoreInfo.class);
            intent.putExtra("objetito", objID);
            view.getContext().startActivity(intent);
        }
    
        private void showNotificacion(Context c, String t) {
            Toast.makeText(c, t, Toast.LENGTH_LONG).show();
        }
    
        static class ViewHolder {
    
            TextView txt_itemName;
            TextView txt_itemDescription;
            TextView txt_itemPrice;
            ImageView itemImage;
            CheckBox ckb_degustado;
        }
    }
    
  • MainActivity:

    public class MainActivity extends Activity {
    
        private SharedPreferences pref;
        private Editor editor;
    
        private String _NOMBREPREF = "perroo";
        private String _CADINICIO = "gatoo";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ArrayList<ItemDetails> image_details = GetSearchResults();
    
            // Init shares vars
            pref = getApplicationContext().getSharedPreferences(_NOMBREPREF, 0);
            editor = pref.edit();
    
            final ListView lv1 = (ListView) findViewById(R.id.listV_main);
            lv1.setAdapter(new ItemListBaseAdapter(this, image_details));
            //
            lv1.setOnItemClickListener(new OnItemClickListener() {
    
                @Override
                public void onItemClick(AdapterView<?> a, View v, int position, long id) {
                    /*
                     * 
                     * Object o = lv1.getItemAtPosition(position); ItemDetails
                     * obj_itemDetails = (ItemDetails)o;
                     * Toast.makeText(MainActivity.this, "Has elegido : " + " " +
                     * obj_itemDetails.getName(), Toast.LENGTH_LONG).show();
                     * sendMessage
                     * (findViewById(android.R.id.content),obj_itemDetails);
                     */
                }
            });
        }
    
        private ArrayList<ItemDetails> GetSearchResults() {
            ArrayList<ItemDetails> results = new ArrayList<ItemDetails>();
    
            ItemDetails item_details = new ItemDetails();
            item_details.setIduniko("tap001");
            item_details.setName("Pizza");
            item_details.setItemDescription("prueba");
            item_details.setPrice("2€");
            item_details.setImageNumber(1);
            results.add(item_details);
        }
    }
    

【问题讨论】:

  • 你可以先查看你的_editor.commit();的返回值。
  • 当您恢复应用程序时,并不总是调用 onCreate。这是由于 Activity 生命周期developer.android.com/reference/android/app/… - 您绝对应该将获取 SharedPreferences 的代码移动到 onResume 方法,因为每次打开应用程序时都会调用它。
  • position 内的 onCheckedChanged() 值与循环内 position 的值不同,因为代码在不同的时间运行...
  • @Sam 如何获得相同的位置?

标签: android checkbox sharedpreferences


【解决方案1】:

positiononCheckedChanged() 方法中的值与循环中 position 的值不同,因为代码在不同的时间运行...每次滚动 ListView 时都会运行循环,而 @ 987654324@ 在用户单击 CheckBox 时运行。

一个简单的解决方法是使用setTag()getTag() 来存储该行的字符串。
循环内部:

holder.ckb_degustado.setTag(itemDetailsrrayList.get(position).getIduniko());

内部onCheckedChanged()

cad1 = _CADINICIO + ((String) buttonView.getTag());

(还可以考虑存储对itemDetailsrrayList.get(position) 的本地引用,而不是重复调用相同的方法。)

【讨论】:

    猜你喜欢
    • 2015-02-20
    • 2012-06-25
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多