如何知道 Android ListView 何时完成填充

发布于 2024-09-29 02:10:20 字数 1683 浏览 8 评论 0原文

我有一个包含 ListView 的子 Activity。此活动是从 SQLite 游标异步填充的。列表项包含一个 TextView、一个 RadioButton 和一个普通 Button。 XML 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/rlCategoryListItemLayout" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content">
 <TextView android:id="@+id/tvCategoryListItemTitle" style="@style/uwLargeListItemLabelStyle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:singleLine="true" android:text="This is a test note title" />
 <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:gravity="center_vertical">
  <RadioButton android:id="@+id/rdoCategoryListItemSelect" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginRight="10dip" />
  <Button android:id="@+id/btnCategoryListItemDelete" android:background="@drawable/delete_red" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" />
 </LinearLayout>
</RelativeLayout>

我必须执行一些逻辑来确定默认选择哪个 RadioButton,并且在 ListView 已加载之前我无法执行此操作。问题是,对于到目前为止我尝试过的所有事件(onCreate、onPostCreate、onResume、onWindowFocusChanged),ListView 子项计数为零。我还尝试使用 ArrayAdapter 类中的 getView 方法,但该方法被多次调用,并且 ListView 子项计数每次都可能不同,从而导致意外结果。显然,这些事件是在 ListView 完全填充其子项之前触发的。

是否有一个我可以侦听的事件,或者其他某种方式来确定 ListView 何时完成填充并且其所有子项都可以通过编程进行修改?

谢谢你!

I have a child Activity that contains a ListView. This Activity is populated asynchronously from a SQLite cursor. The list items contain a TextView, a RadioButton, and a normal Button. The XML is shown below:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/rlCategoryListItemLayout" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content">
 <TextView android:id="@+id/tvCategoryListItemTitle" style="@style/uwLargeListItemLabelStyle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:singleLine="true" android:text="This is a test note title" />
 <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:gravity="center_vertical">
  <RadioButton android:id="@+id/rdoCategoryListItemSelect" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginRight="10dip" />
  <Button android:id="@+id/btnCategoryListItemDelete" android:background="@drawable/delete_red" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" />
 </LinearLayout>
</RelativeLayout>

I have to do some logic to determine which RadioButton is selected by default, and I can't do it until the ListView is already loaded. The problem is that with all the events I have tried so far (onCreate, onPostCreate, onResume, onWindowFocusChanged), the ListView child count is zero. I've also tried using the getView method in the ArrayAdapter class, but that method is called mutliple times and the ListView child count is potentially different every time, leading to unexpected results. Apparently, these events are firing before the ListView has finished being completely populating with its child items.

Is there an event I can listen for, or some other way to determine when the ListView is finished populating and has all of its children accessible to be modified programmatically?

Thank you!

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

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

发布评论

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

评论(4

靖瑶 2024-10-06 02:10:20

您可以使用处理程序来完成此任务,如下所示:

在您的活动中添加处理程序作为任何其他属性。

private Handler mListViewDidLoadHanlder = new Handler(new Handler.Callback() { 
    @Override
    public boolean handleMessage(Message message) {
        //Do whatever you need here the listview is loaded
        return false;
    }
});

在列表视图适配器的 getView 方法中,您进行比较以查看当前位置是否是最后一个,因此,它将完成(只需将其放在返回之前):

public View getView(int position, View convertView, ViewGroup parent) {
         //Your views logic here

         if (position == mObjects.size() - 1) {
                mViewDidLoadHanlder.sendEmptyMessage(0);
            }

         return convertView;
     }

You can use a Handler to accomplish this task, like this:

In your activity add the Handler as any other property.

private Handler mListViewDidLoadHanlder = new Handler(new Handler.Callback() { 
    @Override
    public boolean handleMessage(Message message) {
        //Do whatever you need here the listview is loaded
        return false;
    }
});

And inside the getView method of your listview adapter you do the comparison to see if the current position is the last one , so , it will finish (just put it before the return):

public View getView(int position, View convertView, ViewGroup parent) {
         //Your views logic here

         if (position == mObjects.size() - 1) {
                mViewDidLoadHanlder.sendEmptyMessage(0);
            }

         return convertView;
     }
城歌 2024-10-06 02:10:20

在数据库上的异步工作结束时,您可以使用 Handler.post(Runnable) 来在主线程上运行代码。

这几乎就像触发一个回调,您可以保证该回调将在填充列表后运行。如果您需要非常仔细地安排所有事情的时间,您可以安排 Runnable 在某个特定时间发生。

我希望这有帮助。

At the end of your asynchronous work on the database, you can use Handler.post(Runnable) to run code back on the main thread.

It's almost like triggering a callback that you can guarantee will run after the list is populated. You can schedule the Runnable to occur at a certain time, if you need to time everything very carefully.

I hope this was helpful.

过度放纵 2024-10-06 02:10:20

ListView 实际上并不为它正在呈现的数据列表中的每个元素创建视图。相反,它会回收视图以便响应而不占用内存。当您说需要填充 ListView 时,您可能会重新考虑您真正需要什么。

如果您更详细地了解您的应用程序并发布一些代码,可能会有所帮助。

A ListView does not actually create a View for each element in the list of data it is rendering. Instead, it recycles views in order to be responsive and not hog memory. You might rethink what you really need when you say the ListView needs to be populated.

It might help if you go into a little more detail about your app and post some code.

冷清清 2024-10-06 02:10:20

您可以在您的活动中添加一个字符串变量(例如public static String END_LOAD)并在您的 getView 方法(在适配器中)中设置值,然后在您的活动中,之后

ListView listView = (ListView) findViewById(R.id.recordListView);
        listView.setAdapter(adapter);

您可以添加一个简单的线程将检查 END_LOAD 变量:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        while (END_LOAD == null || END_LOAD .equals("") ) { // your conditions
        }
        createReadRequest(); // your task to execute
    }
};

new Thread(runnable).start();

添加一个您可能感兴趣的简单条件,然后当条件为 false 时,因为 getView 方法已完成,现在您可以执行您的特定过程。

You can add a string variable in your activity (e.g. public static String END_LOAD) and set the value in your getView method (in the adapter), then in your activity, after

ListView listView = (ListView) findViewById(R.id.recordListView);
        listView.setAdapter(adapter);

You can add a simple thread that will be check the END_LOAD variable:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        while (END_LOAD == null || END_LOAD .equals("") ) { // your conditions
        }
        createReadRequest(); // your task to execute
    }
};

new Thread(runnable).start();

Add a simple condition that can be interesting for you, then when the condition will be false is because the getView method is done, now you can do your specific process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文