RecyclerView添加頭佈局後,使用adapter.notifyItemChanged(pos,"test") 局部刷新無效的問題

給RecyclerView添加頭佈局使用的是HeaderAndFooterWrapper,然後我做的是列表滑動播放短視頻,但是在每個視頻Item的下面都有拔草按鈕跟數字,點擊種草或者拔草要刷新數字。使用RecyclerView的局部刷新即

headerAndFooterWrapper.notifyItemChanged(zhong_ba_cao_pos+1,"test");

然後build發現點擊後數字沒變化,以爲代碼哪裏錯了然後一路debug發現確實執行完方法了,只不過是沒調用起  HeaderAndFooterWrapper包含的實際列表適配器即

mInnerAdapter中的onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads)

然後開始度娘ing(怎麼沒調用到onBindViewHolder的三個參數函數?)

千篇一律的都是說在適配器的onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads)中判斷payloads爲空如何如何,但是這個我已經在mInnerAdapter的onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads)寫了;  

os:what鬼?

然後自己寫了個簡單的RecyclerView局部刷新的demo   運行發現是可以刷新局部item的,說明代碼沒有問題,然後把RecyclerView的adapter從headerAndFooterWrapper變成不加頭佈局的mInnerAdapter,一步一步縮小問題範圍,改完後發現局部也是可以刷新的,看來問題就出在這個頭佈局適配器即HeaderAndFooterWrapper上。

在HeaderAndFooterWrapper文件中發現了同樣的構造

onBindViewHolder(RecyclerView.ViewHolder holder, int position)但是沒有三參的,靈機一動,自己加了個即
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
    if(payloads.isEmpty()){
        onBindViewHolder(holder,position);
    }else{
        mInnerAdapter.onBindViewHolder(holder,position - getHeadersCount(),payloads);
    }
}

運行後發現ok了,問題解決。折騰了下午好一會,記錄一下。附上HeaderAndFooterWrapper的代碼跟mInnerAdapter的代碼如下,只看二個適配器中的onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads)函數就行了:

 

public class HeaderAndFooterWrapper extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    public static final int BASE_ITEM_TYPE_HEADER = 100000;
    public static final int BASE_ITEM_TYPE_FOOTER = 200000;
    private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
    private SparseArrayCompat<View> mFooterViews = new SparseArrayCompat<>();

    private RecyclerView.Adapter mInnerAdapter;

    public HeaderAndFooterWrapper(RecyclerView.Adapter innerAdapter) {
        mInnerAdapter = innerAdapter;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (mHeaderViews.get(viewType) != null){
            return new MyViewHolder(mHeaderViews.get(viewType));
        }else if (mFooterViews.get(viewType) != null){
            return new MyViewHolder(mFooterViews.get(viewType));
        }
        return mInnerAdapter.onCreateViewHolder(parent,viewType);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
        if(payloads.isEmpty()){
            onBindViewHolder(holder,position);
        }else{
            mInnerAdapter.onBindViewHolder(holder,position - getHeadersCount(),payloads);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (isHeaderViewPos(position))
            return;
        if (isFooterViewPos(position))
            return;
        mInnerAdapter.onBindViewHolder(holder,position - getHeadersCount());
    }

    @Override
    public int getItemCount() {
        return getHeadersCount() + getFootersCount() + getRealItemCount();
    }

    @Override
    public int getItemViewType(int position) {
        if (isHeaderViewPos(position)){
            return mHeaderViews.keyAt(position);
        }else if (isFooterViewPos(position)){
            return mFooterViews.keyAt(position - getHeadersCount() - getRealItemCount());
        }
        return mInnerAdapter.getItemViewType(position - getHeadersCount());
    }

    /**
     * 獲取正常數據的size
     * @return
     */
    private int getRealItemCount(){
        return mInnerAdapter.getItemCount();
    }

    /**
     * 判斷是否是Header
     * @param position
     * @return
     */
    private boolean isHeaderViewPos(int position){
        return position < getHeadersCount();
    }

    /**
     * 判斷是否是Footer
     * @param position
     * @return
     */
    private boolean isFooterViewPos(int position){
        return position >= getHeadersCount() + getRealItemCount();
    }


    public void addHeaderView(View view){
        mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER,view);
    }
    public void addFooterView(View view){
        mFooterViews.put(mFooterViews.size() + BASE_ITEM_TYPE_FOOTER,view);
    }
    private int getHeadersCount(){
        return mHeaderViews.size();
    }
    public int getFootersCount(){
        return mFooterViews.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder{
        public MyViewHolder(View itemView) {
            super(itemView);
        }
    }

    /**
     * 適配網格佈局
     * @param recyclerView
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        mInnerAdapter.onAttachedToRecyclerView(recyclerView);
        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager){
            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return isHeaderViewPos(position) || isFooterViewPos(position) ? ((GridLayoutManager) layoutManager).getSpanCount() : 1;
                }
            });
        }
    }

    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {

        mInnerAdapter.onViewAttachedToWindow(holder);
        int position = holder.getLayoutPosition();
        if (isHeaderViewPos(position)||isFooterViewPos(position)){
            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
            if (lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams){
                StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
                p.setFullSpan(true);
            }
        }
    }
}

 

 

 

 

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

    public static final String TAG = "AdapterRecyclerView";
    private Context context;
    private MyData videoData;

    public AdapterRecyclerView(Context context, MyData videoData) {
        this.context = context;
        this.videoData = videoData;
    }


    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
                context).inflate(R.layout.item_videoview, parent,
                false));
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position, @NonNull List<Object> payloads) {
        if(payloads.isEmpty()){
            onBindViewHolder(holder,position);
        }else{
            MyRow rowItem = videoData.get(position);
            if (MathUtils.getInt(rowItem.get("user_like_flag") + "") == 1) {   //like_main_bottom
                holder.tv_font_zhong_cao.setTextColor(context.getResources().getColor(R.color.my_red));
            } else {
                holder.tv_font_zhong_cao.setTextColor(context.getResources().getColor(R.color.gray_color_d9d9d9));
            }

            if (MathUtils.getInt(rowItem.get("user_dislike_flag") + "") == 1) {   //like_main_bottom
                holder.tv_font_ba_cao.setTextColor(context.getResources().getColor(R.color.my_red));
            } else {
                holder.tv_font_ba_cao.setTextColor(context.getResources().getColor(R.color.gray_color_d9d9d9));
            }

            holder.zhong_cao_num.setText(MathUtils.getInt(rowItem.get("like_count") + "") + "");
            holder.ba_cao_num.setText(MathUtils.getInt(rowItem.get("dislike_count") + "") + "");
        }
    }

    @SuppressLint("LongLogTag")
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {  //裏面是我的業務邏輯  不用管
        MyRow rowItem = videoData.get(position);

        holder.userAvatar.setTag(null);
       Glide.with(context.getApplicationContext()).asBitmap().load((rowItem.getString("avatar_url"))).into(holder.userAvatar);
        holder.userAvatar.setTag(rowItem.getInt("user_id"));

        Log.i(TAG, "onBindViewHolder [" + holder.jzvdStd.hashCode() + "] position=" + position);
        holder.jzvdStd.setUp(
                videoData.get(position).getString("play_addr"),
                "", Jzvd.SCREEN_FULLSCREEN);
        Glide.with(holder.jzvdStd.getContext()).load( videoData.get(position).getString("cover_url")).into(holder.jzvdStd.posterImageView);

        LinearLayout.LayoutParams lps = (LinearLayout.LayoutParams) holder.layout_card.getLayoutParams();
        lps.width = ScreenUtils.getScreenWidth(context)-ScreenUtils.dp2px(context,10);
        lps.height = (int) (lps.width/0.727);
        holder.layout_card.setLayoutParams(lps);
        holder.layout_card.setRadius(5f);
        holder.video_des.setText(rowItem.getString("video_des"));
        if(rowItem.getBoolean("isShowLink")){
            holder.ll_shop_tab.setVisibility(View.VISIBLE);
        }else{
            holder.ll_shop_tab.setVisibility(View.GONE);
        }
        MyRow r = new MyRow();
        r.put("goods_from",rowItem.getString("goods_from"));
        r.put("goods_url",rowItem.getString("goods_url"));
        holder.fest_buy.setTag(r);
        MyRow rCao = new MyRow();
        rCao.put("id",rowItem.getInt("id"));
        rCao.put("pos",position);
        rCao.put("like_count",MathUtils.getInt(rowItem.get("like_count")+""));
        rCao.put("dislike_count",MathUtils.getInt(rowItem.get("dislike_count")+""));
        rCao.put("user_like_flag",MathUtils.getInt(rowItem.get("user_like_flag")+""));
        rCao.put("user_dislike_flag",MathUtils.getInt(rowItem.get("user_dislike_flag")+""));
        holder.ll_comment.setTag(rCao);
        holder.zhong_cao.setTag(rCao);
        holder.ba_cao.setTag(rCao);
        holder.img_follow.setTag(rowItem.getInt("user_id"));
        holder.user_name.setText(rowItem.getString("user_nickname"));
        holder.layout_card.setRadius(5);
        holder.ll_jubao.setTag(rowItem.getInt("id"));
        MyRow r1 = new MyRow();
        r1.put("pos", position);
        r1.put("goods_from", rowItem.getString("goods_from"));
        r1.put("goods_url", rowItem.getString("goods_url"));
        holder.ll_get_link.setTag(r1);
        rowItem.put("pos", position);
   Glide.with(context.getApplicationContext()).asBitmap().load((rowItem.getString("goods_pic"))).into(holder.shop_img);
        holder.shop_name.setText(rowItem.getString("goods_name"));
        holder.shop_price.setText("¥"+rowItem.getString("goods_price"));
    }

    @Override
    public int getItemCount() {
        return null == videoData ? 0 : videoData.size();
    }

    static class MyViewHolder extends RecyclerView.ViewHolder {
        JzvdStd jzvdStd;
        CardView layout_card;

        public CircleImageView userAvatar;
        public ImageView img_follow;
        public XCRoundRectImageView shop_img;
        public TextView name,tv_font_zhong_cao,user_name, tv_font_ba_cao, tv_font_comment, video_des, zhong_cao_num, ba_cao_num, tv_font_sandian, comment_num, shop_name, shop_price, fest_buy;
        public LinearLayout ll_get_link, ll_jubao, ll_shop_tab,zhong_cao,ba_cao,ll_comment;

        public MyViewHolder(View itemView) {
            super(itemView);
            jzvdStd = itemView.findViewById(R.id.videoplayer);
            layout_card= itemView.findViewById(R.id.layout_card);

//            name = (TextView) itemView.findViewById(R.id.tv_video_name);

            ll_get_link = itemView.findViewById(R.id.ll_get_link);

            userAvatar = (CircleImageView) itemView.findViewById(R.id.head_icon);
            img_follow = (ImageView) itemView.findViewById(R.id.img_follow);

            tv_font_zhong_cao = itemView.findViewById(R.id.tv_font_zhong_cao);
            tv_font_ba_cao = itemView.findViewById(R.id.tv_font_ba_cao);
//                tv_font_get_link = itemView.findViewById(R.id.tv_font_get_link);
            tv_font_comment = itemView.findViewById(R.id.tv_font_comment);
            tv_font_sandian = itemView.findViewById(R.id.tv_font_sandian);

            video_des = itemView.findViewById(R.id.video_des);

            zhong_cao_num = itemView.findViewById(R.id.zhong_cao_num);
            ba_cao_num = itemView.findViewById(R.id.ba_cao_num);
            comment_num = itemView.findViewById(R.id.comment_num);
            ll_jubao = itemView.findViewById(R.id.ll_jubao);

            ll_shop_tab = itemView.findViewById(R.id.ll_shop_tab);

            shop_name = (TextView) itemView.findViewById(R.id.shop_name);
            shop_price = (TextView) itemView.findViewById(R.id.shop_price);
            shop_img = itemView.findViewById(R.id.shop_img);

            fest_buy = itemView.findViewById(R.id.fest_buy);

            zhong_cao = itemView.findViewById(R.id.zhong_cao);
            ba_cao= itemView.findViewById(R.id.ba_cao);

            user_name = itemView.findViewById(R.id.user_name);
            ll_comment= itemView.findViewById(R.id.ll_comment);
        }
    }

}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章