Я создаю приложение для заметок, которое использует RecyclerView для отображения ArrayList<Note>
данных, где Note
- это класс данных для каждого элемента, и я сохраняю и извлекаю их, используя другой класс, называемый NotesController (используя Gson). Чтобы обновить список, теперь я переназначаю новое значение в NotesAdapter (адаптер RecyclerView), который я установил в своем списке. Вот мой код:
NotesController:
public class NotesController {
private ArrayList<Note> notesList;
private String notesPath;
private Gson gson = new Gson();
private Type type = new TypeToken<ArrayList<Note>>() {
}.getType();
public NotesController(String notesPath) {
this.notesPath = notesPath;
if (FileUtil.isExistFile(notesPath)) {
getNotesList();
} else {
createNewList();
}
}
/**
* Creates a new list if it doesn't exist. Internal class use only.
*/
private void createNewList() {
notesList = new ArrayList<>();
saveLatestData();
}
/**
* Reads the saved notes.json file and retrieves the ArrayList of items of class {@link Note}.
* @return An ArrayList<<h>Note</h>> containing all notes saved in file <b>notes.json</b>
*/
public ArrayList<Note> getNotesList() {
String json = FileUtil.readFile(notesPath);
notesList = gson.fromJson(json, type);
return notesList;
}
/**
* Saves latest changes to the list {@linkplain NotesController#notesList} to notes.json file. Internal class use only.
*/
private void saveLatestData() {
String json = gson.toJson(notesList, type);
FileUtil.writeFile(notesPath, json);
}
/**
* Adds an item of type {@link Note} to the list and saves data by calling {@link NotesController#saveLatestData()}.
* @param note The {@link Note} instance to get added.
*/
public void add(Note note) {
notesList.add(0, note);
saveLatestData();
}
/**
* Replaces an existing item with a new one of type {@link Note} in the list {@link NotesController#notesList} and saves data by calling {@link NotesController#saveLatestData()}.
* @param position The position of the item to get replaced.
* @param note The {@link Note} instance to replace the old item.
* @throws ArrayIndexOutOfBoundsException When position is out of {@link NotesController#notesList} range.
*/
public void set(int position, Note note) {
notesList.set(position, note);
saveLatestData();
}
/**
* Gets the {@link Note} item from the specified position.
* @param position The position of the item to return.
* @return The item at the position specified.
* @throws ArrayIndexOutOfBoundsException When position is out of {@link NotesController#notesList} range.
*/
public Note get(int position) {
return notesList.get(position);
}
/**
* Removes the {@link Note} item in the specified position from the list.
* @param position The position of the item to remove.
* @throws ArrayIndexOutOfBoundsException When position is out of {@link NotesController#notesList} range.
*/
public void remove(int position) {
notesList.remove(position);
saveLatestData();
}
/**
* Indexes the notes list for the given text and returns items that contain the query either in the title or the content.
* @param query The text query to search for (low cased).
* @return The notes whose title or content contains the query (all trimmed and low cased).
*/
public ArrayList<Note> search(String query) {
ArrayList<Note> results = new ArrayList<>();
for (Note note: getNotesList()) {
if (note.getTitle().trim().toLowerCase().contains(query.trim().toLowerCase()) || note.getContent().trim().toLowerCase().contains(query.trim().toLowerCase())) {
results.add(note);
}
}
return results;
}
/**
* Simple method to convert many int parameters to an int[] array.
* @param categories The varargs int[] array.
* @return int[] array from parameters.
*/
public int[] categories(int... categories) {
return categories;
}
}
MainActivity: (только соответствующие коды)
public class MainActivity extends AppCompatActivity {
private NotesAdapter notesAdapter;
public static NotesController notesController;
private RecyclerView notesRecyclerView;
private String notesDir;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fabric.with(this, new Answers(), new Crashlytics());
setContentView(R.layout.activity_main);
...
notesDir = ContextCompat.getDataDir(this).getPath() + "/files/notes.json";
notesController = new NotesController(notesDir);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
notesRecyclerView.setLayoutManager(layoutManager);
updateRecyclerView();
notesAdapter.setOnItemActionListener(new NotesAdapter.ActionListener() {
@Override
public void onItemClick(final int position, View v) {
...
}
@Override
public void onItemLongClick(final int position, View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this).setTitle("Delete?").setMessage("Just for testing.");
dialog.setPositiveButton("DELETE", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
notesController.remove(position);
updateRecyclerView();
}
});
dialog.show();
}
});
...
}
...
private void updateRecyclerView() {
notesAdapter = new NotesAdapter(notesController.getNotesList(), getApplicationContext());
notesRecyclerView.setAdapter(notesAdapter);
notesAdapter.notifyDataSetChanged();
}
}
Теперь, глядя на метод updateRecyclerView()
, вы видите, что я переназначаю Адаптер с новыми данными из NotesController, затем уведомляю список, что данные изменились.
Но мне нужно как-то, безисключая контроллер, чтобы сделать список, сделать анимацию удаления, когда я удаляю (например, длинным щелчком) или добавляю что-то (только по умолчанию). И для этого класс Android RecyclerView Adapter предоставляет нам notifyItemInserted(int)
и notifyItemRemoved(int)
, но в моем случае они не работали (даже с удалением notifyDataSetChanged (), который прерывает эти анимации).
Пожалуйста, неПредложите мне исключить NotesController, поскольку он помогает легко получать доступ к заметкам из разных частей приложения, и мне просто нужен способ, чтобы эти два метода уведомления о вставке и удалении работали без проблем (кстати, любое другое решение приветствуется).
Примечание: вот мой тип адаптера: public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NoteViewHolder>
.