RecyclerView粘性頭部

法1:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                //  獲取第一個item
                View itemHeader = recyclerView.getChildAt(0);

                tvMainHead.setVisibility(View.VISIBLE);
                tvMainHead.setText(itemHeader.getContentDescription());

                ViewGroup view = (ViewGroup) recyclerView.findChildViewUnder(rlMainHead.getWidth(),rlMainHead.getHeight()+1);

                if(view != null){
                    int deltY = view.getTop()-rlMainHead.getHeight();

                    if(view.getChildAt(0).getVisibility() == View.VISIBLE) {
                        if (deltY < 0 && Math.abs(deltY) <= rlMainHead.getHeight()) {
                            rlMainHead.setTranslationY(deltY);
                        } else {
                            rlMainHead.setTranslationY(0);
                        }
                    }else {
                        rlMainHead.setTranslationY(0);

                    }
                }

            }
        });
@Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        MyViewHolder myViewHolder = (MyViewHolder)holder;
        GroupStr groupStr = list.get(position);

        if(position == 0){
            myViewHolder.rlHead.setVisibility(View.VISIBLE);
        } else {
            if(!groupStr.getGroupName().equals(list.get(position-1).getGroupName())){
                myViewHolder.rlHead.setVisibility(View.VISIBLE);
            } else {
                myViewHolder.rlHead.setVisibility(View.GONE);
            }
        }

        myViewHolder.tvHead.setText(groupStr.getGroupName());
        myViewHolder.tvContent.setText(groupStr.getText());
        myViewHolder.item.setContentDescription(groupStr.getGroupName());
        myViewHolder.item.setTag(groupStr.getGroupName()+position);

    }
<RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/account_pull_rv"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginBottom="300dp"/>

                    <RelativeLayout
                        android:id="@+id/rl_main_head"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:background="@color/color_e1faf7">

                        <TextView
                            android:id="@+id/tv_main_head"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="1st head"
                            android:padding="10dp"
                            android:textSize="16sp"/>
                    </RelativeLayout>

                </RelativeLayout>

法2:

利用ItemDecoration,當Head的高度大於Item高度時有點小瑕疵,但不影響使用

    recyclerView.addItemDecoration(decoration);
public class MyDecoration extends RecyclerView.ItemDecoration {

    private Paint mPaint;
    private Paint textPaint;
    private float offset = 200;
    private List<GroupStr> list;

    public MyDecoration(List<GroupStr> list ) {

        this.list = list;

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);

        textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setColor(Color.BLACK);
        textPaint.setTextSize(80);
    
    }

    //before the item views are drawn,在繪製item之前調用,會被item view蓋掉
    //getItemOffsets 是針對每一個 ItemView,而 onDraw 方法卻是針對 RecyclerView 本身,
    // 所以在 onDraw 方法中需要遍歷屏幕上可見的 ItemView,分別獲取它們的位置信息
//    @Override
//    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
//        super.onDraw(c, parent, state);
//
//        for(int i=0;i<parent.getChildCount();i++){
//
//            View child = parent.getChildAt(i);
//            int index = parent.getChildAdapterPosition(child);
//            if(!list.get(index).isHead()){
//                continue;
//            }
////            if(parent.getChildAdapterPosition(child) != 0) {
//                float topDivide = child.getTop() - offset;
//                float bottomDivide = child.getTop();
//                float leftDivide = parent.getPaddingLeft();
//                float rightDivide = parent.getWidth() - parent.getPaddingRight();
//
//                c.drawRect(leftDivide, topDivide, rightDivide, bottomDivide, mPaint);
//                c.drawText(list.get(index).getGroupName(),leftDivide+100,bottomDivide-100,textPaint);
////                c.drawCircle(left/2,(child.getBottom()-child.getTop())/2+child.getTop(),10,mPaint);
////            }
//
////            c.drawLine(left/2,child.getTop() - 1,left/2,child.getBottom(),mPaint);
//        }
//    }

    //after the item views are drawn,繪製item之後調用,能蓋item view
    @Override
    public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        super.onDrawOver(c, parent, state);

        for(int i=0;i<parent.getChildCount();i++){

            View child = parent.getChildAt(i);

            int index = parent.getChildAdapterPosition(child);

            float leftDivide = parent.getPaddingLeft();
            float rightDivide = parent.getWidth() - parent.getPaddingRight();


            //非第一個item但是組內第一個時畫頭部
            if(i!= 0 && list.get(index).isHead()){

                float topDivide = child.getTop() - offset;
                float bottomDivide = child.getTop();

                c.drawRect(leftDivide, topDivide, rightDivide, bottomDivide, mPaint);
             
                c.drawText(list.get(index).getGroupName(),leftDivide+100,bottomDivide-100,textPaint);

            }else if(i == 0){
                Log.d("zyy","index = 0");
                //當child是屏幕上第一個可見的 ItemView 時,畫頂部粘性頭部

                float topDivide,bottomDivide;
                topDivide = parent.getPaddingTop();
                bottomDivide = topDivide + offset;

                //組別裏的最後一個
                if(!list.get(index).getGroupName().equals(list.get(index+1).getGroupName())){

                    if(child.getBottom() <  bottomDivide){
                        topDivide = topDivide - (bottomDivide - child.getBottom());
                    }

                }

                bottomDivide = topDivide + offset;


                c.drawRect(leftDivide, topDivide, rightDivide, bottomDivide, mPaint);
          
                c.drawText(list.get(index).getGroupName(),leftDivide+100,bottomDivide-100,textPaint);
            }

        }
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        int index = parent.getChildAdapterPosition(view);
        if(list.get(index).isHead()){
            outRect.top = (int) offset;
        }

    }
}

 

 

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