Установка элементов после создания 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();
Другие вопросы по тегам