java - 如何使用 ImageView 将现有 sqlite 数据库中的数据填充到 ListView

标签 java android

我正在寻找一种方法,将我之前使用“数据库浏览器”创建的现有 sqlite 数据库中的数据显示到 ListView 中。在数据库中,有一个 Logo /图像(Blob)列,我想将其输入到 ListView 中。我怎样才能做到这一点?

我从网上得到了下面的代码,但不幸的是这个方法不能显示图像,只能显示一行中的两行。

这是我的 main_activity 更改为 Home_Act..

    public class Home_Act extends AppCompatActivity {

        static final String DBNAME = "testing.db";
        static final String DBASSETPATH = "databases/" + DBNAME;
        static final String CHANNELTABLE = "Channel_Info";
        static final String KEY_NO = "No";
        static final String KEY_NAME = "Name";
        static final String KEY_CATEGORY = "Category";
        static final String KEY_LOGO = "Logo";

        ListView channelList;
        SQLiteDatabase mDB;
        SimpleCursorAdapter mSCA;
        Cursor mCsr;

        @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.act_home);

    channelList = this.findViewById(R.id.channelList);
    mDB = openDB();



    if (mDB != null) {
        mCsr = mDB.query(CHANNELTABLE,
                new String[]{KEY_NO + " AS _id",
                        KEY_NAME, KEY_CATEGORY, KEY_LOGO
                },
                null,null,null,null,null);
        mSCA = new SimpleCursorAdapter(this,R.layout.mylist,mCsr,
                new String[]{KEY_NAME, KEY_CATEGORY, KEY_LOGO},
                new int[]{R.id.item, R.id.textView1, R.id.icon},0);

        mSCA.setViewBinder(new SimpleCursorAdapter.ViewBinder(){
            // Binds the Cursor column defined by the specified index to the specified view
            public boolean setViewValue(View view, Cursor cursor, int columnIndex){
                if(view.getId() == R.id.icon){
                    //...
                    String channelName = cursor.getString(3);
                    Home_Act.this.getResources();
                    int resID = getResources().getIdentifier(channelName, "drawable", getPackageName());

                    //Option 1
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
                        ((ImageView)view).setImageDrawable(getResources().getDrawable(resID, getApplicationContext().getTheme()));
                    } else {
                        ((ImageView)view).setImageDrawable(getResources().getDrawable(resID));
                    }

                    //Option 2
                    //((ImageView)view).setImageDrawable(getResources().getDrawable(resID));

                    return true; //true because the data was bound to the view
                }
                return false;

            }
        });

        channelList.setAdapter(mSCA);
    } else {
        Toast.makeText(this,"Unable to open Database.",Toast.LENGTH_LONG);
    }

    channelList.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
            // TODO Auto-generated method stub
            String Slecteditem = itemname[+position];
            channelName = Slecteditem;
            OpenDialog();
            //Toast.makeText(getApplicationContext(), Slecteditem, Toast.LENGTH_SHORT).show();

        }
    });
}

private SQLiteDatabase openDB() {
    String dbpath = this.getDatabasePath(DBNAME).getPath();
    if (this.getDatabasePath(DBNAME).exists()) {
        Log.d("OPENDB","Opening already existing Database");
        return SQLiteDatabase.openDatabase(dbpath,null,SQLiteDatabase.OPEN_READWRITE);
    }
    InputStream is;
    byte[] buffer;
    FileOutputStream db;
    try {
        is =  this.getAssets().open(DBASSETPATH);
        buffer = new byte[is.available()];
        is.read(buffer);
        is.close();
    } catch (Exception e) {
        e.printStackTrace();
        Log.d("OPENDB","Unable to locate or buffer input from assets " + DBASSETPATH);
        return null;
    }
    // Just in case the databases directory doesn't exist create it.
    File dbmkdir = (this.getDatabasePath(DBNAME)).getParentFile();
    dbmkdir.mkdirs();
    try {
        db = new FileOutputStream(this.getDatabasePath(DBNAME).getPath());
    } catch (Exception e) {
        e.printStackTrace();
        Log.d("OPENDB","Unable to create outputstream for DB at path " + dbpath);
        try {
            is.close();
        } catch (Exception e2) {
        }
        return null;
    }
    try {
        db.write(buffer);
        db.flush();
        db.close();
        is.close();
    } catch (Exception e) {
        Log.d("OPENDB","Failed to copy asset to DB");
        e.printStackTrace();
        return null;
    }
    return SQLiteDatabase.openDatabase(dbpath,null,SQLiteDatabase.OPEN_READWRITE);
}

上面的代码只显示 1 行中的 2 行,我想包括左侧的图像。

这是使用上面的代码,图像未显示并且没有错误。

enter image description here

这就是我想要的。

enter image description here

编辑:

现在它可以按我想要的方式工作了。 第一,你必须有自己的布局,其中包括 2 个 TextView 和 1 个 ImageView。 .xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="100dp"
        android:layout_height="60dp"
        android:padding="5dp" />

    <LinearLayout android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="5dp"
            android:padding="2dp"
            android:textColor="#33CC33" />
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:layout_marginLeft="10dp"/>
    </LinearLayout>
</LinearLayout>

第二,遵循上面的代码。

最佳答案

SimpleCursorAdapter 不支持 to 中的图像。在你的代码中

new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, mCsr,
                    new String[]{KEY_NAME, KEY_CATEGORY, KEY_LOGO},
                    new int[]{android.R.id.text1, android.R.id.text2}, 0);

您正在将 3 列传递给 2 个 TextView ,这些 TextView 毫无异常(exception)地显示在 UI 中。如果您想显示图像+ TextView ,您需要创建自己的自定义适配器。

或者尝试如下设置:

mSCA.setViewBinder(new SimpleCursorAdapter.ViewBinder(){
   /** Binds the Cursor column defined by the specified index to the specified view */
   public boolean setViewValue(View view, Cursor cursor, int columnIndex){
       if(view.getId() == R.id.your_image_view_id){
           String yourImageNameFromDb = cursor.getString(2);
           int resID = getResources().getIdentifier(yourImageNameFromDb , "drawable", getPackageName());

          ((ImageView)view).setImageDrawable(getResources().getDrawable(resID));
           return true; //true because the data was bound to the view
       }
       return false;
   }
});

关于java - 如何使用 ImageView 将现有 sqlite 数据库中的数据填充到 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58708785/

相关文章:

java - 使用 Java 将模拟的 Windows 键盘事件发送到使用 SDL 的 C 程序

java - 如何使用 Wss4jSecurityInterceptor/Spring WS 将时间戳添加到签名

java - 包括库,同时避免使用您的代码的代码发生冲突

android - 在 ActionBarSherlock 中使用选择器突出显示选定的列表项

java - 如何从文件路径中获取文件所在的文件夹路径?

android - 模拟 java.lang.AssertionError : Verification failed: call 1 of 1: was not called

java - 写入 System.out 或 .err 时测试失败

java - 使用 bouncycaSTLe 计算 SHA3 哈希值 - `error: cannot find symbol`

java - Android 使用 2 个不同的 ArrayList 填充相同的自定义 ListView 布局

Android EditText OnClickListener 问题