使用DiffUtil通过onResume更新时,RecyclerView为空

时间:2017-08-23 16:53:11

标签: android android-recyclerview recycler-adapter

基本上我正在努力制作一个简单的笔记记录。

  • 包含RecyclerView的启动器活动应显示已创建的备注列表,否则为空。
  • 我有一个浮动操作按钮,可以驱动用户进行音符创建活动,用户可以在其中设置标题和内容。
  • 我尝试通过覆盖启动器活动的RecyclerView并使用使用onResume的自定义更新方法来更新DiffUtil适配器数据。
  • 但不知何故,列表名为'notes'(在NoteAdapter.java中的更新方法中),即包含新数据的列表变空。
  • 此外,我还在NoteAdapter.java的更新方法中对'notes'列表大小进行了一些记录,其中logcat图像显示在最后。

以下是我的NoteAdapter课程:

public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteViewHolder>
{
    private List<Note> noteList;

    class NoteViewHolder extends RecyclerView.ViewHolder {
         TextView title, content;

        NoteViewHolder(View view) {
            super(view);
            title =  view.findViewById(R.id.title);
            content =  view.findViewById(R.id.content);
        }
    }

    NoteAdapter(List<Note> noteList) {
        this.noteList=noteList;
    }

    public void update(List<Note> notes) {
        final NoteDiffUtilCallback diffCallback = new NoteDiffUtilCallback(getData(), notes);
        final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);
        Log.d("TAG",String.valueOf(notes.size()));
        setData(notes);
        Log.d("TAG",String.valueOf(notes.size()));
        diffResult.dispatchUpdatesTo(this);
        Log.d("TAG",String.valueOf(notes.size()));
    }

    @Override
    public NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row,parent,false);
        return new NoteViewHolder(view);
    }

    @Override
    public void onBindViewHolder(NoteViewHolder holder, int position) {
        Note note=noteList.get(position);
        holder.title.setText(note.getTitle());
        holder.content.setText(note.getContent());
    }

    @Override
    public int getItemCount() {
        return  noteList.size();
    }

    public List<Note> getData() {
        return noteList;
    }

    public void setData(List<Note> newList) {
        noteList.clear();
        noteList.addAll(newList);
    }
}

我的DiffUtilCallBack课程:

public class NoteDiffUtilCallback extends DiffUtil.Callback {
    private List<Note> oldNoteList,newNoteList;

    NoteDiffUtilCallback(List<Note> oldNoteList,List<Note> newNoteList) {
        this.oldNoteList=oldNoteList;
        this.newNoteList=newNoteList;
    }

    @Override
    public  int getOldListSize() {
        if(oldNoteList==null)
            return 0;
        else
            return oldNoteList.size();
    }

    @Override
    public  int getNewListSize() {
        if(newNoteList==null)
            return 0;
        else
            return newNoteList.size();
    }

    @Override
    public boolean areItemsTheSame(int o,int n) {
        return oldNoteList.get(o).getTitle().equals(newNoteList.get(n).getTitle());
    }

    @Override
    public boolean areContentsTheSame(int o, int n) {
        Note old=oldNoteList.get(o);
        Note nyu=newNoteList.get(n);
    return (old.getTitle().equals(nyu.getTitle()) && old.getContent().equals(nyu.getContent()));
    }
}

以下是我的Note课程:

public class Note {
    private String title,content;

    public Note() {
    }

    public Note(String title, String content) {
        this.title = title;
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }
}

以下活动允许用户为新笔记设置标题和内容:

public class MainActivity extends AppCompatActivity {
    private EditText maineditText, titleeditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        maineditText = (EditText) findViewById(R.id.maineditText);
        titleeditText = (EditText) findViewById(R.id.titleEditText);
        final CoordinatorLayout cl = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        String title = titleeditText.getText().toString();
                        if (!title.equals(""))
                            save(cl, title);
                        else
                            Toast.makeText(getApplicationContext(), "Please enter title", Toast.LENGTH_LONG).show();
                    }
                });
    }

    public void save(View view, String filename) {
        FileOutputStream outputStream;

        try {
            outputStream = openFileOutput(filename, MODE_PRIVATE);
            outputStream.write(maineditText.getText().toString().getBytes());

            Snackbar.make(view, "Note Saved", Snackbar.LENGTH_LONG)
                    .show();
        } catch (Exception e) {
            Snackbar.make(view, "Failed to save. Try again.", Snackbar.LENGTH_LONG)
                    .show();
        }
    }
}

以下是我的NotesList活动,其中包含RecyclerView

public class NotesList extends AppCompatActivity {
    private List<Note> noteList = new ArrayList<>();
    private NoteAdapter noteAdapter;
    private RecyclerView noteRecycler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notes_list);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent myIntent = new Intent(NotesList.this, MainActivity.class);
                NotesList.this.startActivity(myIntent);
            }
        });
        setupNotes();
        noteRecycler = (RecyclerView) findViewById(R.id.notelistrecycler);
        noteAdapter = new NoteAdapter(noteList);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
        noteRecycler.setLayoutManager(layoutManager);
        noteRecycler.setAdapter(noteAdapter);
    }

    private void setupNotes() {
        File directory = getFilesDir();
        File[] files = directory.listFiles();
        String fileName;
        for (File file : files) {
            fileName = file.getName();
            Note note = new Note(fileName, load(fileName));
            noteList.add(note);
        }
    }

    public boolean fileExists(String fileName) {
        File file = getBaseContext().getFileStreamPath(fileName);
        return file.exists();
    }

    public String load(String fileName) {
        String content = "";
        if (fileExists(fileName)) {
            try {
                FileInputStream fin = openFileInput(fileName);
                InputStreamReader isr = new InputStreamReader(fin);
                BufferedReader br = new BufferedReader(isr);
                String str;
                StringBuilder sb = new StringBuilder();
                while ((str = br.readLine()) != null) {
                    sb.append(str);
                    sb.append("\n");
                }
                fin.close();
                content = sb.toString();
            } catch (Exception e) {
                Toast.makeText(this, "Failed to load.", Toast.LENGTH_LONG).show();
            }
        }
        return content;
    }

    @Override
    protected void onResume() {
        super.onResume();
        Toast.makeText(this, "In onResume()", Toast.LENGTH_LONG).show();
        noteList.clear();
        setupNotes();
        noteAdapter.update(noteList);
    }
}

我的Logcat图片:

logcat

1 个答案:

答案 0 :(得分:0)

实际上,在创建新笔记时更新RecyclerView并不需要做很多事情。您只需调用适配器上的notifyDatasetChanged()函数来相应地更新列表。所以这是你应该如何执行你的实现。

  • 在您计算备注列表中的更改时删除NoteDiffUtilCallback类,这是非常必要的。
  • 修改update中将NoteAdapter函数调用的notifyDataSetChanged()函数。
  • 稍微修改onResume功能代码段以更新NoteList活动中的列表。

所以update函数看起来像这样。仔细看看,我已经删除了函数参数,因为这需要使用适配器中定义的noteList变量。您也可以从setData中删除未使用的功能NoteAdapter

public void update() {
    noteList.notifyDataSetChanged();
}

现在修改onResume活动中的NoteList功能,如下所示。

@Override
protected void onResume() {
    super.onResume();
    noteList.clear();
    setupNotes();
    noteAdapter.update();
}

这应该有效!