Динамическое обновление содержимого Recyclerview (во фрагменте), когда данные RecyclerView были получены из базы данных SQlite (Android) - PullRequest
0 голосов
/ 12 июля 2020

Я веду записи базы данных расписания занятий на каждый день недели в локальной базе данных 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();
        }
    }
}
...