簡體   English   中英

通知適配器插入 RoomDatabase 中的項目並更新 recyclerView

[英]Notify adapter on item inserted in RoomDatabase and update the recyclerView

我正在使用 java 創建一個筆記應用程序,我將房間數據庫添加到我的應用程序中,當用戶保存筆記時,它會將其添加到數據庫中,但不會立即顯示在 recyclerView 中,當我重新加載應用程序時它會顯示,應該如何以及在哪里我插入 notifyiteminserted 以便 recyclerView 立即更改

我已經嘗試過 onResume 方法,但這會導致應用程序崩潰。 這是我的主要活動。


import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {


    static ArrayList<Notes> arrNotes;
    @SuppressLint("StaticFieldLeak")
    RecyclerViewAdapter adapter;
    RecyclerView.LayoutManager layoutManager;
    notesModelView modelView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);

        arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();


        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        adapter = new RecyclerViewAdapter(this, arrNotes);
        recyclerView.setAdapter(adapter);

        //setting up recycler view
        layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);

        //Setting custom Toolbar
        Toolbar toolbar1 = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar1);

        //Moving from MainActivity to add_Notes Activity
        Button button = findViewById(R.id.floatingActionButton);
        button.setOnClickListener(view -> {
            Intent intent = new Intent(MainActivity.this, addActivity.class);
            startActivity(intent);

        });

    }
}


這是我的 add_Activity。

package com.example.keepnotes;

import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import java.util.Objects;

public class addActivity extends AppCompatActivity {


    MainActivity mainActivity;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);

        Toolbar toolbar_add = findViewById(R.id.toolbar_add_activity);
        setSupportActionBar(toolbar_add);
        Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
        toolbar_add.setNavigationIcon(R.drawable.back_button);
        toolbar_add.setNavigationOnClickListener(view -> onBackPressed());

        EditText titleText = findViewById(R.id.add_activity_title);
        EditText bodyText = findViewById(R.id.add_activity_text);
        Button saveBtn = findViewById(R.id.button);
        DatabaseHelper database = DatabaseHelper.getDatabase(this);


        saveBtn.setOnClickListener(view -> {
            String titleBody = titleText.getText().toString();
            String textBody = bodyText.getText().toString();

            if (titleBody.equals("") && textBody.equals("")) {
                Toast.makeText(addActivity.this, "Fields can't be empty",
                        Toast.LENGTH_LONG).show();
            } else {
                database.notesDao().addNotes(new Notes(titleBody, textBody));
                finish();
            }
        });
    }
}

我如何通知適配器添加到數據庫中的每個項目的更改。

這是我更新到 liveData 后的 MainActivity。


import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {


    static ArrayList<Notes> arrNotes;
    @SuppressLint("StaticFieldLeak")
    RecyclerViewAdapter adapter;
    RecyclerView.LayoutManager layoutManager;
    notesModelView modelView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);

        modelView = new ViewModelProvider(this).get(notesModelView.class);
        modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
            @Override
            public void onChanged(List<Notes> notes) {
                arrNotes = (ArrayList<Notes>) notes;
            }
        });

        
        arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();


        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        adapter = new RecyclerViewAdapter(this, arrNotes);
        recyclerView.setAdapter(adapter);

        //setting up recycler view
        layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);

        //Setting custom Toolbar
        Toolbar toolbar1 = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar1);

        //Moving from MainActivity to add_Notes Activity
        Button button = findViewById(R.id.floatingActionButton);
        button.setOnClickListener(view -> {
            Intent intent = new Intent(MainActivity.this, addActivity.class);
            startActivity(intent);

        });

    }
}

這是道。


import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

@Dao
public interface NotesDao {

    @Query("SELECT * FROM notesTable")
    List<Notes> getAllNotes();

    @Query("SELECT * FROM notesTable")
    LiveData<List<Notes>> findAllNotes();

    @Insert
    void addNotes(Notes note);

    @Update
    void updateNotes(Notes note);

    @Delete
    void deleteNotes(Notes note);



}

這是我的 ViewModel

package com.example.keepnotes;

import android.app.Application;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;

import java.util.List;

public class notesModelView extends AndroidViewModel {

    DatabaseHelper databaseHelper;

    public notesModelView(@NonNull Application application) {
        super(application);
        databaseHelper = DatabaseHelper.getDatabase(application.getApplicationContext());
    }

    public LiveData<List<Notes>> getAllNotes() {
        return databaseHelper.notesDao().findAllNotes();
    }

}

這是我的 RecyclerView 適配器

package com.example.keepnotes;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

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

import java.util.ArrayList;
import java.util.List;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    Context context;
    ArrayList<Notes> arrNotes;
    DatabaseHelper databaseHelper;

    RecyclerViewAdapter(Context context, ArrayList<Notes> arrNotes, DatabaseHelper databaseHelper) {
        this.context = context;
        this.arrNotes = arrNotes;
        this.databaseHelper = databaseHelper;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.single_view, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, @SuppressLint("RecyclerView") int position) {
        holder.title.setText(arrNotes.get(position).title);
        holder.body.setText(arrNotes.get(position).text);
        holder.index.setText(String.valueOf(position + 1));

        holder.llView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {

                AlertDialog.Builder alert = new AlertDialog.Builder(context)
                        .setTitle("Delete view")
                        .setMessage("Are you sure to delete")
                        .setIcon(R.drawable.ic_baseline_delete_24)
                        .setPositiveButton("yes", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                
                                databaseHelper.notesDao().deleteNotes(new Notes(arrNotes.get(position).id,arrNotes.get(position).title,arrNotes.get(position).text));
                                notifyItemRemoved(position);
                                notifyItemRangeChanged(position, arrNotes.size());
                            }
                        })
                        .setNegativeButton("No", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {

                            }
                        });
                alert.show();


                return true;
            }
        });

    }

    @Override
    public int getItemCount() {
        return arrNotes.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView title, body, index;
        CardView llView;

        public ViewHolder(View itemView) {
            super(itemView);
            title = itemView.findViewById(R.id.text_title_view);
            body = itemView.findViewById(R.id.text_text_view);
            index = itemView.findViewById(R.id.index);
            llView = itemView.findViewById(R.id.card_View);
            databaseHelper = DatabaseHelper.getDatabase(context);
        }
    }
}


它會刪除選定的筆記,但在確認刪除后也會立即崩潰。

它會引發以下錯誤

    java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{535e3b3 position=5 id=-1, oldPos=4, pLpos:4 scrap [attachedScrap] tmpDetached not recyclable(1) no parent} androidx.recyclerview.widget.RecyclerView{11f4816 VFED..... ......ID 31,171-689,1048 #7f090165 app:id/recycler_view}, adapter:com.example.keepnotes.RecyclerViewAdapter@fd652a0, layout:androidx.recyclerview.widget.StaggeredGridLayoutManager@32e1e59, context:com.example.keepnotes.MainActivity@286bccd

刪除這兩行

notifyItemRemoved(position);
notifyItemRangeChanged(position, arrNotes.size());

舊答案

首先,如果你使用 liveData 你不需要調用該方法

arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();

只需保留對適配器實例的引用,只要 liveData 發生更改,就調用 notifyDataSetChanged 方法。

adapter = new RecyclerViewAdapter(this,new List<Notes>());
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(adapter);
modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
        @Override
        public void onChanged(List<Notes> notes) {
            arrNotes.clear();
            arrNotes.addAll(notes);
            adapter.notifyDataSetChanged()
        }
    });

觀察 LiveData object 因為它不是 LifecycleOwner

在 LiveData 上使用observeForever() ,在適當的時候通過removeObserver()手動取消注冊(服務的onDestroy() ,如果不是更早的話)。

請記住,此處適用標准服務限制(例如,服務在 Android 8.0+ 上運行約 1 分鍾,除非它們是前台服務),因此您可能需要考慮其他方法。

您也可以在此處閱讀更多原始帖子 -> 鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM