RecyclerView和FrameLayout.onMeasure [npe]

时间:2015-03-02 11:33:22

标签: android android-recyclerview

我在实现recyclerview而不是listview时遇到问题。使用listview检测到没有问题,但使用recyclerview我有以下错误

java.lang.NullPointerException
 14204         AndroidRuntime  E  at android.widget.FrameLayout.onMeasure(FrameLayout.java:309)
 14204         AndroidRuntime  E  at android.view.View.measure(View.java:16654)
 14204         AndroidRuntime  E  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5150)
 14204         AndroidRuntime  E  at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:327)
 14204         AndroidRuntime  E  at android.view.View.measure(View.java:16654)
 14204         AndroidRuntime  E  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5150)
 14204         AndroidRuntime  E  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
 14204         AndroidRuntime  E  at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2421)
 14204         AndroidRuntime  E  at android.view.View.measure(View.java:16654)
 14204         AndroidRuntime  E  at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2064)
 14204         AndroidRuntime  E  at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1189)
 14204         AndroidRuntime  E  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1374)
 14204         AndroidRuntime  E  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1076)
 14204         AndroidRuntime  E  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5913)
 14204         AndroidRuntime  E  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:807)
 14204         AndroidRuntime  E  at android.view.Choreographer.doCallbacks(Choreographer.java:601)
 14204         AndroidRuntime  E  at android.view.Choreographer.doFrame(Choreographer.java:562)
 14204         AndroidRuntime  E  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:791)
 14204         AndroidRuntime  E  at android.os.Handler.handleCallback(Handler.java:733)
 14204         AndroidRuntime  E  at android.os.Handler.dispatchMessage(Handler.java:95)
 14204         AndroidRuntime  E  at android.os.Looper.loop(Looper.java:157)
 14204         AndroidRuntime  E  at android.app.ActivityThread.main(ActivityThread.java:5867)
 14204         AndroidRuntime  E  at java.lang.reflect.Method.invokeNative(Native Method)
 14204         AndroidRuntime  E  at java.lang.reflect.Method.invoke(Method.java:515)
 14204         AndroidRuntime  E  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
 14204         AndroidRuntime  E  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
 14204         AndroidRuntime  E  at dalvik.system.NativeStart.main(Native Method)

这是我的适配器

public class SearchPoiAdapter extends RecyclerView.Adapter<SearchPoiAdapter.SearchPoiAdapterHolder> {

    private IPoiListener mListener;
    private List<Poi> mSearchings;

    public interface IPoiListener {
        public void onClickPoi(Poi poi);
        public void noPoi();
    }

    public SearchPoiAdapter(IPoiListener listener) {
        this.mListener = listener;
    }

    public SearchPoiAdapter(List<Poi> pSearchings, IPoiListener listener) {
        this.mListener = listener;
        if (pSearchings != null) {
            mSearchings = pSearchings;
        } else {
            mSearchings = new ArrayList<>();
        }
    }

    public static class SearchPoiAdapterHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        protected TextView title;
        protected Poi item;
        protected IPoiListener myListener;

        public SearchPoiAdapterHolder(View itemView, IPoiListener listener) {
            super(itemView);
            itemView.setOnClickListener(this);
            title = (TextView) itemView.findViewById(R.id.title);
            myListener = listener;
        }

        public void setItem(Poi poi) {
            item = poi;
        }

        @Override
        public void onClick(View view) {
            myListener.onClickPoi(item);
        }
    }

    @Override
    public int getItemCount() {
        if (mSearchings != null) {
            if (mSearchings.size() == 0) {
                mListener.noPoi();
            }
            return mSearchings.size();
        }
        return 0;
    }

    @Override
    public SearchPoiAdapterHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.
                from(parent.getContext()).
                inflate(R.layout.search_list_item, parent, false);

        return new SearchPoiAdapter.SearchPoiAdapterHolder(itemView, mListener);
    }

    @Override
    public void onBindViewHolder(SearchPoiAdapterHolder holder, int position) {
        holder.setItem(mSearchings.get(position));
        holder.title.setText(mSearchings.get(position).getName());
    }

    public void addPoi(Poi poi) {
        if (mSearchings == null) {
            mSearchings = new ArrayList<>();
        }
        mSearchings.add(poi);
    }

    /**
     * Sort all the Pois by their name
     */
    public void sortPoi() {
        if (mSearchings != null) {
            Collections.sort(mSearchings, new Comparator<Object>() {
                @Override
                public int compare(Object obj1, Object obj2) {
                    if (obj1 instanceof Poi && obj2 instanceof Poi) {
                        Poi poiOne = (Poi) obj1;
                        Poi poiTwo = (Poi) obj2;
                        return poiOne.getName().compareToIgnoreCase(poiTwo.getName());
                    }
                    return 0;
                }
            });
        }
    }

    public void updatePois(List<Poi> pPois) {
        this.mSearchings = pPois;
        notifyDataSetChanged();
    }

    public void clear() {
        if (mSearchings != null) {
            int size = mSearchings.size();
            mSearchings.clear();
            notifyItemRangeRemoved(0, size);
        }
    }
}

负责崩溃的代码。 Stacktrace没有引用我的代码,因此调试它真的很难。但是经过很多评论我终于找到了这个地方。

protected void updateAdapter(int filter) {
        if (poiAdapter != null) {
            poiAdapter.clear();  // If I comment this line, it seems I have no problem but the adapter is not cool
        } else {
            poiAdapter = new SearchPoiAdapter(this);
        }
        switch (filter) {
            case RAIL_STATION : {
                for (int i = 0; i < pois.size(); i++) {
                    if (pois.get(i).getType().equals(Constants.RAILSTATION)  && !pois.get(i).hasChild()) {
                        poiAdapter.addPoi(pois.get(i));
                    }
                }
                list.setAdapter(poiAdapter);
                poiAdapter.sortPoi();
                poiAdapter.notifyDataSetChanged();
                break;
            }
            case AIRPORT : {
                for (int i = 0; i < pois.size(); i++) {
                    if (pois.get(i).getType().equals(Constants.AIRPORT)  && !pois.get(i).hasChild()) {
                        poiAdapter.addPoi(pois.get(i));
                    }
                }
                list.setAdapter(poiAdapter);
                poiAdapter.sortPoi();
                poiAdapter.notifyDataSetChanged();
                break;
            }
            case OTHER_POIS : {  // display only parents
                for (int i = 0; i < pois.size(); i++) {
                    if (pois.get(i).getType().equals(Constants.OTHER)  && pois.get(i).hasChild()) {
                        poiAdapter.addPoi(pois.get(i));
                    }
                }
                list.setAdapter(poiAdapter);
                poiAdapter.sortPoi();
                poiAdapter.notifyDataSetChanged();
                break;
            }
        }
        emptyView.setVisibility(View.GONE);
    }

当我切换到另一个poi时发生错误。我再说一遍,我对ListView的旧实现没有任何问题。

你有想法解决我的问题吗?

提前谢谢

0 个答案:

没有答案