【问题标题】:Populate ListView with SQLite, Images and Text from local resources使用本地资源中的 SQLite、图像和文本填充 ListView
【发布时间】:2015-06-02 22:43:37
【问题描述】:

我有一个 ListView,它能够为每个 ListViewItem 显示两个 TextView 和一个 ImageView。我还有一个 SQLite 数据库,其中包含以下字段:_idnamedescriptionimage

示例记录如下: 1,R.string.name1,R.string.description1,R.drawable.image1

名称和描述的字符串在strings.xml文件中,所需的图像在res/drawable文件夹中,通常会被R.drawable.image_name引用

我正在使用 SQLiteAssetHelper 库来管理数据库。

我能够获得一个包含所有所需信息的光标,并且我能够使用文本填充列表视图,但是当我运行应用程序时,文本视图显示为 R.string.name1R.string.description1 等。我还不能让图像工作。

如何使文本正确显示(以便将来可以使用不同的语言)以及如何显示图像?

到目前为止,这是我的代码:

数据库助手

    public class Database extends SQLiteAssetHelper {

        private static final String DATABASE_NAME = "database.sqlite";
        private static final int DATABASE_VERSION = 1;

        public Database(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            setForcedUpgrade();
        }
        public Cursor getList() {

            SQLiteDatabase db = getReadableDatabase();
            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

            String [] sqlSelect = {"_id","name","description","image"};
            String sqlTables = "tbl_list";
            qb.setTables(sqlTables);
            Cursor c = qb.query(db, sqlSelect, null, null,
                    null, null, null);

            c.moveToFirst();
            return c;

        }
    }

主要活动

public class SQLite_List extends ActionBarActivity {
    private ListView listView1;
    private Cursor list;
    private Database db;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.listview);
        getSupportActionBar().setTitle("List");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        db = new Database(this);
        list = db.getList(); //Move this to its own thread later on

        ListAdapter adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_2,
                mods,
                new String[] {"name","description"}, //table values
                new int[] {android.R.id.text1,android.R.id.text2});

        listView1 = (ListView) findViewById(R.id.listview);
        listView1.setAdapter(adapter);
        }
...
}

谢谢

编辑:我已经写了一个新的适配器,但图像仍然无法正常工作:

public class SQLite_Adapter extends ResourceCursorAdapter {

    public SQLite_Mods_Adapter(Context context, int layout, Cursor c, int flags) {
        super(context, layout, c, flags);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        TextView name = (TextView) view.findViewById(R.id.txtTitle);
        name.setText(cursor.getString(cursor.getColumnIndex("name")));

        TextView description = (TextView) view.findViewById(R.id.txtDescription);
        description.setText(cursor.getString(cursor.getColumnIndex("description")));

        ImageView image = (ImageView) view.findViewById(R.id.imgIcon);
        image.setImageResource(context.getResources().getIdentifier("image","drawable","com.package"));
    }

}

编辑 2: 我找到了解决方案。答案贴在下面。

【问题讨论】:

  • 您可以使用reflection 从资源名称中获取值。然后在这种情况下,您甚至可以not use a custom row layout 并将图像合并到 TextView 中(使其成为compound drawable)。
  • 我将研究反射,并且我已经实现了自定义行布局、ViewBinder 和new String[]{"name","description","image"},并将图像视图 ID 放入“to”int[]。文本在自定义布局中有效,但图像不显示。 Logcat 显示 R.drawable.image 的 URI 无效
  • 这就是反射派上用场的地方:对反射类型使用“drawable”。
  • @DerGolem 我用一个新的适配器编辑了我的帖子,我尝试了一些方法来让图像工作,但它们根本不起作用。如果你能看一看,将不胜感激。谢谢
  • 我知道了,答案将很快发布在下面。感谢您为我指明正确的方向@DerGolem

标签: android sqlite android-listview


【解决方案1】:

好的,我得到了这个工作,而不是使用 SimpleCursorAdapter,使用自定义适配器。代码可以在下面找到。

然后您使用getIdentifier 方法将图像或字符串的名称转换为可用于TextView 上的setText 或ImageView 上的setImageResource 的整数:

public class SQLite_ListView_Adapter extends ResourceCursorAdapter {

    public SQLite_ListView_Adapter(Context context, int layout, Cursor c, int flags) {
        super(context, layout, c, flags);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
       TextView name = (TextView) view.findViewById(R.id.txtTitle);
       String name_string=cursor.getString(cursor.getColumnIndex("name"));
       int resIdName = context.getResources().getIdentifier(name_string, "string", context.getPackageName());
       name.setText(resIdName);

       TextView description = (TextView) view.findViewById(R.id.txtDescription);
       String description_string = cursor.getString(cursor.getColumnIndex("description"));
       int resIdDescription = context.getResources().getIdentifier(description_string, "string", context.getPackageName());
       description.setText(resIdDescription);

       ImageView image = (ImageView) view.findViewById(R.id.imgIcon);
       String image_string = cursor.getString(cursor.getColumnIndex("image"));
       int resId=context.getResources().getIdentifier(image_string, "drawable", context.getPackageName());
       image.setImageResource(resId);
    }

}

因此,如果您有字符串 R.string.name1 并且您希望它显示在 TextView 中,那么在数据库中记录的名称字段中,您只需要 name1 与drawables和您可能需要的任何其他类似的想法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 2018-11-22
    • 2020-09-24
    相关资源
    最近更新 更多