开发者

How to know when an Android ListView is done being populated

开发者 https://www.devze.com 2023-01-22 21:47 出处:网络
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 show

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 call开发者_StackOverflow社区ed 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!


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;
     }


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消