【发布时间】:2018-03-07 18:20:55
【问题描述】:
我已将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"/>
现在,我想用这个deliconImageButton来删除对应的条目。
因此,我尝试将其放入我的适配器中(注意:已更新,请参阅末尾的更新代码):
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)
【问题讨论】:
标签: android android-sqlite android-room