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;


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?


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();
    return fragment;

public void onCreate(Bundle savedInstanceState) {


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

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

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

     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() {
private static final DiffUtil.ItemCallback<WordEntity> DIFF_CALLBACK = new DiffUtil.ItemCallback<WordEntity>() {
    public boolean areItemsTheSame(WordEntity oldItem, WordEntity newItem) {
        return oldItem.getId() == newItem.getId();
    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();
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);

public void onBindViewHolder(@NonNull CategoryHolder holder, int position) {
    WordEntity currentWord = getItem(position);

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

        itemView.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                int position = getAdapterPosition();
                if (listener != null && position != RecyclerView.NO_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