在 android 中,在回收器视图的第一行中使用 ViewPager 加载布局时出错



我正在尝试在Android中垂直回收器视图的第一行添加滑动横幅。当在活动中和我的回收器视图之外引用时,它工作正常,但是当我尝试在回收器视图中使用它时,我在 ViewPager 对象上收到空指针异常。

如果我注释掉第一行功能,回收器视图将成功加载并填充所有行。

错误信息

   java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.view.ViewPager.setAdapter(android.support.v4.view.PagerAdapter)' on a null object reference
                      at media.client.clientmediaandroid.activity.home.ListCategoryAdapter$CategoryViewHolder.init(ListCategoryAdapter.java:136)
                      at media.client.clientmediaandroid.activity.home.ListCategoryAdapter$CategoryViewHolder.<init>(ListCategoryAdapter.java:109)
                      at media.client.clientmediaandroid.activity.home.ListCategoryAdapter.onCreateViewHolder(ListCategoryAdapter.java:53)
                      at media.client.clientmediaandroid.activity.home.ListCategoryAdapter.onCreateViewHolder(ListCategoryAdapter.java:31)
                      at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6493)
                      at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5680)
                      at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563)
                      at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559)
                      at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2229)
                      at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1556)
                      at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516)
                      at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:608)
                      at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693)
                      at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3109)
                      at android.view.View.measure(View.java:19734)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
                      at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
                      at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
                      at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
                      at android.view.View.measure(View.java:19734)
                      at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:934)
                      at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:973)
                      at android.view.View.measure(View.java:19734)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
                      at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:714)
                      at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:91)
                      at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1361)
                      at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:784)
                      at android.view.View.measure(View.java:19734)
                      at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1060)
                      at android.view.View.measure(View.java:19734)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
                      at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
                      at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
                      at android.view.View.measure(View.java:19734)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
                      at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
                      at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
                      at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
                      at android.view.View.measure(View.java:19734)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
                      at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
                      at android.view.View.measure(View.java:19734)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
                      at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
                      at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
                      at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
E/AndroidRuntime:     at android.view.View.measure(View.java:19734)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
                      at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
                      at com.android.internal.policy.DecorView.onMeasure(DecorView.java:687)
                      at android.view.View.measure(View.java:19734)
                      at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2271)
                      at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1358)
                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1607)
                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1246)
                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6301)
                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
                      at android.view.Choreographer.doCallbacks(Choreographer.java:683)
                      at android.view.Choreographer.doFrame(Choreographer.java:619)
                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
                      at android.os.Handler.handleCallback(Handler.java:751)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6077)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

列表类别适配器.java

    public class ListCategoryAdapter extends RecyclerView.Adapter<ListCategoryAdapter.CategoryViewHolder> {
    private LayoutInflater inflater;
    private HomeView mHomeView;
    private List<MediaCategoriesResponseDTO> datum;
    public ListCategoryAdapter(HomeView mHomeView, List<MediaCategoriesResponseDTO> dt) {
        this.mHomeView = mHomeView;
        this.datum = dt;
    }
    @Override
    public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        CategoryViewHolder holder = null;
        CardView view = null;
        inflater = LayoutInflater.from(parent.getContext());
        if (viewType == 1) {
            // inflate your first item layout & return that viewHolder
            view = (CardView) inflater.inflate(R.layout.list_item_media_banner, parent, false);

            holder = new CategoryViewHolder(mHomeView, view, new ArrayList<Media>());
        } else {
            // inflate your second item layout & return that viewHolder
            view = (CardView) inflater.inflate(R.layout.list_item_media_category, parent, false);

            holder = new CategoryViewHolder(mHomeView, view, new ArrayList<Media>());
        }
        return holder;
    }
    @Override
    public void onBindViewHolder(CategoryViewHolder holder, int position) {
        if(position > 0) {
            holder.textViewCategoryName.setText(datum.get(position).getName());
        }
    }
    @Override
    public int getItemCount() {
        return datum.size();
    }
    @Override
    public int getItemViewType(int position) {
        if (position == 0) return 1;
        else return 2;
    }
    public static class CategoryViewHolder extends RecyclerView.ViewHolder {
        //private HomeView mHomeView;
        private static ViewPager mPager;
        private static int currentPage = 0;
        private static int NUM_PAGES = 0;
        private ArrayList<ImageModel> imageModelArrayList;
        private int[] myImageList = new int[]{R.drawable.landing_screen_1, R.drawable.landing_screen_2,
                R.drawable.landing_screen_3};
        public TextView textViewCategoryName;
        public CategoryViewHolder(HomeView mHomeView, CardView cardView, List<Media> medias) {
            super(cardView);
            //this.mHomeView = mHomeView;
            textViewCategoryName = (TextView) cardView.findViewById(R.id.textViewCategoryName);
            imageModelArrayList = new ArrayList<>();
            imageModelArrayList = populateList();
            init(mHomeView);
            RecyclerView horizontalMediaRecyclerView = cardView.findViewById(R.id.list_item_media);
            LinearLayoutManager mLayoutManager = new LinearLayoutManager((Context)mHomeView, LinearLayoutManager.HORIZONTAL, false);
//            HomePresenter presenter = new HomePresenterImpl(mHomeView, new HomeInteractorImpl(), mLayoutManager,null, horizontalMediaRecyclerView);
//            presenter.loadMediaFeed(medias);
        }
        private ArrayList<ImageModel> populateList(){
            ArrayList<ImageModel> list = new ArrayList<>();
            for(int i = 0; i < 3; i++){
                ImageModel imageModel = new ImageModel();
                imageModel.setImage_drawable(myImageList[i]);
                list.add(imageModel);
            }
            return list;
        }
        private void init(HomeView mHomeView) {
            mPager = (ViewPager) ((AppCompatActivity)mHomeView).findViewById(R.id.pager_home);
            mPager.setAdapter(new SlidingImage_Adapter((AppCompatActivity) mHomeView, imageModelArrayList));
            CirclePageIndicator indicator = (CirclePageIndicator)
                    ((AppCompatActivity)mHomeView).findViewById(R.id.indicator_home);
            indicator.setViewPager(mPager);
            final float density = ((AppCompatActivity)mHomeView).getResources().getDisplayMetrics().density;
//Set circle indicator radius
            indicator.setRadius(5 * density);
            NUM_PAGES =imageModelArrayList.size();
            // Auto start of viewpager
            final Handler handler = new Handler();
            final Runnable Update = new Runnable() {
                public void run() {
                    if (currentPage == NUM_PAGES) {
                        currentPage = 0;
                    }
                    mPager.setCurrentItem(currentPage++, true);
                }
            };
            Timer swipeTimer = new Timer();
            swipeTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    handler.post(Update);
                }
            }, 3000, 3000);
            // Pager listener over indicator
            indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageSelected(int position) {
                    currentPage = position;
                }
                @Override
                public void onPageScrolled(int pos, float arg1, int arg2) {
                }
                @Override
                public void onPageScrollStateChanged(int pos) {
                }
            });
        }
    }
}

空指针异常在此行引发

mPager.setAdapter(new SlidingImage_Adapter((AppCompatActivity) mHomeView, imageModelArrayList));

在@MikeM的帮助下,我做了更多的研究,我已经解决了这个问题。创建单独的 ViewHolder 并根据 RecyclerView 呈现的索引或位置选择或呈现它们适用的视图持有人就可以解决问题。

大部分工作是在适配器中完成的。

public class ListCategoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private LayoutInflater inflater;
private HomeView mHomeView;
private List<MediaCategoriesResponseDTO> datum;
private List<Media> listOfMedia;
CardView view;
public ListCategoryAdapter(HomeView mHomeView, List<MediaCategoriesResponseDTO> dt) {
    this.mHomeView = mHomeView;
    this.datum = dt;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    inflater = LayoutInflater.from(parent.getContext());
    if (viewType == 1) {
        // inflate your first item layout & return that viewHolder
        view = (CardView) inflater.inflate(R.layout.list_item_media_banner, parent, false);

        return new MediaBannerViewHolder(mHomeView, view);
    } else {
        // inflate your second item layout & return that viewHolder
        view = (CardView) inflater.inflate(R.layout.list_item_media_category, parent, false);

        return new CategoryViewHolder(mHomeView, view);
    }
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if(position > 0) {
        ((CategoryViewHolder)holder).textViewCategoryName.setText(datum.get(position).getName());
        listOfMedia = datum.get(position).getMedias();
        RecyclerView horizontalMediaRecyclerView = view.findViewById(R.id.list_item_media);
        LinearLayoutManager mLayoutManager = new LinearLayoutManager((Context)mHomeView, LinearLayoutManager.HORIZONTAL, false);
        horizontalMediaRecyclerView.setLayoutManager(mLayoutManager);
        horizontalMediaRecyclerView.setHasFixedSize(true);
        HomePresenter presenter = new HomePresenterImpl(mHomeView);
        presenter.loadMediaFeed(listOfMedia, horizontalMediaRecyclerView);
    }
    //Manipulate ViewPager View here
}
@Override
public int getItemCount() {
    return datum.size();
}
@Override
public int getItemViewType(int position) {
    if (position == 0) return 1;
    else return 2;
}
public static class CategoryViewHolder extends RecyclerView.ViewHolder {
    public TextView textViewCategoryName;
    public CategoryViewHolder(HomeView mHomeView, CardView cardView) {
        super(cardView);

        textViewCategoryName = (TextView) cardView.findViewById(R.id.textViewCategoryName);
    }
}
public static class MediaBannerViewHolder extends RecyclerView.ViewHolder {
    //The ViewPager code here
}

}

最新更新