0

So this is my code for the fragment:


import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherActivityInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class Frag1 extends Fragment {
    CustomViewModel viewModel;



    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.frag1_layout, container, false);


            viewModel = new ViewModelProvider(this).get(CustomViewModel.class);

            RecyclerView recyclerView = rootView.findViewById(R.id.rv1);
            final Adapter adapter = new Adapter(new Adapter.Diff());

            recyclerView.setAdapter(adapter);
            recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

            viewModel.show().observe(getViewLifecycleOwner(), rEnts -> {
                adapter.submitList(rEnts);
                Log.d("ItemCount", String.valueOf(adapter.getItemCount()));
            });

        Log.d("ItemCountOUTSIDE", String.valueOf(adapter.getItemCount()));

        return rootView;
    }

when I run the app the recycler view is empty, in the logs the "ItemCountOUTSIDE" shows 0 and is written earlier the "ItemCount" which shows 2. RoomDB is capable of showing the 2 items that are in it when the app is run, so i'd imagine its not a problem with the ViewModel. I was able to output the objects in the DB on a TextView using the same observer function and also using the ViewModel. I understand that apparently observer runs in separate thread and that is executed later but I dont know how to fix that since I know concurrency only on a surface level. Also when doing my research this pattern that I'm using seems to be working for others, hence my frustration.

Additional Code for the Adapter and ViewHolder:


import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import org.w3c.dom.Text;

public class Holder extends RecyclerView.ViewHolder {
    private final TextView textView;

    private Holder(@NonNull View itemView) {
        super(itemView);
        textView = itemView.findViewById(R.id.textName);
    }

    public void bind(rEnt E){
        textView.setText(E.rN);
    }

    static Holder create(ViewGroup parent){
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv1_item, parent, false);
        return new Holder(view);
    }

}

and


import android.util.Log;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Query;

import java.util.List;


public class Adapter extends ListAdapter<rEnt, Holder> {

    List<rEnt> myList = getCurrentList();


    public Adapter(@NonNull DiffUtil.ItemCallback<rEnt> diffCB){
        super(diffCB);
    }

    @NonNull
    @Override
    public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return Holder.create(parent);
    }

    @Override
    public void onBindViewHolder(@NonNull Holder holder, int position) {
        rEnt currentEnt = getItem(position);
        holder.bind(currentEnt);
    }

    static class Diff extends DiffUtil.ItemCallback<rEnt>{ //fuck is this as well???

        @Override
        public boolean areItemsTheSame(@NonNull rEnt oldItem, @NonNull rEnt newItem) {
            return oldItem.getId() == newItem.getId();
        }

        @Override
        public boolean areContentsTheSame(@NonNull rEnt oldItem, @NonNull rEnt newItem) {
            return oldItem.rN.equals(newItem.rN);
        }

    }
}
  • The observer is asynchronous, so the code there doesn't run in the order it's written. You should still see a log statement inside the observer print when it gets new data. As for not showing the data, try using `submitList(new ArrayList<>(arr));` to get around [this issue](https://stackoverflow.com/questions/49726385/listadapter-not-updating-item-in-recyclerview). If that doesn't work please try to make a minimum complete example someone else could run to see the same issue – Tyler V Jul 19 '22 at 20:23
  • Also, the DiffUtil class you seem confused about is what the ListAdapter uses to decide which rows to redraw after you call `submitList`. If you haven't implemented it properly it can cause rows to not be updated correctly. – Tyler V Jul 19 '22 at 20:26
  • I found out that my adapter has the items in it but they are in a variable called mDiffer and i also found out that i cant debug my app if i put a breakpoint on the diffcallback. Maybe its my callback isnt called and/or i dont have proper definiton of it – novykovd Jul 20 '22 at 21:12
  • If you make the diff util callback return false for both methods it should force the list to refresh all items every time you submit a list. Be sure to submit a new list object each time too (read the issue I linked above) – Tyler V Jul 20 '22 at 21:38
  • well theyre both false now. I found out my viewholder gets the items and settext works as well, but my recycler view is still empty so i dont know what to think at this point. – novykovd Jul 21 '22 at 15:46
  • Did you use the "new list" fix too? – Tyler V Jul 21 '22 at 15:52
  • yeah, i tried to trace whats happening after settext is called but its written in elvish so i didnt really get far – novykovd Jul 21 '22 at 18:59
  • I don't see anything obviously wrong, can you add the relevant parts of your view model and the `rEnt` class? Or better yet, make a new project with the minimum code needed to replicate the error and share that so someone else could see the same behavior (e.g. posting fake data instead of from Room)? – Tyler V Jul 21 '22 at 20:41
  • well now i remade all of my recycler view code (adapter/holder) in a separate app and it works. so im even more confused. so data gets to the holder in this app, the data is capable of being put out by the viewmodel the viewholder and adapter work fine on their own as well which means its probably something with the flifecycle of the fragment or something – novykovd Jul 22 '22 at 21:03
  • Well now that you have that framework set up you can start adding in things that might be the cause and see when it breaks. – Tyler V Jul 23 '22 at 01:58

0 Answers0