How to create adapter for RecyclerView that displays some data taken from Room Database?

I am creating a Room based language learning app.

Here is how my Entity looks:

@Entity(tableName = "word_table")
public class WordEntity {

@PrimaryKey(autoGenerate = true)
private int id;

private String word;
private String translation;
private String category;

public WordEntity(String word, String translation, String category) {
    this.word = word;
    this.translation = translation;
    this.category = category;
}

/*GETTERS AND ID SETTER*/

In my wordDAO besides standard inserts, deletes etc. I have

@Query("SELECT DISTINCT category FROM word_table")
List<String> getAllCategories();

so I can retrieve all Categories of words in table.

My plan is to create a fragment with RecyclerView that displays all categories but I can’t manage to write a properly working adapter. In most attempts I try to access the database while it’s not yet created and I keep getting "null" errors. I succeeded at creating RecyclerView of all words but it’s useless in this case. Could you help me remake this adapter and fragment to work in intended way?

CategoryPickerFragment:

public class CategoryPickerFragment extends Fragment {

private FragmentCategoryPickerBinding binding;
private WordViewModel categoryPickerViewModel;

public CategoryPickerFragment() {
    // Required empty public constructor
}

public static CategoryPickerFragment newInstance() {
    CategoryPickerFragment fragment = new CategoryPickerFragment();
    Bundle args = new Bundle();
    fragment.setArguments(args);
    return fragment;
}

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


}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    binding = FragmentCategoryPickerBinding.inflate(inflater, container, false);
    return binding.getRoot();
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    RecyclerView mRecyclerView = binding.categoryRecyclerView;
    final CategoryRecyclerViewAdapter adapter = new CategoryRecyclerViewAdapter();

    categoryPickerViewModel = new ViewModelProvider(this, ViewModelProvider
            .AndroidViewModelFactory       
            .getInstance(Objects.requireNonNull(
                            this.getActivity())
                            .getApplication()))
            .get(WordViewModel.class);

     categoryPickerViewModel.getAllWords().observe(getActivity(), adapter::submitList);

     mRecyclerView.setAdapter(adapter);
     mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 }

 public WordViewModel getCategoryPickerViewModel() {
     return categoryPickerViewModel;
 }
}

and the RecyclerView adapter:

public class CategoryRecyclerViewAdapter extends ListAdapter<WordEntity, CategoryRecyclerViewAdapter.CategoryHolder> {
private OnItemClickListener listener;
private List<String> mCategoryList;

public CategoryRecyclerViewAdapter() {
    super(DIFF_CALLBACK);
}
private static final DiffUtil.ItemCallback<WordEntity> DIFF_CALLBACK = new DiffUtil.ItemCallback<WordEntity>() {
    @Override
    public boolean areItemsTheSame(WordEntity oldItem, WordEntity newItem) {
        return oldItem.getId() == newItem.getId();
    }
    @Override
    public boolean areContentsTheSame(WordEntity oldItem, WordEntity newItem) {
        return oldItem.getWord().equals(newItem.getWord()) &&
                oldItem.getTranslation().equals(newItem.getTranslation()) &&
                oldItem.getCategory().equals(newItem.getCategory()) &&
                oldItem.getId() == newItem.getId();
    }
};
@NonNull
@Override
public CategoryHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.category_item_view, parent, false);
    return new CategoryHolder(itemView);
}

@Override
public void onBindViewHolder(@NonNull CategoryHolder holder, int position) {
    WordEntity currentWord = getItem(position);
    holder.categoryTextView.setText(currentWord.getCategory());
}

class CategoryHolder extends RecyclerView.ViewHolder {
    private TextView categoryTextView;
    public CategoryHolder(View itemView) {
        super(itemView);
        categoryTextView = itemView.findViewById(R.id.category_name_text_view);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = getAdapterPosition();
                if (listener != null && position != RecyclerView.NO_POSITION) {
                    listener.onItemClick(getItem(position));
                }
            }
        });
    }
}

public interface OnItemClickListener {
    void onItemClick(WordEntity wordEntity);
}

public void setOnItemClickListener(OnItemClickListener listener) {
    this.listener = listener;
}
}

Maybe there is a way to initialize my database without observer at the start of application so that I can access it whever I want?

I’m really thankful for all help!

Source: Android Questions

LEAVE A COMMENT