Android 将房间中的预填充数据获取到微调器适配器
大家好!今天我试图解决下一个问题:我为语言列表创建了room数据库,为不同的语言预先填充了五个ready对象,然后我试图将它们传输到spinner adapter中,类似这样:Android 将房间中的预填充数据获取到微调器适配器,android,spinner,android-room,Android,Spinner,Android Room,大家好!今天我试图解决下一个问题:我为语言列表创建了room数据库,为不同的语言预先填充了五个ready对象,然后我试图将它们传输到spinner adapter中,类似这样: @Database(entities = {Language.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { private static AppDatabase INSTANCE; public
@Database(entities = {Language.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public abstract LanguageDao languageDao();
public synchronized static AppDatabase getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = buildDatabase(context);
}
return INSTANCE;
}
private static AppDatabase buildDatabase(final Context context) {
return Room.databaseBuilder(context, AppDatabase.class, "my-database")
.addCallback(new Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
@Override
public void run() {
getInstance(context).languageDao()
.insertAll(Language.populateData());
}
});
}
})
.allowMainThreadQueries()
.build();
}
}
语言
对象的实体和DAO代码:
@Entity
public class Language {
@PrimaryKey
private long id;
@ColumnInfo(name = "language")
private String language;
public Language(String language) {
this.language = language;
}
public static Language[] populateData() {
return new Language[]{new Language("English"), new Language("French"), new Language(
"Spanish"), new Language("Russian"), new Language("Italian")};
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
@Dao
public interface LanguageDao {
@Query("SELECT * FROM language")
List<Language> getAll();
@Insert
void insertAll(Language... languages);
}
如您所见,我已将语言对象的预填充数据插入到数据库实例中。我知道这里不推荐使用allowMainThreadQueries()
方法(只需使用它来简化当前的培训)
此外,我还创建了以下方法,该方法返回微调器对象并将其放入活动代码中:
private Spinner createLanguageSpinner(){
Spinner spinner = findViewById(R.id.language_spinner);
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
List<String>languageStrings = new LinkedList<>();
for(int i = 0; i < languages.size(); i++){
languageStrings.add(languages.get(i).getLanguage());
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line,
languageStrings);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
return spinner;
}
private微调器createLanguageSpinner(){
微调器微调器=findviewbyd(R.id.language\u微调器);
List languages=AppDatabase.getInstance(this.languageDao().getAll();
ListLanguageString=新建LinkedList();
对于(int i=0;i
我的问题是:
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
List languages=AppDatabase.getInstance(this.languageDao().getAll();
我无法用预定义对象填充当前列表,这将导致没有选项可供选择的空微调器。你能告诉我哪里错了吗?我还想听听关于如何简化适配器创建的意见。我来晚了一点,但万一有人也有这个问题 问题是您试图插入没有PrimaryKey
id
值的新对象。因此,您将在数据库中获得一个空表
您可以手动设置id
值,例如:
@Entity
public class Language {
...
public Language(long id, String language) {
this.id = id; // or create method to generate a unique id as a PrimaryKey value must be unique
this.language = language;
}
public static Language[] populateData() {
return new Language[]{
new Language(1, "English"),
new Language(2, "French"),
new Language(3, "Spanish"),
new Language(4, "Russian"),
new Language(5, "Italian")
};
}
}
或者使用PrimaryKey的autoGenerate
属性让SQLite生成唯一id:
@PrimaryKey(autoGenerate = true)
private long id;
有关更多信息,请参阅
不需要对代码进行其他更改
关于第二个问题: 我还想听听关于如何简化程序的意见 适配器的创建 您可以为微调器创建自定义适配器,并将
列表直接传递给它:
public class MyAdapter extends BaseAdapter implements SpinnerAdapter {
private LayoutInflater mInflater;
private List<Language> mItems;
public MyAdapter(Context context, List<Language> items) {
mInflater = LayoutInflater.from(context);
mItems = items;
}
@Override
public int getCount() {
return mItems.size();
}
@Override
public Object getItem(int position) {
return mItems.get(position);
}
@Override
public long getItemId(int position) {
return mItems.get(position).getId();
}
// This is for the default ("idle") state of the spinner.
// You can use a custom layout or use the default one.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = mInflater.inflate(R.layout.spinner_item, parent, false);
}
Language item = (Language) getItem(position);
TextView textView = view.findViewById(R.id.text);
textView.setText(item.getTitle());
return view;
}
// Drop down item view as stated in the method name.
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = mInflater.inflate(R.layout.spinner_dropdown_item, parent, false);
}
Language item = (Language) getItem(position);
TextView textView = view.findViewById(R.id.text);
textView.setText(item.getTitle());
return view;
}
}
在你的活动中:
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
Spinner spinner = findViewById(R.id.spinner);
MyAdapter myAdapter = new MyAdapter(this, languages);
spinner.setAdapter(myAdapter);
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
Spinner spinner = findViewById(R.id.spinner);
// Pass your list as the third parameter. No need to convert it to List<String>
ArrayAdapter<Language> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, languages);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
List languages=AppDatabase.getInstance(this.languageDao().getAll();
微调器微调器=findViewById(R.id.Spinner);
//将列表作为第三个参数传递。无需将其转换为列表
ArrayAdapter=新的ArrayAdapter(这是android.R.layout.simple\u下拉列表\u item\u 1line,语言);
setDropDownViewResource(android.R.layout.simple\u微调器\u下拉菜单\u项);
旋转器。设置适配器(适配器);
根据android设计模式,您应该使用存储库,而不是调用dao来填充微调器,否则您可能会得到exception@Zhar当然但是这个答案是基于这个问题,为了便于理解,我使用了与OP相同的方法。DoesR.layout.spinner_item
layout是spinner放置的布局吗?
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
Spinner spinner = findViewById(R.id.spinner);
// Pass your list as the third parameter. No need to convert it to List<String>
ArrayAdapter<Language> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, languages);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);