RecyclerView 暫無數據 點擊重新加載 (二)

上回初步弄了下RecyclerView 暫無數據 點擊重新加載 但那個效果不之適用於點擊全屏 RecyclerView 暫無數據 點擊重新加載 (一)
這回講下局部刷新 實現下面這樣的效果的大致思路

上篇文章實現的方式只是單純的重寫onDraw和dispatchTouchEvent方法
本次實現的思路圖片和文字還是和上回一樣在onDraw繪製
主要的處理在於局部刷新按鈕
廢話不多說 上個圖
image.png
ps.沒啥圖片整的隨便搞了圖將就下
第一步 繪製出 重新加載按鈕
image.png
通過addview 把按鈕繪製到屏幕中間 由於RecyclerView的item是屬於RecyclerView.ViewHolder 直接view 不處理的話會報這樣的錯

java.lang.NullPointerException: Attempt to invoke virtual method ‘boolean androidx.recyclerview.widget.RecyclerView$ViewHolder.shouldIgnore()’ on a null object reference

so 就要去第二個步驟了 重寫 onMeasure onLayout方法
image.png
onMeasure沒啥好說的就是把childview繪製下寬高

onLayout的話就要注意那個if判斷以及v.layout這倆個地方

super.onLayout(changed,l,t,r,b); 是處理item的繪製 也就是真實數據的item
v.layout是單獨處理addview添加的按鈕 把那個報錯信息處理掉 按鈕不是
ViewHolder繪製出來 如果不加判斷 會異常 而 真實數據不返回 super.onLayout則item不會繪製

最後一步onDraw 繪製圖片和描述文字
image.png

到此就這麼結束了 上完整代碼

public class My2RecyclerView extends RecyclerView {
    Shuaxin shuaxin; //這個是自己瞎寫的接口  
    boolean complete;
    Bitmap bitmap;
    Paint paint;
    public My2RecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        paint.setTextSize(DisplayUtils.sp2px(context,14));
        paint.setTextAlign(Paint.Align.CENTER);
        paint.setColor(Color.BLACK);
    }

    public void setShuaxin(Shuaxin shuaxin) {
        this.shuaxin = shuaxin;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }


    public void noData(){
        if(getChildCount() == 0){
            LayoutParams params =
                    new RecyclerView.LayoutParams(
                            ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            TextView textView =new  TextView(getContext());
            textView.setPadding(60,30,60,30);
            textView.setLayoutParams(params);
            textView.setText("重新加載");
            textView.setGravity(Gravity.CENTER);
            textView.setTag("加載");
            textView.setBackgroundResource(R.drawable.click);
            textView.setTextColor(Color.WHITE);
            textView.setOnClickListener(v -> {
                if(this.shuaxin!=null){
                    this.shuaxin.shuaxin();
                }
            });
            addView(textView);
        }
        requestLayout();
        //由於是addview 實現 需要刷新view的位置 故不採用 invalidate 回調onDraw方法
        //requestLayout 回調 onMeasure    onLayout 如果有視圖改變 纔會 onDraw
    }

    public void complete(){
        complete =true;
        bitmap = null;
        removeAllViews();
    }

    @Override
    protected void onMeasure(int widthSpec, int heightSpec) {
        super.onMeasure(widthSpec, heightSpec);
        Log.d("RecyclerView","onMeasure---"+getChildCount());
        for (int i = 0; i < getChildCount(); i++) {
            View v = getChildAt(i);
            measureChild(v,widthSpec,heightSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        Log.d("RecyclerView","onLayout---"+getChildCount());
        if (getChildCount()>0) {
            for (int i = 0; i < getChildCount(); i++) {
                View v = getChildAt(i);
                if(v.getTag()!=null &&v.getTag().equals("加載")) {
                    int left  =(getWidth()-v.getMeasuredWidth())/2;
                    int top  =(getHeight()-v.getMeasuredHeight())/2;
                    v.layout(left,top+bitmap.getHeight(),
                            v.getMeasuredWidth()+left,
                            v.getMeasuredHeight()+top+bitmap.getHeight());
                }
            }
        }
        if(complete){
            super.onLayout(changed,l,t,r,b);
        }
    }

    @Override
    public void onDraw(Canvas c) {
        Log.d("RecyclerView", "onDraw");
        if (getChildCount() > 0) {
            View v = getChildAt(0);
           if(v.getTag()!=null &&v.getTag().equals("加載")) {
               c.drawColor(Color.GREEN);
               int x = (getWidth() - bitmap.getWidth()) / 2 ;
               int y = (getHeight() - bitmap.getHeight()) / 2;
               c.drawBitmap(bitmap, x, y-200, paint);
                 c.drawText("暫無數據",getWidth()/2,
                                   (getHeight()/2)+bitmap.getHeight()-200,paint);
           }
        }
    }
}

activity使用
image.png

大概思路就是這樣 到此結束

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