[英]Android ROOM - How can I Observe LiveData changes (every time my calendar is set-up) and send the LiveData list results to my adapter?
[英]How can I observe LiveData and then pass this data to my adapter?
我有一个日历。 要创建它,我有一个CalendarFragment
打开CustomCalendarView
(扩展线性布局的 class)。
然后使用MyGridAdapter
(扩展 ArrayAdapter 的类)来构造日历。
当您单击日历上的单元格时,您将进入一个新活动,您可以在其中保存包含一些信息的日志(以及单击日历中单元格的日期)。
我在我的 Dao class: Log_Entries_Dao
中有一个查询,它被传递给LogEntriesRepository
然后是LogEntriesViewModel
。
查询:
@Query("SELECT date FROM log_entries_table WHERE log_entries_table.date =:date " ) LiveData<List<LogDates>> getAllDatesWithLogs(List<Date> date);
该查询接收日历月的所有日期的列表,然后返回存在 logEntry 的所有日期的列表。
现在我想在我的setupCalendar
方法中观察这个 LiveData 并将 logEntry 存在的日期列表传递给我的gridAdater
class,这样我就可以向所有存在 logEntry 的单元格添加圆圈。
问题是,我认为在CustomCalendarView
(LinearLayout 类)中使用我的LogViewModel
class 是不好的做法。 如何正确查询我的数据库、观察 liveData 并将其从我的 setUpCalendar 方法中发送到我的适配器?
日历片段
public class CalendarFragment extends Fragment {
CustomCalendarView customCalendarView;
List<Date> dates = new ArrayList<>();
LogEntriesViewModel logEntriesViewModel;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.calendar_activity_main, container,false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
customCalendarView =(CustomCalendarView) getView().findViewById(R.id.custom_calendar_view);
((AppCompatActivity) getActivity()).getSupportActionBar().hide();
}
}
自定义日历视图
public class CustomCalendarView extends LinearLayout {
ImageButton NextButton, PreviousButton;
TextView CurrentDate;
GridView gridView;
public static final int MAX_CALENDAR_DAYS = 42;
Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
Context context;
MyGridAdapter myGridAdapter;
SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM yyyy", Locale.ENGLISH);
SimpleDateFormat monthFormat = new SimpleDateFormat("MMMM", Locale.ENGLISH);
SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy", Locale.ENGLISH);
SimpleDateFormat eventDateFormat = new SimpleDateFormat(("dd-MM-yyyy"), Locale.ENGLISH);
public static final String MY_PREFS_NAME = "MyPrefsFile";
List<Date> dates = new ArrayList<>();
List<Log_Entries> eventsList = new ArrayList<>();
public CustomCalendarView(Context context) {
super(context);
}
public CustomCalendarView(final Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context = context;
InitializeLayout();
SetUpCalendar();
PreviousButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
calendar.add(Calendar.MONTH, -1);
SetUpCalendar();
}
});
NextButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
calendar.add(Calendar.MONTH, 1);
SetUpCalendar();
}
});
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(true);
final String date = eventDateFormat.format(dates.get(position));
Intent i = new Intent(getContext(), WorkoutButtonsActivity.class);
i.putExtra(WorkoutButtonsActivity.EXTRA_DATE, date);
getContext().startActivity(i);
}
});
}
public CustomCalendarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void InitializeLayout() {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.calendar_layout, this);
NextButton = view.findViewById(R.id.nextBtn);
PreviousButton = view.findViewById(R.id.previousBtn);
CurrentDate = view.findViewById(R.id.current_Date);
gridView = view.findViewById(R.id.gridview);
}
private void SetUpCalendar() {
String currentDate = dateFormat.format(calendar.getTime());
CurrentDate.setText(currentDate);
dates.clear();
Calendar monthCalendar = (Calendar) calendar.clone();
monthCalendar.set(Calendar.DAY_OF_MONTH, 1);
int FirstDayofMonth = monthCalendar.get(Calendar.DAY_OF_WEEK) - 1;
monthCalendar.add(Calendar.DAY_OF_MONTH, -FirstDayofMonth);
while (dates.size() < MAX_CALENDAR_DAYS) {
dates.add(monthCalendar.getTime());
monthCalendar.add(Calendar.DAY_OF_MONTH, 1);
}
myGridAdapter = new MyGridAdapter(context, dates, calendar, eventsList);
gridView.setAdapter(myGridAdapter);
}
}
我的网格适配器
public class MyGridAdapter extends ArrayAdapter {
List<Date> dates;
Calendar currentDate;
List<Log_Entries> logs;
LayoutInflater inflater;
public MyGridAdapter(@NonNull Context context, List<Date> dates, Calendar currentDate, List<Log_Entries> logs){
super(context, R.layout.single_cell_layout);
this.dates = dates;
this.currentDate = currentDate;
this.logs = logs;
inflater = LayoutInflater.from(context);
Log.i("dates", String.valueOf(dates));
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Date monthDate = dates.get(position);
Calendar dateCalendar = Calendar.getInstance();
dateCalendar.setTime(monthDate);
int DayNo = dateCalendar.get(Calendar.DAY_OF_MONTH);
int displayMonth = dateCalendar.get(Calendar.MONTH) +1;
int displayYear = dateCalendar.get(Calendar.YEAR);
int currentMonth = currentDate.get(Calendar.MONTH) + 1;
int currentYear = currentDate.get(Calendar.YEAR);
int currentDay = currentDate.get(Calendar.DAY_OF_MONTH);
View view = convertView;
if (view == null){
view = inflater.inflate(R.layout.single_cell_layout, parent,false);
}
if (displayMonth == currentMonth && displayYear == currentYear){
view.setBackgroundColor(getContext().getResources().getColor(R.color.green));
}
else{
view.setBackgroundColor(Color.parseColor("#cccccc"));
}
TextView Day_Number = view.findViewById(R.id.calendar_day);
Day_Number.setText(String.valueOf(DayNo));
Calendar eventCalendar = Calendar.getInstance();
if(DayNo == currentDay && displayMonth == eventCalendar.get(Calendar.MONTH) + 1 && displayYear == eventCalendar.get(Calendar.YEAR)){
Day_Number.setTextColor(Color.parseColor("#FFFF33"));
}
ArrayList<String> arrayList = new ArrayList<>();
for (int i = 0; i < logs.size(); i++){
}
return view;
}
@Override
public int getCount() {
return dates.size();
}
@Override
public int getPosition(@Nullable Object item) {
return dates.indexOf(item);
}
@Nullable
@Override
public Object getItem(int position) {
return dates.get(position);
}
}
日志条目存储库
public class LogEntriesRepository {
private Log_Entries_Dao log_entries_dao;
private LiveData<List<Log_Entries>> allLogEntries;
private LiveData<List<Log_Entries>> allWorkoutLogEntries;
private LiveData<List<LogDates>> allDatesWithLog;
public LogEntriesRepository(Application application) {
ExerciseDatabase database = ExerciseDatabase.getInstance(application);
log_entries_dao = database.log_entries_dao();
allLogEntries = log_entries_dao.getAllFromLogEntries();
}
public void insert(Log_Entries log_entries) {
new InsertLogEntryAsyncTask(log_entries_dao).execute(log_entries);
}
public void update(Log_Entries log_entries) {
new UpdateLogEntryAsyncTask(log_entries_dao).execute(log_entries);
}
public void delete(Log_Entries log_entries) {
new DeleteLogEntryAsyncTask(log_entries_dao).execute(log_entries);
}
public LiveData<List<Log_Entries>> getAllLogEntries() {
return allLogEntries;
}
public LiveData<List<Log_Entries>> getAllWorkoutLogEntries(int junctionID, String date) {
allWorkoutLogEntries = log_entries_dao.getAllFromWorkoutLogEntries(junctionID, date);
return allWorkoutLogEntries;
}
public LiveData<List<LogDates>> getAllDateLogEntries(List<String> date) {
allDatesWithLog = log_entries_dao.getAllDatesWithLogs(date);
return allDatesWithLog;
}
private static class InsertLogEntryAsyncTask extends AsyncTask<Log_Entries, Void, Void> {
private Log_Entries_Dao log_entries_dao;
private InsertLogEntryAsyncTask(Log_Entries_Dao log_entries_dao) {
this.log_entries_dao = log_entries_dao;
}
@Override
protected Void doInBackground(Log_Entries... log_entries) {
log_entries_dao.insert(log_entries[0]);
return null;
}
}
private static class UpdateLogEntryAsyncTask extends AsyncTask<Log_Entries, Void, Void> {
private Log_Entries_Dao log_entries_dao;
private UpdateLogEntryAsyncTask(Log_Entries_Dao log_entries_dao) {
this.log_entries_dao = log_entries_dao;
}
@Override
protected Void doInBackground(Log_Entries... log_entries) {
log_entries_dao.update(log_entries[0]);
return null;
}
}
private static class DeleteLogEntryAsyncTask extends AsyncTask<Log_Entries, Void, Void> {
private Log_Entries_Dao log_entries_dao;
private DeleteLogEntryAsyncTask(Log_Entries_Dao log_entries_dao) {
this.log_entries_dao = log_entries_dao;
}
@Override
protected Void doInBackground(Log_Entries... log_entries) {
log_entries_dao.delete(log_entries[0]);
return null;
}
}
}
日志条目视图模型
public class LogEntriesViewModel extends AndroidViewModel {
private LogEntriesRepository repository;
private LiveData<List<Log_Entries>> allLogEntries;
private LiveData<List<Log_Entries>> allWorkoutLogEntries;
private LiveData<List<LogDates>> allDateLogEntries;
public LogEntriesViewModel(@NonNull Application application) {
super(application);
repository = new LogEntriesRepository(application);
allLogEntries = repository.getAllLogEntries();
}
public void insert(Log_Entries log_entries){
repository.insert(log_entries);
}
public void update(Log_Entries log_entries){
repository.update(log_entries);
}
public void delete(Log_Entries log_entries ) {
repository.delete(log_entries);
}
// public LiveData<List<Log_Entries>> getAllLogs(){
// return allLogEntries;
// }
public LiveData<List<Log_Entries>> getAllWorkoutLogEntries(int junctionID, String date){
allWorkoutLogEntries = repository.getAllWorkoutLogEntries(junctionID, date);
return allWorkoutLogEntries;
}
public LiveData<List<LogDates>> getAllDateLogEntries(List<String> date){
allDateLogEntries = repository.getAllDateLogEntries(date);
return allDateLogEntries;
}
}
试试这个通用模式:
我希望它可以帮助
我希望如果您理解这一点并将其应用于您的代码,如果我没有错,那将解决您的查询。 我没有查看您的所有代码,但我得到了您的查询,即“如何将 Livedata 设置为适配器”,这是解决方案。
您可以在此处与您的参考代码进行比较。
@Dao
interface UserDao {
@Query("SELECT * FROM user ORDER BY lastName ASC")
public abstract LiveData<List<User>> usersByLastName();
}
class MyViewModel extends ViewModel {
public final LiveData<List<User>> usersList;
public MyViewModel(UserDao userDao) {
usersList = userDao.usersByLastName();
}
}
class MyActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
RecyclerView recyclerView = findViewById(R.id.user_list);
UserAdapter<User> adapter = new UserAdapter();
viewModel.usersList.observe(this, list -> adapter.submitList(list));
recyclerView.setAdapter(adapter);
}
}
class UserAdapter extends ListAdapter<User, UserViewHolder> {
public UserAdapter() {
super(User.DIFF_CALLBACK);
}
@Override
public void onBindViewHolder(UserViewHolder holder, int position) {
holder.bindTo(getItem(position));
}
public static final DiffUtil.ItemCallback<User> DIFF_CALLBACK =
new DiffUtil.ItemCallback<User>() {
@Override
public boolean areItemsTheSame(
@NonNull User oldUser, @NonNull User newUser) {
// User properties may have changed if reloaded from the DB, but ID is fixed
return oldUser.getId() == newUser.getId();
}
@Override
public boolean areContentsTheSame(
@NonNull User oldUser, @NonNull User newUser) {
// NOTE: if you use equals, your object must properly override
Object#equals()
// Incorrectly returning false here will result in too many animations.
return oldUser.equals(newUser);
}
}
}
总之,
第 1 步在您的道中:
public abstract LiveData<List<User>> usersByLastName();
第 2 步在您的 ViewModel 中:
public final LiveData<List<User>> usersList;
usersList = userDao.usersByLastName();
最后在您的活动/片段中:
UserAdapter<User> adapter = new UserAdapter();
viewModel.usersList.observe(this, list -> adapter.submitList(list));
recyclerView.setAdapter(adapter);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.