删除行on

时间:2018-03-07 18:20:56

标签: android android-sqlite android-room

我已将room 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)

1 个答案:

答案 0 :(得分:2)

为什么要在ArrayList中传递PlaceSaved removeItem()removeItem()仅接受PlaceSaved

所以请将onclick更改为

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

在方法签名holder中使final PlacesAdapter.ViewHolder holder成为最终版,否则就无法编译。

您已在delete中定义了PlaceDatabase,而您正在呼叫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);

db

现在,您的PlacesAdapter将拥有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);

var servicePages = Model.Content.Children.Where(x => x.Name.StartsWith("Our Sevice"));