Android:适配器的viewconvert为null,但我通过了正确的布局

时间:2018-11-01 16:44:36

标签: android listview android-arrayadapter

摘要

首先,我将解释问题的目的和背景。然后,我将为您提供一些有关如何实现此功能的概述。我将再次给您一些解释的代码。最后,我将向您展示输出的Java异常,并清楚地询问您我的问题。


目标与背景

由于使用了一些区分功能的REST API,我从网上得到了一些消息。我想在片段的ListView中显示每个新闻。

实施

说明

  1. 我创建了对新闻进行建模的布局。它包含一个用于托管新闻图片的ImageView和一些用于托管标题,描述等的TextView

  2. 我创建了ArrayAdapter,它重新使用了此布局并填充了其小部件。

  3. 我设置了REST API调用,以在JSONArray中获取JSONObject。后者将转换为新闻对象列表。 ArrayAdapter使用此列表(请参阅2。)。

来源

ArrayAdapter

NB:在下面的代码中,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

NB:在下面的代码中,R.layout.world_news_list_item(是对新闻进行建模的布局)将在ArrayAdapter的构造函数中使用(见上文)。

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

(在HTTP成功(和响应成功)的情况下,写在API REST调用的回调中)。

片段的布局包含一个ListView,它被夸大为list_view


输出异常和问题

输出异常

当我启动包含ListView的片段时,将输出此异常:

  

E / Android运行时:致命异常:主要       流程: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(Choreographer.java:911)           在android.view.Choreographer.doCallbacks(Choreographer.java:723)           在android.view.Choreographer.doFrame(Choreographer.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_item(在ArrayAdapter中),这是对新闻进行建模的布局,所以convertView {{1}为什么}(也在null中)?

换句话说:为什么我必须写类似ArrayAdapter的东西?

1 个答案:

答案 0 :(得分:2)

您需要自己为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在android中都是这样,这就是它们的力量。您可以使用自己的布局自定义每一行。请记住,在您的情况下,您已经覆盖了getView,因此您需要按照here所述自己进行布局创建。另外,您也可以检查here是否使用各种适配器。 here也可以找到另一本很棒的ListView教程。

建议:

学习使用RecyclerView。它更复杂,但是比简单的ListView强大得多。