guillefix
guillefix

Reputation: 994

Update RecyclerView when something happens in the Holder

So, here's my project structure. It's just a two tab app.

On the left tab, there's a list of all the available items. On the right tab, there's a list of the user favorite items. In each item there's a button where you click and then that item becomes a favorite. Well, at least that's what I want to achieve. Apparently the items get added to the favorites list, but at the moment the only way to see the new favorites list is closing and reopening the app.

What I need is some way to call the adapter.notifyDataSetChanged() when the item is added as favorite.

Right now, this favorite functionality is done as a method from the Holder I'm using. So, basically the user clicks the fav button on the item, and then the Holder has a clickListener which updates an Array that I store as a JSON in the SharedPreferences, which contains all the favorites items.

Those two tabs are Fragments, and each Fragment has a RecyclerView. They both use the same class:

public class PlaceholderFragment extends Fragment {

    private static final String ARG_SECTION_NUMBER = "section_number";

    private PageViewModel pageViewModel;

    private int section;

    private RecyclerView recyclerView;

    private SharedPreferences prefs = null;

    public static PlaceholderFragment newInstance(int index) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle bundle = new Bundle();
        bundle.putInt(ARG_SECTION_NUMBER, index);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        pageViewModel = ViewModelProviders.of(this).get(PageViewModel.class);
        int index = 1;
        if (getArguments() != null) {
            index = getArguments().getInt(ARG_SECTION_NUMBER);
        }

        section = index;
        pageViewModel.setIndex(index);
        prefs = getContext().getSharedPreferences("app_preferences", MODE_PRIVATE);
    }

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView = rootView.findViewById(R.id.items_list);

        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation());
        recyclerView.addItemDecoration(dividerItemDecoration);

        recyclerView.setLayoutManager(linearLayoutManager);

        List<ItemModel> itemList= new ArrayList<>();

        // All Items Tab
        if (section == 1) {
            // Here I get all the Items and set them in the itemList Array

        else { // Favorite Items Tab (it retrieves an array of items stored in the SharedPreferences)
            Gson gson = new Gson();
            String json = prefs.getString("favoriteList", "");

            if (json.isEmpty()) {

            } else {
                Type type = new TypeToken<List<ItemModel>>() {
                }.getType();

                itemList= gson.fromJson(json, type);
            }
        }

        MyItemAdapter itemAdapter = new MyItemAdapter (getContext(), getActivity(), itemList, section);

        recyclerView.setAdapter(itemAdapter);

        return rootView;
    }

Upvotes: 0

Views: 58

Answers (2)

Birju Vachhani
Birju Vachhani

Reputation: 6373

As you're already using SharedPreferences to save your favorites list, you can register a listener on it to get updates whenever it gets updated and then you can retrieve those changes from SharedPreferences and then update your list.

In your Fragment's onCreateView() method where you check this condition:

// All Items Tab
    if (section == 1) {
        // Here I get all the Items and set them in the itemList Array

    else { // Favorite Items Tab (it retrieves an array of items stored in the SharedPreferences)

        pref.unregisterOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener(){
            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key){
                // here you can retrieve updated data from SharedPreferences and update your list
            }
        });

        Gson gson = new Gson();
        String json = prefs.getString("favoriteList", "");

        if (json.isEmpty()) {

        } else {
            Type type = new TypeToken<List<ItemModel>>() {
            }.getType();

            itemList= gson.fromJson(json, type);
        }
    }

Upvotes: 0

Chrisvin Jem
Chrisvin Jem

Reputation: 4070

You could use MutableLiveData to observe your list, you can then call adapter.notifyDataSetChanged() inside the observe block. So, for example,

public class PlaceholderFragment extends Fragment {

    private MutableLiveData<List<ItemModel>> mMutableLiveData;

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        mMutableLiveData = new MutableLiveData<>();
        mMutableLiveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
               rootView.findViewById(R.id.items_list).getAdapter().notifyDataSetChanged();
            }
        });

        List<ItemModel> itemList= new ArrayList<>();

        // All Items Tab
        if (section == 1) {
            // Here I get all the Items and set them in the itemList Array

        else { // Favorite Items Tab (it retrieves an array of items stored in the SharedPreferences)
            Gson gson = new Gson();
            String json = prefs.getString("favoriteList", "");

            if (json.isEmpty()) {

            } else {
                Type type = new TypeToken<List<ItemModel>>() {
                }.getType();

                itemList= gson.fromJson(json, type);
                mMutableLiveData.setValue(itemList);
            }
        }

        MyItemAdapter itemAdapter = new MyItemAdapter (getContext(), getActivity(), itemList, section);

        recyclerView.setAdapter(itemAdapter);

        return rootView;
    }
}

Upvotes: 1

Related Questions