从 ListAdapter 或 SimpleCursorAdapter 填充列表视图

发布于 2024-12-14 06:44:31 字数 501 浏览 4 评论 0原文

我正在制作一个新的 Android 应用程序,它基本上反映了我们网站上可用的数据。 GUI 将显示每个项目中包含图像和文本的 ListView,或显示单个项目详细信息的 RelativeLayout

为了提高此应用程序的响应能力,如果数据足够新,我想从内部数据库读取数据,如果内部数据太旧,我想从服务器的 API(JSON over http)读取数据(然后填充包含新数据的内部数据库)。

从基本教程来看,从内部数据库读取数据时似乎应该使用数据库和 SimpleCursorAdapter (*)。但是当从网络上读取时,我想我会使用 ArrayList 和 ArrayAdapter。

是否有某种类型的适配器可以处理这两种情况?

(*) 我知道最新的事情是将 LoaderManager 与 CursorLoader 一起使用,但我正在尝试支持 Android 2.1。我想我可以将 SimpleCursorAdapter 放入 AsyncTask 中并避免 ANR。

I'm making a new Android app that essentially mirrors data available on our website. The GUI will show either a ListView with images and text in each item, or a RelativeLayout that will display details of a single item.

In order to increase responsiveness in this app, I'd like to read data from the internal DB if the data is recent enough, and read data from the server's API (JSON over http) if the internal data is too old (and then populate the internal DB with the new data).

From the basic tutorials, it seems that one should use the DB and SimpleCursorAdapter (*) when reading from the internal DB. But when reading from the web, I guess I'd be using an ArrayList and ArrayAdapter.

Is there some type of Adapter that can handle both situations?

(*) I know the latest thing is to use LoaderManager with a CursorLoader, but I'm trying to support Android 2.1. I figure I can put the SimpleCursorAdapter into an AsyncTask and avoid ANR.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨曦慕雪 2024-12-21 06:44:31

当然,您可以使用 SimpleCursorAdapterAsyncTask。但是通过 Android 兼容包,您可以开始使用 CursorLoader Android 1.6 的 API。 Loader API 使管理游标的生​​命周期变得更加容易。

我建议使用 CursorLoader API 从 ContentProvider 或数据库检索 Cursor。并使用 AsyncTask (或 AsyncLoader 的自定义实现)从服务器获取数据并更新 ContentProvider

如果您为每个任务(加载光标和更新数据)使用两个不同的AsyncTasks(或Loaders),您可以使您的ListView自动更新,如果数据库中的数据已更改。

为此,请在从数据库检索的 Cursor 上设置通知 Uri

cursor.setNotificationUri(getContentResplver(), Uri.parseString("mydata://someuri"));

如果您已更新数据,请为该 Uri 发送通知代码>:

getContentResolver().notifyChange(Uri.parseString("mydata://someuri"), null);

Of course you can use a SimpleCursorAdapter and an AsyncTask. But with the Android Compatibility Package you can start using the CursorLoader API with Android 1.6. The Loader API makes it easier to manage the lifecycle of the Cursors.

I would suggest using the CursorLoader API to retrieve a Cursor from a ContentProvider or a database. And use an AsyncTask (or a custom implementation of AsyncLoader) to fetch the Data from the server and update ContentProvider.

If you use two different AsyncTasks (or Loaders) for each task (loading cursor and updating data) you can make your ListView update itself automatically if the data in the db has changed.

To do so set a notification Uri on the Cursor that you retrieved from the db:

cursor.setNotificationUri(getContentResplver(), Uri.parseString("mydata://someuri"));

And if you have updated the data, send a notification for that Uri:

getContentResolver().notifyChange(Uri.parseString("mydata://someuri"), null);
泅人 2024-12-21 06:44:31

我认为您可以编写一个自定义适配器,扩展 BaseAdapter 类并将其用于这两种情况。

在扩展 BaseAdapter 的类中,您将有一个 List,其中 DataEntry 是 Java POJO 类,表示来自 Web 或 db 的数据(假设它们具有相同的属性)。假设您已经使用 DataEntry 对象填充了 List,并且已经包含数据,您可以执行以下操作:

1) 在扩展 BaseAdapter 的类的 getView() 方法中,在 inflate 中,您将使用 xml 布局,它基本上代表 1 个数据行。假设您将通过 TextView 显示数据,则 1 个数据行布局将具有与 DataEntry 对象的数据字段数量一样多的 TextView 元素。膨胀后,您将值放入 TextView 中,如下所示:

    TextView someTextViewToDisplayField = (TextView) convertView.findViewById(R.id.yourID);
    someTextViewToDisplayField.setText(String.valueOf(dataEntry.getWhateverProperty()));

2)在更新布局中的 UI 的过程中,您应该有一个 ListView ,如下所示:

    <ListView android:id="@+id/YourListViewID" android:layout_width="fill_parent"
    android:layout_height="wrap_content"></ListView>

然后初始化扩展 BaseAdapter 的类,

   ListView listView = (ListView) findViewById(R.id.YourListViewID); 

   YourClassExtendingBaseAdapter adapter = 
            new YourClassExtendingBaseAdapter(this, listOfEntryDataObjects);

    listView.setAdapter(adapter);   

listOfEntryDataObjects 为 ListDataEntry> 已填充数据。构造函数中的“this”是与当前 Activity 关联的上下文,您可以从中进行调用。

扩展BaseAdapter的类的结构:

public class YourClassExtendingBaseAdapter extends BaseAdapter { 

    private Context context;
    private List<DataEntry> entries;

public YourClassExtendingBaseAdapter(Context context,
        List<DataEntry> entries) {
    this.context = context;
    this.entries = entries;
}
  // Overwriting necessary methods 
} 

I think you can write a custom Adapter, extending BaseAdapter class and use it for both cases.

In your class, that extends BaseAdapter, you will have a List<DataEntry>, where DataEntry is Java POJO class, representing the data coming from web or db (assuming it has the same properties). Assuming you have populated the List<DataEntry> with DataEntry objects, already containing data you can do as follows:

1) In the getView() method of the class that extends BaseAdapter, in the inflate, you will use an xml layout, that's basically represents 1 data row. Assuming you will display data via TextView, the 1 data row layout will have as many TextView elemnts, as the number of data-fields of your DataEntry object. After the inflate, you put values in the TextViews like:

    TextView someTextViewToDisplayField = (TextView) convertView.findViewById(R.id.yourID);
    someTextViewToDisplayField.setText(String.valueOf(dataEntry.getWhateverProperty()));

2) in the process where you update the UI in your layout you should have a ListView like:

    <ListView android:id="@+id/YourListViewID" android:layout_width="fill_parent"
    android:layout_height="wrap_content"></ListView>

and after that you initialize your class that extends BaseAdapter

   ListView listView = (ListView) findViewById(R.id.YourListViewID); 

   YourClassExtendingBaseAdapter adapter = 
            new YourClassExtendingBaseAdapter(this, listOfEntryDataObjects);

    listView.setAdapter(adapter);   

the listOfEntryDataObjects is List<DataEntry> already populated with data. The 'this' in the constructor is the context associated with the current Activity, you make the call from.

Structure of class that extends BaseAdapter:

public class YourClassExtendingBaseAdapter extends BaseAdapter { 

    private Context context;
    private List<DataEntry> entries;

public YourClassExtendingBaseAdapter(Context context,
        List<DataEntry> entries) {
    this.context = context;
    this.entries = entries;
}
  // Overwriting necessary methods 
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文