Как узнать, когда Android ListView будет заполнен - PullRequest
13 голосов
/ 28 октября 2010

У меня есть дочерняя активность, которая содержит ListView. Это действие заполняется асинхронно из курсора SQLite. Элементы списка содержат TextView, RadioButton и обычную кнопку. 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 равно нулю. Я также пытался использовать метод getView в классе ArrayAdapter, но этот метод вызывается по нескольку раз, и число дочерних элементов ListView потенциально каждый раз меняется, что приводит к неожиданным результатам. По-видимому, эти события срабатывают до того, как ListView полностью заполнится дочерними элементами.

Есть ли событие, которое я могу прослушать, или каким-либо другим способом определить, когда заполнение ListView завершено и все ли его дочерние элементы доступны для изменения программным способом?

Спасибо!

Ответы [ 4 ]

6 голосов
/ 05 октября 2014

Вы можете использовать обработчик для выполнения этой задачи, например:

В своей деятельности добавьте обработчик как любое другое свойство.

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;
     }
2 голосов
/ 28 октября 2010

В конце вашей асинхронной работы с базой данных вы можете использовать Handler.post(Runnable) для запуска кода в главном потоке.

Это почти как запуск обратного вызова, который, как вы можете гарантировать, будет запущен после заполнения списка.Вы можете запланировать запуск Runnable в определенное время, если вам нужно все очень тщательно рассчитать.

Надеюсь, это было полезно.

1 голос
/ 28 октября 2010

ListView фактически не создает View для каждого элемента в списке данных, которые он отображает.Вместо этого, он перерабатывает представления, чтобы быть отзывчивым, а не забирать память.Вы можете переосмыслить то, что вам действительно нужно, когда говорите, что ListView должен быть заполнен.

Это может помочь, если вы немного подробнее расскажете о своем приложении и опубликуете некоторый код.

0 голосов
/ 15 февраля 2014

Вы можете добавить строковую переменную в свою деятельность (например, 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();

Добавьте простое условие, которое может вас заинтересовать, тогда, когда условие будет ложным, потому что метод getView завершен, теперь вы можете выполнять свой конкретный процесс.

...