Я веду записи базы данных расписания занятий на каждый день недели в локальной базе данных SQlite, и я пытаюсь динамически обновлять содержимое RecyclerView
, когда я нажимаю любую из кнопок внизу экран (который был реализован с помощью горизонтальной прокрутки RecyclerView). RecyclerView
получает данные из базы данных расписания SQlite. Мне нужна ситуация, при которой, когда я нажимаю любую из этих кнопок, представляющих дни недели, я получаю соответствующие данные расписания из базы данных sqlite, а затем обновляю sh и обновляю RecyclerView
. Под этим я подразумеваю, например, когда я нажимаю кнопку вторник, я получаю базу данных SQlite вторника и отображаю полученные данные в RecyclerView
. У меня была идея использовать 7 разных фрагментов, представляющих расписание определенного дня, один из которых заменит ранее видимый фрагмент в макете. Но мне это кажется неэффективным, потому что для этого мне пришлось бы создать 7 дополнительных фрагментов. Я также провел свое исследование и обнаружил, что этот метод notifyDataSetChanged()
существует в классе RecyclerView.Adapter
, но пока я пытался научиться его использовать, я также обнаружил, что это дорогостоящая операция, и тем, кто опубликовал статью, был я чтение по методу notifyDataSetChanged()
посоветовало мне использовать DiffUtils
. И это только сбило меня с толку, если есть простой способ добиться этого. Заранее спасибо :-) . Код показан ниже. Это фрагмент, который представляет макет (прошу прощения, но я не мог загружать изображения в StackOverflow, потому что моя репутация низкая).
В TimeTableFragment. java
package com.projects.timetableapp;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
@SuppressWarnings("ConstantConditions")
public class TimeTableFragment extends Fragment implements View.OnClickListener {
static String dayTableName; // dayTableName refers to the name of the database table to access
private LinearLayoutManager layout;
private RecyclerView horizontalDayList;
Resources resources;
private Typeface typeface;
List<TimetableModel> modelList;
public static TimeTableFragment newInstance() {
return new TimeTableFragment();
}
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
// typeface of the TextView to be changed
typeface = Typeface.createFromAsset(getActivity().getAssets(),
"fonts/Bubbly-Regular.otf");
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup parent,
Bundle savedState) {
setDayTableName(); // retrieve the last selected day
//get all the saved timetable data from the database
Log.d(getClass().getSimpleName(), "Table name: " + dayTableName);
modelList = new DatabaseHelper(getActivity()).getTimeTableData(dayTableName);
if (modelList.isEmpty())
return inflater.inflate(R.layout.assignment_empty, parent, false);
return inflater.inflate(R.layout.fragment_timetable, parent, false);
}
// set the table name from the set button text
private static void setDayTableName() {
String buttonText = DayRowHolder.getSetButtonText();
if (buttonText == null) buttonText = "Monday";
if (buttonText.equalsIgnoreCase("Sunday"))
dayTableName = DatabaseHelper.TIMETABLE_SUNDAY;
else if (buttonText.equalsIgnoreCase("Tuesday"))
dayTableName = DatabaseHelper.TIMETABLE_TUESDAY;
else if (buttonText.equalsIgnoreCase("Wednesday"))
dayTableName = DatabaseHelper.TIMETABLE_WEDNESDAY;
else if (buttonText.equalsIgnoreCase("Thursday"))
dayTableName = DatabaseHelper.TIMETABLE_THURSDAY;
else if (buttonText.equalsIgnoreCase("Friday"))
dayTableName = DatabaseHelper.TIMETABLE_FRIDAY;
else if (buttonText.equalsIgnoreCase("Saturday"))
dayTableName = DatabaseHelper.TIMETABLE_SATURDAY;
else dayTableName = DatabaseHelper.TIMETABLE_MONDAY;
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedState) {
resources = getResources();
boolean isInLandscape =
resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
horizontalDayList = view.findViewById(R.id.horizontalDayList);
if (modelList.isEmpty()) {
// if modelList was empty, a layout indicating an empty list will be
// displayed, to avoid displaying an empty list, which is not just quite
// good for UX design
TextView text = view.findViewById(R.id.no_task_text);
text.setTypeface(typeface);
text.setText(R.string.no_task_in_timetable);
FloatingActionButton fab_add = view.findViewById(R.id.fab_add_empty);
fab_add.setOnClickListener(this);
} else {
RecyclerView timetable = view.findViewById(R.id.timetable);
// set both list to have a fixed size to increase performance of device
horizontalDayList.setHasFixedSize(true);
timetable.setHasFixedSize(true);
// set the view adapter of both list
horizontalDayList.setAdapter(new DaysRowAdapter());
timetable.setAdapter(new TimeTableRowAdapter());
// check if android device is in landscape
if (isInLandscape) {
setHasOptionsMenu(true);
// if device is in landscape mode set the layout of the day buttons to vertical
layout = new LinearLayoutManager(getActivity(),
LinearLayoutManager.VERTICAL,
false);
// if device is in landscape mode set the layout of the saved timetable list to
// the grid style to maximize screen usage
timetable.setLayoutManager(new GridLayoutManager(getActivity(), 2));
} else {
// the default mode for day buttons ==>> horizontal
layout = new LinearLayoutManager(getActivity(),
LinearLayoutManager.HORIZONTAL,
false);
// the default mode for saved timetable list ==>> vertical
timetable.setLayoutManager(new LinearLayoutManager(getActivity(),
LinearLayoutManager.VERTICAL,
false));
FloatingActionButton fab_add_new = view.findViewById(R.id.fab_add_new);
fab_add_new.setOnClickListener(this);
}
// set the layout of horizontal buttons based on screen orientation
horizontalDayList.setLayoutManager(layout);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.timetable_menu, menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case R.id.add_item:
addItem(); // set-up the add timetable screen
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onResume() {
super.onResume();
((MainActivity) getActivity()).getSupportActionBar().setTitle("Timetable");
}
@Override
public void onClick(View v) {
addItem();
}
// This method will be used by the add button on the options menu(while in landscape)
// or by the FAB (while in portrait)
private void addItem() {
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frame, AddTimeTableFragment.newInstance())
.addToBackStack(null)
.commit();
}
// For the horizontal scrolling list (days)
private class DaysRowAdapter extends RecyclerView.Adapter<DayRowHolder> {
@NonNull
@Override
public DayRowHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int ignored) {
View view = getLayoutInflater().inflate(R.layout.day_row, viewGroup, false);
return new DayRowHolder(view);
}
@Override
public void onBindViewHolder(@NonNull DayRowHolder dayRowHolder, int position) {
dayRowHolder.with( typeface, horizontalDayList, layout,
resources, position).bindModel();
}
@Override
public int getItemCount() {
return 7;
}
}
// For the vertical scrolling list (timetable)
private class TimeTableRowAdapter extends RecyclerView.Adapter<TimeTableRowHolder> {
@NonNull
@Override
public TimeTableRowHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int ignored) {
View view = getLayoutInflater().inflate(R.layout.timetable_row, viewGroup, false);
return new TimeTableRowHolder(view);
}
@Override
public void onBindViewHolder(@NonNull TimeTableRowHolder timeTableRowHolder, int position) {
timeTableRowHolder.setHeaderColors(getItemCount());
timeTableRowHolder.with(modelList, resources, typeface, position).bindModel();
}
@Override
public int getItemCount() {
return modelList.size();
}
}
}