Установка элементов после создания ArrayAdapter?
В моем приложении я показываю список элементов, загруженных из Интернета (типа pItem
). Я использую пользовательский ArrayAdapter, который расширяет ArrayAdapter<pItem>
что в основном так:
public class PArrayAdapter extends ArrayAdapter<pItem> {
private List<pItem> pList = new ArrayList<pItem>();
public PArrayAdapter(Context context) {
super(context, R.layout.p_row);
this.context = context;
}
public void SetList(List<PItem> pl){
pList = pl;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = convertView;
if (rowView == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
rowView = vi.inflate(R.layout.p_row, null);
}
// ...
return rowView;
}
}
Теперь, обычно при создании пользовательского ArrayAdapter, список элементов устанавливается в конструкторе. Но в моем случае, когда я динамически выбираю элементы в AsyncTask
(список постоянно меняется), я отделил настройку пунктов созданием адаптера.
В своей основной деятельности это то, что я делаю: (только основная часть кода)
public class MainPageActivity extends SherlockFragmentActivity implements
OnScrollListener {
// List of items
private List<pItem> pList = new ArrayList<pItem>();
// Adapter
private arrayAdapter pAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_page);
//...
listView = (ListView) findViewById(R.id.p_list);
adpater = new PArrayAdapter(getApplicationContext());
new ASTask().execute("");
}
private class ASTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... args) {
// Add the downloaded items to list
pList.addAll(Downloader.GetItems());
return "";
}
@Override
protected void onPostExecute(String result) {
Log.d("Main", String.valueOf(pList.size())); // Shows the right number
// Show Items
pAdapter.setList(pList);
listView.setAdapter(pAdapter);
Handler mHandler = new Handler(Looper.getMainLooper());
Runnable rn = new Runnable() {
@Override
public void run() {
pAdapter.notifyDataSetChanged();
}
};
mHandler.post(rn);
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
}
}
Вот проблема: когда я запускаю его, ничего не отображается в listView. Это не дает никаких ошибок.
Но если я установлю список в конструкторе PArrayAdapter
, все работает отлично, и я вижу элементы.
Что я здесь не так делаю?
3 ответа
ХОРОШО. Я нашел то, что было моей проблемой. Это была ошибка новичка:
Вместо назначения списка ввода списку внутри адаптера:
pList = pl;
Я должен был добавить все элементы, как это:
pList.addAll(pl);
Это решило проблему.
Добавлять pAdapter.notifyDataSetChanged();
в конце метода onPostExecute().
Попробуйте вот так:
@Override
protected void onPostExecute(String result) {
Log.d("Main", String.valueOf(pList.size())); // Shows the right number
// Show Items
pAdapter.setList(pList);
listView.setAdapter(pAdapter);
pAdapter.notifyDataSetChanged();
}
В onPostExecute
удалить этот код
Handler mHandler = new Handler(Looper.getMainLooper());
Runnable rn = new Runnable() {
@Override
public void run() {
pAdapter.notifyDataSetChanged();
}
};
mHandler.post(rn);
добавить только эту строку
pAdapter.notifyDataSetChanged();