有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java从CustomListAdapter内部的SharedReferences中删除值问题

当用户添加注释时,此注释将保存到SharedReferences中。但是,当用户单击图像以删除注释时,该注释将被正确删除,并从SharedReferences中正确删除。但是,当用户关闭应用程序或更改选项卡并返回时,删除的笔记数量会被最后一个笔记替换,因此它会显示所有重复的笔记,以代替删除的笔记。我无法理解这一点,并且感到困惑:/

代码:

import 安卓.app.Activity;
import 安卓.content.SharedPreferences;
import 安卓.preference.PreferenceManager;
import 安卓.util.Log;
import 安卓.view.LayoutInflater;
import 安卓.view.View;
import 安卓.view.ViewGroup;
import 安卓.widget.ArrayAdapter;
import 安卓.widget.Button;
import 安卓.widget.ImageView;
import 安卓.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.ArrayList;
import java.util.Map;
import static 安卓.content.Context.MODE_PRIVATE;

public class CustomListAdapter extends ArrayAdapter<String> {

        private final Activity context;
        private ArrayList<String> notes = new ArrayList<>();
        private ImageView image;
        private int imageCross;
        TextView ruleNotesSet;
        final SharedPreferences FeedPref= PreferenceManager.getDefaultSharedPreferences(getContext());
        final SharedPreferences.Editor fd = FeedPref.edit();

        public CustomListAdapter(Activity context, ArrayList<String> notes, int imageCross) {
            super(context, R.layout.item,notes);
            this.context=context;
            this.notes = notes;
            this.imageCross = imageCross;
        }

        public View getView(final int position, View view, ViewGroup parent) {
            LayoutInflater inflater = context.getLayoutInflater();
            final View rowView = inflater.inflate(R.layout.item, null, false);
            ruleNotesSet = (TextView) rowView.findViewById(R.id.textView1);
            image = (ImageView) rowView.findViewById(R.id.icon);

            Glide.with(getContext())
                    .load(imageCross)
                    .skipMemoryCache(true)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .into(image);


            image.setOnClickListener(new Button.OnClickListener(){
                @Override
                public void onClick(View v){
                    notes.remove(position);
                    fd.remove(Integer.toString(position));
                    fd.apply();
                    fd.commit();
                    notifyDataSetChanged();
                }
            });

            ruleNotesSet.setText(notes.get(position));
            fd.putString(Integer.toString(position), notes.get(position));
            fd.apply();
            fd.commit();

            return rowView;
        }

        public void addNote(String data) {
            notes.add(data);
        }
}

日志:

10-30 13:22:30.053 2538-2538/org.app.random E/Logs: Adding a note{}
10-30 13:22:35.437 2538-2538/org.app.random E/Logs: Adding a note{0=note1}
10-30 13:22:44.927 2538-2538/org.app.random E/Logs: Adding a note{0=note1}
10-30 13:22:49.422 2538-2538/org.app.random E/Logs: Adding a note{0=note1}
10-30 13:22:51.187 2538-2538/org.app.random E/Logs: Adding a note{0=note1}
10-30 13:22:51.200 2538-2538/org.app.random E/Logs: Adding a note{0=note1}
10-30 13:22:51.211 2538-2538/org.app.random E/Logs: Adding a note{0=note1, 1=note2}
10-30 13:22:51.222 2538-2538/org.app.random E/Logs: Adding a note{0=note1, 1=note2, 2=note3}
10-30 13:23:06.252 2538-2538/org.app.random E/Logs: Change tabs/Close app{0=note1, 1=note2, 2=note3, 3=note4}
10-30 13:23:06.299 2538-2538/org.app.random E/Logs: Adding a note{0=note1, 1=note2, 2=note3, 3=note4}
10-30 13:23:06.319 2538-2538/org.app.random E/Logs: Adding a note{0=note1, 1=note2, 2=note3, 3=note4}
10-30 13:23:26.709 2538-2538/org.app.random E/Logs: Removing a note{0=note1, 2=note3, 3=note4}
10-30 13:23:26.716 2538-2538/org.app.random E/Logs: Adding a note{0=note1, 2=note3, 3=note4}
10-30 13:23:26.721 2538-2538/org.app.random E/Logs: Adding a note{0=note1, 2=note3, 3=note4}
10-30 13:23:26.747 2538-2538/org.app.random E/Logs: Adding a note{0=note1, 1=note3, 2=note3, 3=note4}
10-30 13:23:29.795 2538-2538/org.app.random E/Logs: Removing a note{1=note3, 2=note4, 3=note4}
10-30 13:23:29.799 2538-2538/org.app.random E/Logs: Adding a note{1=note3, 2=note4, 3=note4}
10-30 13:23:29.815 2538-2538/org.app.random E/Logs: Adding a note{0=note3, 1=note3, 2=note4, 3=note4}
10-30 13:23:38.491 2538-2538/org.app.random E/Logs: Change tabs/Close app{0=note3, 1=note4, 2=note4, 3=note4}
10-30 13:23:38.506 2538-2538/org.app.random E/Logs: Adding a note{0=note3, 1=note4, 2=note4, 3=note4}
10-30 13:23:38.521 2538-2538/org.app.random E/Logs: Adding a note{0=note3, 1=note4, 2=note4, 3=note4}

我已经使日志非常具有描述性基本上我添加了4个注释,按back键删除键盘这会填充SharedReferences,我更改选项卡,我返回并删除注释,更改选项卡再次使用删除的内容填充注释4

编辑:

在使用SharedReferences中的内容重新填充视图时,我需要:

Start off with : app{0=note1, 1=note2, 2=note3, 3=note4}
Remove notes1 and note2: {1=note3, 2=note4}
When repopulating the view repopulate with only : {1=note3, 2=note4}
Instead what happens currently: {1=note3, 2=note4, 3=note4, 4=note4}

编辑:

根据下面的答案添加更多日志,因为代码已更改:

10-30 17:12:31.527 12984-12984/org.random.app E/Logs: Notes in addNote{0=note 1}
10-30 17:12:31.554 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1}
10-30 17:12:34.400 12984-12984/org.random.app E/Logs: Notes in addNote{0=note 1, 1=note 2}
10-30 17:12:34.415 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 1=note 2}
10-30 17:12:36.525 12984-12984/org.random.app E/Logs: Notes in addNote{0=note 1, 1=note 2, 2=note 3}
10-30 17:12:36.542 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 1=note 2, 2=note 3}
10-30 17:12:38.273 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 1=note 2, 2=note 3}
10-30 17:12:38.295 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 1=note 2, 2=note 3}
10-30 17:12:45.983 12984-12984/org.random.app E/Logs: Removing a note{0=note 1, 2=note 3}
10-30 17:12:45.991 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 2=note 3}
10-30 17:12:45.994 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 2=note 3}
10-30 17:12:50.951 12984-12984/org.random.app E/Logs: Change tabs/Close app{0=note 1, 2=note 3}
10-30 17:12:50.975 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 2=note 3}
10-30 17:12:50.978 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 2=note 3}
10-30 17:12:54.390 12984-12984/org.random.app E/Logs: Removing a note{0=note 1, 2=note 3}
10-30 17:12:54.401 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 2=note 3}
10-30 17:12:57.466 12984-12984/org.random.app E/Logs: Change tabs/Close app{0=note 1, 2=note 3}
10-30 17:12:57.522 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 2=note 3}
10-30 17:12:57.531 12984-12984/org.random.app E/Logs: Notes in getView{0=note 1, 2=note 3}

共 (1) 个答案

  1. # 1 楼答案

    我可能会发现原因: 在get View中将字符串再次添加回SharedPrefernces,每次调用该字符串时,都会执行以下代码:

    fd.putString(Integer.toString(position), notes.get(position));
    fd.apply();
    fd.commit();
    

    就在第行下方:

    ruleNotesSet.setText(notes.get(position));
    

    enter image description here

    如您所见,当适配器构建视图以使其可见时,您正在将相同的值添加回SharedReferences,如果您有足够大的列表,则扩展程度将更大,因为向上/向下滚动将向共享首选项添加新值

    请将它们注释掉并检查结果


    新方法

    创建一个类注释,如下所示:

    public class Note {
    
        private long key;
        private String note;
    
    
        public Note(String note) {
            this.note = note;
            this.key = System.currentTimeMillis();
        }
    
        public Note(long key, String note) {
            this.key = key;
            this.note = note;
        }
    
        public Note(String key, String note) {
            this.key = Long.parseLong(key);
            this.note = note;
        }
    
        public long getKey() {
            return key;
        }
    
        public String getNote() {
            return note;
        }
    
        public String getKeyAsString(){
            return String.valueOf(key);
        }
    }
    

    然后将其添加到您的活动中(仅用于测试):

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        ArrayList<Note> notes = new ArrayList<Note>();
        try {
            notes.add(new Note(System.currentTimeMillis(), "Note 1"));
            Thread.sleep(2);
            notes.add(new Note(System.currentTimeMillis(), "Note 2"));
            Thread.sleep(2);
            notes.add(new Note(System.currentTimeMillis(), "Note 3"));
        } catch (Exception e) {
    
        }
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
    
        SharedPreferences.Editor edit = sp.edit();
    
        for (Note n : notes) {
            edit.putString(n.getKeyAsString(), n.getNote());
        }
    }
    

    此方法用于从SharedReferences加载笔记

    private List<Note> readNotes() {
        List<Note> notes = new ArrayList<Note>();
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        Map<String, ?> values = sp.getAll();
    
        for (String key : values.keySet()) {
            notes.add(new Note(key, (String) values.get(key)));
        }
    
        return notes;
    }
    

    自定义ListAdapter的最后一个选项:

    public class CustomListAdapter extends ArrayAdapter<String> {
    
        private final Activity context;
        private ArrayList<Note> notes = new ArrayList<Note>();
        private ImageView image;
        private int imageCross;
        TextView ruleNotesSet;
        final SharedPreferences FeedPref= PreferenceManager.getDefaultSharedPreferences(getContext());
        final SharedPreferences.Editor fd = FeedPref.edit();
    
        public CustomListAdapter(Activity context, ArrayList<String> notes, int imageCross) {
            super(context, R.layout.item,notes);
            this.context=context;
            this.notes = notes;
            this.imageCross = imageCross;
        }
    
        public View getView(final int position, View view, ViewGroup parent) {
            Note note = notes.get(position);
    
            LayoutInflater inflater = context.getLayoutInflater();
            final View rowView = inflater.inflate(R.layout.item, null, false);
            ruleNotesSet = (TextView) rowView.findViewById(R.id.textView1);
            image = (ImageView) rowView.findViewById(R.id.icon);
    
            Glide.with(getContext())
                    .load(imageCross)
                    .skipMemoryCache(true)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .into(image);
    
    
            image.setOnClickListener(new Button.OnClickListener(){
                @Override
                public void onClick(View v){
                    Note n = (Note) v.getTag();
                    notes.remove(n);
                    fd.remove(n.getKeyAsString());
                    fd.apply();
                    fd.commit();
                    notifyDataSetChanged();
                }
            });
    
            ruleNotesSet.setText(note.getNote());
    
            image.setTag(note);
    
            return rowView;
        }
    
        public void addNote(String data) {
            Note note = new Note(System.currentTimeMillis(), data);
            fd.putString(note.getKeyAsString(), note.getNote());
            fd.commit();
            notes.add(note);
            notifyDataSetChanged();
        }
    }
    

    我相信这会在你需要的时候起作用

    注意:我将时间戳作为密钥,以确保密钥不会重复,因此,在添加新注释时不会覆盖现有密钥

    还请注意,我在每个图像上添加了相应的Note对象作为view标记,以便在用户单击删除它时将其返回,从而获得正确的Note键

    请尝试一下,让我知道它是否适合你