簡體   English   中英

刪除行onclick時,會議室數據庫錯誤

[英]Room database error while deleting row onclick

我已將會議室 SQLite數據庫定義為:

@Database(entities = {PlaceSaved.class},version = 1)
public abstract class PlaceDatabase extends RoomDatabase {

    public abstract DatabaseInterface databaseInterface();

    @Override
    protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) {
        return null;
    }

    @Override
    protected InvalidationTracker createInvalidationTracker() {
        return null;
    }

}

定義在:

@Entity
public class PlaceSaved {

  @PrimaryKey(autoGenerate = true)
  private int id;

  @ColumnInfo(name = "time")
  private String time;

  @ColumnInfo(name="title")
  private String title;

  public PlaceSaved(){

  }

  public PlaceSaved(String time, String title) {
    this.time = time;
    this.title = title;
  }

  public String getTime() {
    return time;
  }

  public void setTime(String time) {
    this.time = time;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }
}

相應的DAO為:

@Dao
public interface DatabaseInterface {
  @Query("SELECT * FROM placesaved")
  List<PlaceSaved> getAllItems();

  @Insert
  void insertAll(PlaceSaved... todoListItems);
  @Delete
  public void delete(PlaceSaved... todoListItems);
  @Update
  public void update(PlaceSaved...todoListItems);
}

並且這些數據通過recyclerview顯示,每個項目的布局定義為:

  <TextView
     android:id="@+id/secondLine"/>
   <TextView
    android:id="@+id/firstLine"/>
 <ImageButton
    android:id="@+id/delicon"/>

現在,我想使用此delicon ImageButton刪除相應的條目。 因此,我嘗試將其放入適配器中( 注意:已更新,請參閱末尾的更新代碼 ):

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

    //PlaceDatabase db;
    List<PlaceSaved> items;

    public PlacesAdapter(List<PlaceSaved> items) {
        this.items = items;
    }

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

    @Override
    public void onBindViewHolder(PlacesAdapter.ViewHolder holder, final int position) {

        holder.name.setText(items.get(position).getTitle());
        holder.time.setText(items.get(position).getTime());
//        holder.delbutton.setClickable(true);
        holder.delbutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
          removeItem(items);
        }
      });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder{
        public TextView name;
        public TextView time;
        public ImageButton delbutton;

        public ViewHolder(View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.secondLine);
            time= itemView.findViewById(R.id.firstLine);
            delbutton = itemView.findViewById(R.id.delicon);

        }
    }
    private void removeItem(PlaceSaved infoItem){
      PlaceSaved placeSaved = new PlaceSaved();
      placeSaved.delete(infoItem);
    }
}

並將recyclerview稱為:(**注:onCreate已更新並在末尾發布)

public class PlacesActivity extends AppCompatActivity {
    FloatingActionButton fab, fab1, fab2, fab3;
    LinearLayout fabLayout1, fabLayout2, fabLayout3;
    boolean isFABOpen=false;
    View fabBGLayout;
  public static RecyclerView recyclerView;
  public static RecyclerView.Adapter adapter;
  List<PlaceSaved> items;

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

    //whenever the activity is started, it reads data from database and stores it into
    // local array list 'items'
    final PlaceDatabase db = Room.databaseBuilder(getApplicationContext(), PlaceDatabase.class, "production")
        .build();

    //it is very bad practice to pull data from Room on main UI thread,
    // that's why we create another thread which we use for getting the data and displaying it
    Runnable r = new Runnable() {
      @Override
      public void run() {
        items = db.databaseInterface().getAllItems();
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(getApplication()));
        adapter = new PlacesAdapter(items);
        adapter.notifyDataSetChanged();
        recyclerView.setAdapter(adapter);
      }
    };

這給出了編譯時間錯誤:

PlacesAdapter.java
Error:(43, 22) error: incompatible types: List<PlaceSaved> cannot be converted to PlaceSaved
Error:(68, 17) error: cannot find symbol method delete(PlaceSaved)

請幫助我解決這個問題。

更新根據Vishu的回答,我已將適配器更新為:

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

  private static final String TAG = "MyActivity";

  List<PlaceSaved> items;
  PlaceDatabase db;
  public PlacesAdapter(List<PlaceSaved> items, PlaceDatabase db) {
    this.items = items;
    this.db = db;
  }

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

    @Override
    public void onBindViewHolder(final PlacesAdapter.ViewHolder holder, final int position) {
      holder.name.setText(items.get(position).getTitle());
        holder.time.setText(items.get(position).getTime());
        holder.delbutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
        removeItem(items.get(holder.getAdapterPosition()));
        }
      });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder{
      public TextView name;
      public TextView time;
      public ImageButton delbutton;

      public ViewHolder(View itemView) {
        super(itemView);
        name = itemView.findViewById(R.id.secondLine);
        time= itemView.findViewById(R.id.firstLine);
        delbutton = itemView.findViewById(R.id.delicon);

      }
    }
    private void removeItem(PlaceSaved infoItem){
//      db.delete(infoItem);
      Log.v(TAG, "remove Item called");
    }
}

並在PlacesActivity中:

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

    final PlaceDatabase db = Room.databaseBuilder(getApplicationContext(), PlaceDatabase.class, "production")
        .build();

    Runnable r = new Runnable() {
      @Override
      public void run() {
        items = db.databaseInterface().getAllItems();
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(getApplication()));
        adapter = new PlacesAdapter(items, db);
        adapter.notifyDataSetChanged();
        recyclerView.setAdapter(adapter);
      }
    };

這仍然給語法錯誤:

Error:(71, 17) error: cannot find symbol method delete(PlaceSaved)

和2條警告(並非由於Vishu的回答,它之前曾出現過):

PlaceSaved.java
Warning:(11, 8) There are multiple good constructors and Room will pick the no-arg constructor. You can use the @Ignore annotation to eliminate unwanted constructors.

PlaceDatabase.java
Warning:(13, 17) Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide `room.schemaLocation` annotation processor argument OR set exportSchema to false.

錯誤:更新:
添加db.databaseInterface().delete(infoItem); 在removeitem中給出:

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
      at android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:164)                                                                             
     at android.arch.persistence.room.RoomDatabase.beginTransaction(RoomDatabase.java:211)
     at DatabaseInterface_Impl.delete(DatabaseInterface_Impl.java:94)
     at PlacesAdapter.removeItem(PlacesAdapter.java:69)
     at PlacesAdapter.access$000(PlacesAdapter.java:20)
     at PlacesAdapter$1.onClick(PlacesAdapter.java:45)
     at android.view.View.performClick(View.java:6294)

為什么在removeItem()傳遞PlaceSaved ArrayList removeItem()僅接受PlaceSaved

因此將onclick更改為

removeItem(items.get(holder.getAdapterPosition()));

holder最終在方法簽名final PlacesAdapter.ViewHolder holder否則將無法編譯。

您已經在PlaceDatabase定義了delete並且正在調用PlaceSaved ,這就是為什么您得到Error:(68, 17) error: cannot find symbol method delete(PlaceSaved) PlaceSaved Error:(68, 17) error: cannot find symbol method delete(PlaceSaved)

你可以通過dbPlacesAdapter就像items一樣PlacesAdapter(items, db)

更改

adapter = new PlacesAdapter(items);

adapter = new PlacesAdapter(items, db);

現在,您的PlacesAdapter將具有db實例。 您可以替換placeSaved.delete(infoItem); db.delete(infoItem)

更改

List<PlaceSaved> items;
public PlacesAdapter(List<PlaceSaved> items) {
    this.items = items;
}

List<PlaceSaved> items;
PlaceDatabase db;
public PlacesAdapter(List<PlaceSaved> items, PlaceDatabase db) {
    this.items = items;
    this.db = db
}

和改變

 placeSaved.delete(infoItem);

db.databaseInterface().delete(infoItem);

暫無
暫無

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

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