当前位置: 首页 > 知识库问答 >
问题:

水平回收器视图内部垂直回收器视图的自定义适配器

蔚元明
2023-03-14

我有一个父回收器视图,其中包含一个水平回收器视图作为其项目。在其中,我将显示分类视频。当我开始滚动水平回收器视图时,应用程序崩溃。

错误是:

FATAL EXCEPTION: main
Process: earn.ads.earningvideos, PID: 11192
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid
view holder adapter positionViewHolder{f5a3493 position=3 id=-1,
oldPos=-1, pLpos:-1 no parent}
android.support.v7.widget.RecyclerView{16875cc VFED..... ........
0,80-686,394 #7f08014e app:id/vid_rv},
adapter:earn.ads.earningvideos.classes.Category_thumbnail@c2e47ce,
layout:android.support.v7.widget.LinearLayoutManager@e986ef,
context:earn.ads.earningvideos.Activities.Home_page@9308787
at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5416)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5598)
atandroid.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:285)
at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:342)
at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:358)
at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:365)
at android.support.v7.widget.GapWorker.run(GapWorker.java:396)
at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063) at
com.android.internal.os.ZygoteInit.main  (ZygoteInit.java:924) 

我的代码是category类

public void getCat(){
    Cursor cur = null;
    cat_list.clear();
    String item_query = " SELECT tcategory.*,(select count(VideoPlaylist.videoId) from VideoPlaylist where tcategory.CategoryId=VideoPlaylist.catId) as totalVideos FROM "+ database.Table.Name.TABLE_CATEGORY +" order by totalVideos asc";
    cur = db.findCursor(item_query, null);


    if (cur != null && cur.moveToNext()) {

        for(int i=0;i<cur.getCount();i++)
        {
            if(Integer.parseInt(cur.getString(cur.getColumnIndex("totalVideos")).toString())>0) {
                HashMap<String, String> map = new HashMap<>();

                map.put("vcategory", cur.getString(cur.getColumnIndex(database.Table.Name.CAT_NAME.toString())));
                map.put("vcategoryid", cur.getString(cur.getColumnIndex(database.Table.Name.CAT_ID.toString())));

                cat_list.add(map);
            }
            cur.moveToNext();
        }
    }
    cur.close();
        recyclerView.setLayoutManager(linearLayoutManager);
        CategoryAdapter categoryAdapter = new CategoryAdapter(getContext(), cat_list);
        recyclerView.setAdapter(categoryAdapter);
        recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}

垂直适配器

public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.MyViewHolder> {

    View view;
    Context context;
    database db;
    Typeface typeface;
    LinearLayoutManager llm;
    String catid;
    public static ArrayList<HashMap<String, String>> cat_list;
    ArrayList<HashMap<String,String>> videoData= new ArrayList<>();


    public CategoryAdapter(Context context,ArrayList<HashMap<String, String>> cat_list) {
        this.context = context;
        this.cat_list = cat_list;
        typeface = Typeface.createFromAsset(context.getAssets(), "fonts/OpenSans-Regular.ttf");
    }

    @Override
    public CategoryAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_custom, parent, false);
        MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder
        return vh;
    }

    @Override
    public void onBindViewHolder(CategoryAdapter.MyViewHolder holder, int position) {

        llm = new 
LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false);

        db = new database(context);
        holder.cat.setText(cat_list.get(position).get("vcategory"));
        catid = cat_list.get(position).get("vcategoryid");
        getData(Integer.parseInt(catid),holder.rv);


        holder.more.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                ((Home_page)context).load_fragment(new More_category());
            }
        });
    }

    @Override
    public int getItemCount() {
        return cat_list.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        // init the item view's
        RecyclerView rv;
        TextView more,cat;


        public MyViewHolder(View itemView) {
            super(itemView);

            // get the reference of item view's
            rv = (RecyclerView)itemView.findViewById(R.id.vid_rv);
            more = (TextView)itemView.findViewById(R.id.more);
            cat = (TextView)itemView.findViewById(R.id.cat);

        }
    }

    public void getData(int cid, RecyclerView rv){
        Cursor cur = null;
        videoData.clear();
        String item_query = "SELECT * FROM "+ database.Table.Name.TABLE_NAME +" WHERE catId = "+ cid + " order by videoId desc" ;
        cur = db.findCursor(item_query, null);

        if (cur != null && cur.moveToNext()) {

            for(int i=0;i<cur.getCount();i++)
            {
                HashMap<String,String> map= new HashMap<>();

                map.put("vtitle", cur.getString(cur.getColumnIndex(database.Table.Name.VIDEOTITLE.toString())));
                map.put("vtime", cur.getString(cur.getColumnIndex(database.Table.Name.VIDEO_TIME.toString())));
                map.put("vviews", cur.getString(cur.getColumnIndex(database.Table.Name.VIDEO_VIEW.toString())));
                map.put("vamount", cur.getString(cur.getColumnIndex(database.Table.Name.VIDEO_AMOUNT.toString())));
                map.put("vimage", cur.getString(cur.getColumnIndex(database.Table.Name.VIDEO_THUMB.toString())));
                map.put("vid", cur.getString(cur.getColumnIndex(database.Table.Name.VIDEO_ID.toString())));
                map.put("vkey", cur.getString(cur.getColumnIndex(database.Table.Name.YOUTUBE_KEY.toString())));
                map.put("vlike", cur.getString(cur.getColumnIndex(database.Table.Name.LIKE.toString())));
                map.put("vlike_status", cur.getString(cur.getColumnIndex(database.Table.Name.LIKE_STATUS.toString())));
                map.put("vcomment", cur.getString(cur.getColumnIndex(database.Table.Name.COMMENT.toString())));
                map.put("vtype", cur.getString(cur.getColumnIndex(database.Table.Name.TYPE.toString())));
                map.put("vseen_status", cur.getString(cur.getColumnIndex(database.Table.Name.STATUS.toString())));
                map.put("vdesc", cur.getString(cur.getColumnIndex(database.Table.Name.VIDEO_DETAILS.toString())));
                map.put("vsubscription", cur.getString(cur.getColumnIndex(database.Table.Name.SUBSCRIPTION.toString())));
                map.put("vsubscriber", cur.getString(cur.getColumnIndex(database.Table.Name.SUBSCRIBER.toString())));
                map.put("vcompany", cur.getString(cur.getColumnIndex(database.Table.Name.COMPANY.toString())));
                map.put("vcompanyid", cur.getString(cur.getColumnIndex(database.Table.Name.COMPANY_ID.toString())));

                videoData.add(map);

                cur.moveToNext();
            }
        }
        cur.close();
        rv .setLayoutManager(llm);
        Category_thumbnail category_thumbnail = new Category_thumbnail(context,videoData);
        rv.setAdapter(category_thumbnail);

    }

}

水平适配器

public class Category_thumbnail extends RecyclerView.Adapter<Category_thumbnail.MyViewHolder> {
    View view;
    Context context;
    Typeface typeface;
    public static ArrayList<HashMap<String, String>> vidList;

    public Category_thumbnail(Context context,ArrayList<HashMap<String, String>> vidList) {
        this.context = context;
        this.vidList = vidList;
        typeface = Typeface.createFromAsset(context.getAssets(), "fonts/OpenSans-Regular.ttf");
    }

    @Override
    public Category_thumbnail.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.categoryvidlist, parent, false);
        MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder
        return vh;
    }

    @Override
    public void onBindViewHolder(final Category_thumbnail.MyViewHolder holder, int position) {

        holder.loader_small.setVisibility(View.VISIBLE);
        holder.vtitle.setText(vidList.get(position).get("vtitle"));
        holder.views.setText(vidList.get(position).get("vviews"));
        holder.duration.setText(vidList.get(position).get("vtime"));


        Picasso.with(context).load(vidList.get(position).get("vimage").toString()).into(holder.thumbnail, new Callback() {
            @Override
            public void onSuccess() {
                holder.loader_small.setVisibility(View.GONE);
            }

            @Override
            public void onError() {
            }
        });
    }

    @Override
    public int getItemCount() {

        return vidList.size();
    }


    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        // init the item view's
         TextView vtitle,views,duration;
         ImageView thumbnail;
         ProgressBar loader_small;


        public MyViewHolder(View itemView) {
            super(itemView);

            // get the reference of item view's
            vtitle = (TextView)itemView.findViewById(R.id.vtitle);
            views = (TextView)itemView.findViewById(R.id.views);
            duration = (TextView)itemView.findViewById(R.id.duration);
            thumbnail = (ImageView)itemView.findViewById(R.id.vidThumb);
            loader_small =(ProgressBar)itemView.findViewById(R.id.smallloader);


        }
    }
}

共有1个答案

姜羽
2023-03-14

如果不工作,您可以尝试以下水平适配器,也可以尝试垂直适配器:

@Override
    public void onBindViewHolder(final Category_thumbnail.MyViewHolder holder, int position) {

        //check this line
        if (position < 0 || position >= vidList.size()) return;

        holder.loader_small.setVisibility(View.VISIBLE);
        holder.vtitle.setText(vidList.get(position).get("vtitle"));
        holder.views.setText(vidList.get(position).get("vviews"));
        holder.duration.setText(vidList.get(position).get("vtime"));


        Picasso.with(context).load(vidList.get(position).get("vimage").toString()).into(holder.thumbnail, new Callback() {
            @Override
            public void onSuccess() {
                holder.loader_small.setVisibility(View.GONE);
            }

            @Override
            public void onError() {
            }
        });
    }

    @Override
    public int getItemCount() {

        //check this line
        return (vidList != null) ? vidList.size() : 0;
    }
 类似资料:
  • 我有一个水平回收视图。每个子级包含一个TextView和一个垂直RecyclerView。垂直RecyclerView的子级仅包含TextView。 垂直滚动非常平滑,但水平滚动滞后很多。我已经尝试在onBindViewHolder中使用swapAdapter,而不是setAdapter,但这并没有解决问题。我也尝试过更改数据集并调用notifyDataSetChanged(),但这也没有帮助。

  • 在其他回收器视图中有一个回收器视图。两者都需要垂直滚动。外部回收器视图滚动正常,但内部回收器视图滚动不正常。 这是代码: ViewAdapter如下: 我尝试了以下两种回收商观点,但都无法解决问题 也尝试了这个:

  • 我在ViewPager中的NestedScrollView中有一个水平的RecyclerView。现在当我尝试滚动RecyclerView时,有时它滚动,但有时只有ViewPager滚动。 这就是我的RecyclerView XML的样子: 到目前为止,我所尝试的,正如你所看到的,我写了一个自定义的viewpager。我尝试告诉ViewPager,如果滚动来自RecyclerView,它就不能滚动

  • 我想在垂直视图页中实现一个recyclerview。我当前的布局如下所示 如果我从Fragment1滑动到Fragment2,一切正常。我可以在回收器视图中上下滚动。如果我尝试滑动/滚动回Fragment1,就会出现问题。 如果用户已滚动到回收器视图的顶部,我想将下一个“向上”滚动事件转发到垂直视图页页面。我尝试过重写 方法,但遗憾的是仍然没有成功。有什么想法吗?感谢您的帮助:)

  • 我正在使用下面的代码创建一个回收器视图。recyclerview有一个网格布局管理器,其项计数最多为每行2个。 不幸的是,我嵌套在ConstraintLayout中的回收器视图根本没有滚动。我错过了什么?约束布局是否支持相同的?

  • 我正在尝试为水平回收视图实现ItemTouchHelper。(将布局管理器设置为LinearLayoutManager,方向为LinearLayoutManager.HORIZONTAL)。例如,我想在向下滑动并向左或向右拖动以交换项目时删除项目。 我所经历的所有示例都解释了ItemTouchHelper的垂直回收站视图或网格中的项目。 以下示例来自以下链接: https://medium.com