Android: viewconvert адаптера имеет значение null, но я передал правильное расположение - PullRequest
0 голосов
/ 01 ноября 2018

Резюме

Сначала я объясню цель и контекст моей проблемы. Затем я дам вам некоторые общие сведения о том, как я реализовал эту функцию. Я дам вам код с некоторыми пояснениями. Наконец, я покажу вам выходное исключение Java и четко задам мой вопрос.


Цель и контекст

Я получил некоторые новости из Интернета благодаря API REST, использующему некоторые отличительные особенности. Я хочу отображать каждую новость в моем фрагменте ListView.

Осуществление

Пояснения

  1. Я создал макет, который моделирует новости. Он содержит ImageView, который будет содержать изображение новостей, и некоторые TextView, которые будут содержать заголовок, описание и т. Д.

  2. Я создал ArrayAdapter, который использует этот макет и заполняет его виджеты.

  3. Я настроил вызов API REST для получения JSONObject в JSONArray. Последний преобразуется в список новостных объектов. Этот список используется ArrayAdapter (см. 2.).

Источники

ArrayAdapter

Примечание: в приведенном ниже коде значение resource установлено на R.layout.world_news_list_item, то есть макет, который моделирует новости.

public class NewsAdapter extends ArrayAdapter<News> {
    private List<News> news;

    NewsAdapter(@NonNull Context context, int resource, @NonNull List<News> objects) {
        super(context, resource, objects);
        this.news = objects;
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {

        News news = this.news.get(position);

        TextView textTitle = convertView.findViewById(R.id.world_news_item_title);
        textTitle.setText(news.getTitle());

        return convertView;
    }

}

Часть фрагмента: установка ArrayAdapter для фрагмента ListView

Примечание: в приведенном ниже коде R.layout.world_news_list_item, который является макетом, который моделирует новости, будет использоваться в конструкторе ArrayAdapter (см. Ранее).

list_view.setAdapter(new NewsAdapter(context, R.layout.world_news_list_item, News.toArrayList(news)));

(записывается в обратном вызове вызова API REST в случае успеха HTTP (и ответа)).

Макет фрагмента содержит ListView, который раздувается до list_view.


Выходное исключение и вопрос

Исключение на выходе

Когда я запускаю фрагмент, содержащий ListView, выводится следующее исключение:

E / AndroidRuntime: FATAL EXCEPTION: main Процесс: com.example.xxx.xxx, PID: 31843 java.lang.NullPointerException: попытка вызвать виртуальный метод 'android.view.View android.view.View.findViewById (int)' для ссылки на пустой объект на com.example.xxx.xxx.NewsAdapter.getView (NewsAdapter.java:25) на android.widget.AbsListView.obtainView (AbsListView.java:3189) на android.widget.ListView.makeAndAddView (ListView.java:2197) на android.widget.ListView.fillDown (ListView.java:824) на android.widget.ListView.fillFromTop (ListView.java:885) на android.widget.ListView.layoutChildren (ListView.java:1952) на android.widget.AbsListView.onLayout (AbsListView.java:2961) на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.support.constraint.ConstraintLayout.onLayout (ConstraintLayout.java:1915) на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.widget.FrameLayout.layoutChildren (FrameLayout.java:323) на android.widget.FrameLayout.onLayout (FrameLayout.java:261) на android.widget.ScrollView.onLayout (ScrollView.java:2492) на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.support.v4.widget.DrawerLayout.onLayout (DrawerLayout.java:1171) на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.widget.FrameLayout.layoutChildren (FrameLayout.java:323) на android.widget.FrameLayout.onLayout (FrameLayout.java:261) на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.widget.LinearLayout.setChildFrame (LinearLayout.java:1791) на android.widget.LinearLayout.layoutVertical (LinearLayout.java:1635) на android.widget.LinearLayout.onLayout (LinearLayout.java:1544)на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.widget.FrameLayout.layoutChildren (FrameLayout.java:323) на android.widget.FrameLayout.onLayout (FrameLayout.java:261) на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.widget.LinearLayout.setChildFrame (LinearLayout.java:1791) на android.widget.LinearLayout.layoutVertical (LinearLayout.java:1635) на android.widget.LinearLayout.onLayout (LinearLayout.java:1544) на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.widget.FrameLayout.layoutChildren (FrameLayout.java:323) на android.widget.FrameLayout.onLayout (FrameLayout.java:261) на com.android.internal.policy.DecorView.onLayout (DecorView.java:945) на android.view.View.layout (View.java:20854) на android.view.ViewGroup.layout (ViewGroup.java:6401) на android.view.ViewRootImpl.performLayout (ViewRootImpl.java:2919) на android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2606) на android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1743) на android.view.ViewRootImpl $ TraversalRunnable.run (ViewRootImpl.java:7780) на android.view.Choreographer $ CallbackRecord.run (Хореограф.java:911) на android.view.Choreographer.doCallbacks (Choreographer.java:723) на android.view.Choreographer.doFrame (Хореограф.java:658) на android.view.Choreographer $ FrameDisplayEventReceiver.run (Choreographer.java:897) на android.os.Handler.handleCallback (Handler.java:789) на android.os.Handler.dispatchMessage (Handler.java:98) на android.os.Looper.loop (Looper.java:164) на android.app.ActivityThread.main (ActivityThread.java:6944) в java.lang.reflect.Method.invoke (родной метод) на com.android.internal.os.Zygote $ MethodAndArgsCaller.run (Zygote.java:327) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)

Вопрос

Поскольку для resource установлено значение R.layout.world_news_list_itemArrayAdapter), то есть макет, который моделирует новости, почему convertView null (также в ArrayAdapter)?

Другими словами: почему я должен писать что-то вроде if(convertView == null) { inflate_world_news_list_item_layout(); }?

1 Ответ

0 голосов
/ 01 ноября 2018

Вам нужно накачать просмотров строк из ListView самостоятельно. Вот почему вам нужен такой код:

public class NewsAdapter extends ArrayAdapter<News> {
    private List<News> news;

    NewsAdapter(@NonNull Context context, int resource, @NonNull List<News> objects) {
        super(context, resource, objects);
        this.news = objects;
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        if (convertView == null) {
            convertView = getLayoutInflater().inflate(R.layout.list_item, container, false);
        }

        News news = this.news.get(position);

        TextView textTitle = convertView.findViewById(R.id.world_news_item_title);
        textTitle.setText(news.getTitle());

        return convertView;
    }

}

Все ListView s такие же в андроиде, и это их сила. Вы можете настроить каждую строку с вашим собственным макетом. Помните, что в вашем случае вы переопределили getView, поэтому вам нужно сделать создание макета самостоятельно, как указано здесь . Кроме того, вы можете также проверить здесь для использования различных адаптеров. Еще один замечательный учебник ListView можно найти здесь .

Предложение:

Научитесь использовать RecyclerView. Это сложнее, но гораздо мощнее простого ListView.

...