当ListView适配器为空时,片段无法打开并崩溃

时间:2016-12-16 14:50:55

标签: java android listview android-fragments nullpointerexception

当我的arraylist中没有项目时,CollectionsFragment无法打开并崩溃我的应用程序。

只有在已经添加了对象的情况下才能访问CollectionsFragment。

package fragments;

/*Imports*/

public class CollectionsFragment extends Fragment {

private static List<Article> mArticleList = new ArrayList<>();
private ListView lvArticles;
private CollectionAdapter mAdapter;

public CollectionsFragment() {}

public static CollectionsFragment newInstance() {
    Bundle args = new Bundle();
    CollectionsFragment fragment = new CollectionsFragment();
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    new MyTask().execute();

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_collections, container, false);

    lvArticles = (ListView) view.findViewById(R.id.lvArticles);
    mAdapter = new CollectionAdapter(getContext(), R.layout.row, mArticleList);
    lvArticles.setAdapter(mAdapter);
    lvArticles.setEmptyView(view.findViewById(R.id.empty));

    return view;
}

private class MyTask extends AsyncTask<Article, Article, Void> {

    @Override
    protected Void doInBackground(Article... articles) {
        Article item = (Article) getArguments().getSerializable("Article");
        mArticleList.add(item);
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        mAdapter.notifyDataSetChanged();

        lvArticles.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Article item = mArticleList.get(position);
                Intent intent = new Intent(getContext(), WebViewActivity.class);
                intent.putExtra("URL", item.getUrl());
                getContext().startActivity(intent);
            }
        });

        lvArticles.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                Article item = mArticleList.get(position);
                createDialog(view, item);
                return true;
            }
        });
    }

    private void createDialog(View view, final Article item) {

        final Dialog d = new Dialog(getContext());
        d.setContentView(R.layout.dialog_collections);
        d.setTitle("Remove article?");
        d.setCancelable(true);

        Button b = (Button) d.findViewById(R.id.button1);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mArticleList.remove(item);
                mAdapter.notifyDataSetChanged();
            }
        });

        d.show();
    }
}
}
日志文件
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String models.Article.getAuthor()' on a null object reference
                                                                        at adapters.CollectionAdapter.getView(CollectionAdapter.java:49)
                                                                        at android.widget.AbsListView.obtainView(AbsListView.java:2347)
                                                                        at android.widget.ListView.makeAndAddView(ListView.java:1864)
                                                                        at android.widget.ListView.fillDown(ListView.java:698)
                                                                        at android.widget.ListView.fillFromTop(ListView.java:759)
                                                                        at android.widget.ListView.layoutChildren(ListView.java:1659)
                                                                        at android.widget.AbsListView.onLayout(AbsListView.java:2151)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
                                                                        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
                                                                        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:131)
                                                                        at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
                                                                        at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1367)
                                                                        at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:849)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1193)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
                                                                        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
                                                                        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
                                                                        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
                                                                        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
                                                                        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
                                                                        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
                                                                        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
                                                                        at android.view.View.layout(View.java:15718)
                                                                        at android.view.ViewGroup.layout(ViewGroup.java:5039)
                                                                        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2129)
                                                                        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1886)
                                                                        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1103)
                                                                        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5944)
                                                                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
                                                                        at android.view.Choreographer.doCallbacks(Choreographer.java:601)
                                                                        at android.view.Choreographer.doFrame(Choreographer.java:571)
                                                                        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
                                                                        at android.os.Handler.handleCallback(Handler.java:739)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                        at android.os.Loo

适配器

package adapters;

/* Imports */

public class CollectionAdapter extends ArrayAdapter {

    private List<Article> articleList;
    private int resource;
    private final LayoutInflater inflater;

    public CollectionAdapter(Context context, int resource, List<Article> objects) {
        super(context, resource, objects);
        articleList = objects;
        this.resource = resource;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

        ViewHolder holder = null;

        if (convertView == null) {
            holder = new ViewHolder();
            convertView = inflater.inflate(resource, null);
            holder.author = (TextView) convertView.findViewById(R.id.a_author);
            holder.title = (TextView) convertView.findViewById(R.id.a_title);
            holder.desc = (TextView) convertView.findViewById(R.id.a_desc);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.author.setText(articleList.get(position).getAuthor());
        holder.title.setText(articleList.get(position).getTitle());
        holder.desc.setText(articleList.get(position).getDescription());

        return convertView;
    }

    private class ViewHolder {
        private TextView author;
        private TextView title;
        private TextView desc;
    }

}

4 个答案:

答案 0 :(得分:0)

执行以下操作:

  1. 通过在View view之外声明您的onCreateView()对象类字段。

  2. onPostExecute()

  3. 中移动这些行

    因为你的asyncTask有可能还没有完成,你试图在你的适配器中使用mArticleList。

    mAdapter = new CollectionAdapter(getContext(), R.layout.row, mArticleList);
    lvArticles.setAdapter(mAdapter);
    lvArticles.setEmptyView(view.findViewById(R.id.empty));
    

答案 1 :(得分:0)

在AsyncTask中:

@Override
    protected Void doInBackground(Article... articles) {
        Article item = (Article) getArguments().getSerializable("Article");
         if(item!=null){
            mArticleList.add(item);
        }
        return null;
    }

在您的代码中,ArrayList添加了NULL模型类,以便您在行上获得错误

  holder.author.setText(articleList.get(position).getAuthor());

缺少一个更重要的覆盖方法。

@Override
    public int getCount() {
        return articleList != null ? articleList.size() : 0;
    }

答案 2 :(得分:0)

我不认为您的AsyncTask是必要的。代码中没有任何内容阻塞或长时间运行。

问题是你在列表中得到了空对象,我认为它来自getSerializable,因此看起来如何使用Author参数启动Fragment导致该问题。

除此之外,您可以使用mAdapter.add将对象添加到ListView中,但您应该extends ArrayAdapter<Article> {

您应该从onCreateView设置click事件侦听器。如果确实需要AsyncTask,它应该只向适配器添加数据并通知它,而不是为ListView重新分配所有侦听器

答案 3 :(得分:-1)

另外,请考虑这样做:

 @Override
    public int getCount() {
        return articleList != null ? articleList.size() : 0;
    }

这将阻止您的列表被加载,并且您将不会有空指针。