【问题标题】:Need help figuring out an Adapter "tutorial" on Google's Android Developer Site需要帮助找出 Google 的 Android 开发者网站上的适配器“教程”
【发布时间】:2015-12-29 04:55:29
【问题描述】:

我目前正尝试在我的 Android 应用中显示数据库信息。
我希望数据以表格形式显示:

+----------+----------+-----+----------+
| column 1 | column 2 | ... | column n |
+----------+----------+-----+----------+
| xxxx     | xxxx     | ... | nnnn     |
| yyyy     | yyyy     | ... | nnnn     |
| ....     | ....     | ... | nnnn     |
| zzzz     | zzzz     | ... | nnnn     |
+----------+----------+-----+----------+

在查看HERE 的信息时,看来我需要使用带有 SimpleCursorAdapter 的 GridView。

所以,我创建了一个扩展 SQLiteOpenHelper 的 DatabaseHelper 类。在那个类中,我有一个为查询返回游标的方法:

public static final String DATABASE_NAME = "myDatabaseName";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "myDatabaseTableName";

public DatabaseHelper(Context context){
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

public static final String MY_QUERY = "SELECT * FROM " + TABLE_NAME;

public Cursor getDataCursor(){
    SQLiteDatabase sqliteDB = this.getReadableDatabase();
    return sqliteDB.rawQuery(MY_QUERY, null);
}

该 Google Dev 页面上的“教程”部分指出:

例如,如果您要创建人员姓名和电话号码的列表,您可以执行一个查询,该查询返回一个 Cursor,其中包含每个人的行和姓名和号码的列。然后,您创建一个字符串数组,指定您希望在布局中为每个结果使用 Cursor 中的哪些列,并创建一个整数数组,指定每列应放置的相应视图

然后有这个代码:

String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {R.id.display_name, R.id.phone_number};

所以,在我的 MainActivity.java 中,我创建了一个 DatabaseHelper 的新实例,并获得了一个光标:

DatabaseHelper myDBHelper = new DatabaseHelper(this);
Cursor myDataCursor = myDBHelper.getDataCursor();

我不知道的是,谷歌上面的 sn-p 中的“ContactsContract”是什么?我认为这可能是他们的光标,但我的光标没有可用的“数据”或“CommonDataKinds”方法。我浏览了 Google 的 API 指南页面,看看他们在哪里定义了这些方法,但似乎找不到它们。我也不知道他们在同一个例子中从哪里得到“R.layout.person_name_and_number”。

感谢您抽出宝贵时间阅读。

编辑:

我已将此代码添加到我的 MainActivity.java 代码中:

DatabaseHelper myDBHelper = new DatabaseHelper(this);
Cursor myDataCursor = myDBHelper.getDataCursor();
String[] fromColumns = {"_id", "columnA","columnB","...","columnN"};
int[] toViews = {R.id.id_textview, R.id.columnA_textview, R.id.columnB_textview, ... , R.id.columnN_textview};
SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.my_new_layout, myDataCursor, fromColumns, toViews, 0);
ListView myListView = (ListView) findViewById(R.id.row_of_data);
myListView.setAdapter(sca);

我创建了一个名为 my_new_layout.xml 的新视图:

<ListView android:id="@+id/row_of_data">
    <TextView android:id="@+id/id_textview" />
    <TextView android:id="@+id/columnA_textview" />
    <TextView android:id="@+id/columnB_textview" />
    ...
    <TextView android:id="@+id/columnN_textview" />
</ListView>

然后我将新视图添加到 activity_main.xml

<include layout="@layout/"my_new_layout />

但是,现在当我尝试运行应用程序时,我得到了错误:

java.lang.unsupportedoperationexception addview(view, layoutparams) is not supported in adapterview

我得到了这个错误,奇怪的是,我将我的新布局包含在 activity_main.xml 中。

【问题讨论】:

  • 我猜在他们的示例中,他们正在从设备联系人中提取数据。
  • 啊,所以这不是数据库查询,他们说“您可以执行返回光标的查询”?如果没有,您能否为我推荐一个更好的地方来查找有关如何实现我的目标的信息?
  • 您可以使用rawQuery() 填充光标(它允许您编写类似“SELECT [column list] FROM aTable WHERE [condition list]”的内容)

标签: android android-sqlite android-adapter android-gridview android-cursor


【解决方案1】:

查看SimpleCursorAdapterdocumentation 可以看到它的构造函数

public SimpleCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to, int flags)

参数

  • context: 与此 SimpleListItemFactory 关联的 ListView 正在运行的上下文
  • layout:定义此列表项视图的布局文件的资源标识符。布局文件应至少包含“to”中定义的那些命名视图
  • c:数据库游标。如果光标尚不可用,则可以为 null。
  • from:表示要绑定到 UI 的数据的列名列表。如果光标尚不可用,则可以为 null。
  • to:应该在“from”参数中显示列的视图。这些都应该是 TextViews。此列表中的前 N ​​个视图被赋予 from 参数中前 N 列的值。如果光标尚不可用,则可以为 null。
  • flags:用于确定适配器行为的标志,根据 CursorAdapter(Context, Cursor, int)。

fromColumns 是您要从中获取数据的表格列的名称

toViews 是您的 TextViews 的 ID,应该在您的行的 XML 布局内(构造函数中的第二个参数 - int layout)。

两个数组中的项目数应该相同。

【讨论】:

  • 好的,所以我正在创建一个新的布局文件,它代表我要显示的表格的单行。这个对吗?另外,当您说“布局文件应至少包含那些在 'to' 中定义的命名视图”时,您的意思是 android:id="@+id/column_name",那么 column_name 应该与我的数据库查询中的列名匹配吗?
  • 是的,你应该为你的行创建一个新的布局文件,并且那个布局文件应该至少包括那些在'to / toViews array'中定义的命名视图。这些与数据库没有任何共同之处,但 from / fromColumns 中的那些。
  • 好的,我以为我终于用布局正确设置了东西,但现在我收到错误“android java.lang.unsupportedoperationexception addview(view, layoutparams)”。有什么想法吗?
  • 我在“编辑”部分添加了我的新代码。谢谢。
  • 你错了......你的 MainActivity 布局,应该只包含一个 &lt;Listview ... \&gt; 而没有任何 TextViews 里面。这些 TextView 应该在一个单独的 XML 文件中,您将其传递给您的 SimpleCursorAdapter。重新安排您的代码,如果您有任何问题,请告诉我。
【解决方案2】:

首先,您的 SQL 命令不应该是这样的。 "SELECT * FROM MyDatabase";

要么你的表名有误导性,要么你的逻辑有错误。

"SELECT * FROM MyDatabase"; 应该是(逻辑上)"SELECT * FROM MyTable";

这可能是您的光标未返回您所期望的结果的原因。


关于ContactsContract.CommonDataKinds.Phone.NUMBER,它只是一个包含常量的静态类。

以下模式允许您在一个有组织的位置创建一个包含所有字符串的类。

这还可以通过允许 IDE 代码自动完成来帮助您不必“记住”每个变量名称/等。您可以自动完成它们以完成。这有助于集中您的常量,并且只有一个地方需要更改字符串值。

例如(仅列出 1 个值)

public class ContactsContract {
    public class CommonDataKinds {
        public class Phone {
            public static final String NUMBER = "number";
        }
    }    

}

更多信息:

这里是相关文件的 javadoc:

https://developer.android.com/reference/android/provider/ContactsContract.html

这是该文件的源代码(来自 grep 代码):

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.0_r1/android/provider/ContactsContract.java

(如您所见,我上面的代码 sn-p 是正确的,只是我忘记了每个班级 final... 但我很接近)


这是另一个可能更清楚的例子:

我写了这段代码(不是我的仓库...代码在我的博士顾问的仓库中,并在 Coursera 课程中使用 https://www.coursera.org/course/posasoftware

我们的MOOC Schema

A file that uses it(即公开的,学习者不必写)

如您所见,模式类的好处是它允许第二类“利用”模式的内部字符串值,而无需直接处理字符串。这些文件之间仍然存在紧密耦合,但它允许您在一个地方对数据库进行更改(例如修复错字等),而无需遍历整个代码来寻找要替换的字符串。 (也减少了代码中其他地方的拼写错误)。

【讨论】:

  • 你说的很对,我已经纠正了我在原帖中的错误。这是我最初在 StackOverflow 上输入帖子时犯的一个错误。但是,我正在从数据库中获取数据,因为我同时也在填充 List
  • 我已经更详细地解释了联系人“模式”(模式“本质上”是定义底层数据库(及其相关的内容提供者(CP))的“模型” . (从技术上讲,Schema 文件可以/(应该?
猜你喜欢
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2017-06-10
  • 2013-03-31
相关资源
最近更新 更多