首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >取房间内预填充数据到旋转适配器

取房间内预填充数据到旋转适配器
EN

Stack Overflow用户
提问于 2018-03-07 17:20:52
回答 1查看 3.1K关注 0票数 1

各位!今天,我试图解决下一个问题:我为语言列表创建了空间数据库,为不同的语言预先填充了五个就绪对象,然后尝试将它们转换为spinner适配器,如下所示:

Language对象的实体和DAO代码:

代码语言:javascript
运行
复制
@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);
}

此外,我在AppDatabase类中使用Singleton创建了数据库对象,如下所示:

代码语言:javascript
运行
复制
@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();
    }
}

如您所见,我已经将语言对象的预填充数据插入到数据库实例中。我知道这里不推荐使用allowMainThreadQueries()方法(只需使用它来简化当前的培训)。

此外,我还创建了以下方法,它返回spinner对象并将其放入活动代码中:

代码语言:javascript
运行
复制
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;
}

我的问题是:

代码语言:javascript
运行
复制
 List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();

我无法用预定义的对象填充当前列表,这将导致没有选项可选的空自旋器。你能告诉我哪里弄错了吗?我还想听听关于如何简化适配器创建的意见。

EN

回答 1

Stack Overflow用户

发布于 2019-01-15 19:18:55

我去派对有点晚了,但万一有人也有这个问题。

问题是,您试图插入没有PrimaryKey id值的新对象。因此,您将在数据库中得到一个空表。

您可以手动设置id值,例如:

代码语言:javascript
运行
复制
@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的PrimaryKey属性让SQLite生成唯一的id:

代码语言:javascript
运行
复制
@PrimaryKey(autoGenerate = true)
private long id;

有关更多信息,请参见参考文献

不需要对代码进行任何其他更改。

回答第二个问题:

我还想听听关于如何简化适配器创建的意见。

您可以为您的旋转器创建一个自定义适配器,并将一个List<Language>直接传递给它:

代码语言:javascript
运行
复制
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;
    }
}

在你的活动中:

代码语言:javascript
运行
复制
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();

Spinner spinner = findViewById(R.id.spinner);
MyAdapter myAdapter = new MyAdapter(this, languages);
spinner.setAdapter(myAdapter);

请参阅BaseAdapterSpinnerAdapter参考。

或者您可以使用ArrayAdapter并简单地重写对象的toString方法,以确定列表(参考文献)中的项将显示什么文本:

代码语言:javascript
运行
复制
@Entity
public class Language {

    ...

    @NonNull
    @Override
    public String toString() {
        // A value you want to be displayed in the spinner item.
        return language;
    }
}

在你的活动中:

代码语言:javascript
运行
复制
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);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49157770

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档