Как узнать, когда заполняется Android ListView
У меня есть дочерняя активность, которая содержит 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, но этот метод называется mutliple times, и подсчет дочерних элементов ListView потенциально различается каждый раз, что приводит к неожиданным результатам. По-видимому, эти события увольняются до того, как ListView закончил полностью заполнять свои дочерние элементы.
Есть ли какое-нибудь событие, которое я могу прослушать, или какой-либо другой способ определить, когда ListView закончен, и все его дети доступны для программной модификации?
Спасибо!
Ответы
Ответ 1
Вы можете использовать обработчик для выполнения этой задачи, например:
В вашей деятельности добавьте обработчик как любое другое свойство.
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 вашего адаптера listview вы сравниваете это, чтобы увидеть, является ли текущая позиция последней, и, таким образом, она закончится (просто поставьте ее перед возвратом):
public View getView(int position, View convertView, ViewGroup parent) {
//Your views logic here
if (position == mObjects.size() - 1) {
mViewDidLoadHanlder.sendEmptyMessage(0);
}
return convertView;
}
Ответ 2
В конце вашей асинхронной работы с базой данных вы можете использовать Handler.post(Runnable)
для запуска кода обратно в главном потоке.
Это почти как запуск обратного вызова, который, как вы можете гарантировать, будет запущен после заполнения списка. Вы можете запланировать запуск Runnable в определенное время, если вам нужно все очень тщательно рассчитать.
Я надеюсь, что это было полезно.
Ответ 3
ListView фактически не создает представление для каждого элемента в списке данных, которые он выполняет. Вместо этого он перерабатывает представления, чтобы быть отзывчивыми, а не память. Вы можете переосмыслить то, что вам действительно нужно, когда вы говорите, что ListView нужно заполнить.
Это может помочь, если вы расскажете немного о своем приложении и разместите код.
Ответ 4
Вы можете добавить строковую переменную в свою активность (например, 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 сделан, теперь вы можете выполнить свой конкретный процесс.