展开和折叠项目时,RecyclerView 中的分隔线表现得很奇怪

问题描述

在展开和折叠我的 Recyclerview 项目时,分隔线多次绘制或被项目透支。

此外,在展开和折叠视图时,分隔线的厚度也在减少。

我的问题是每次在 Recyclerview 中展开和折叠项目时都会绘制分隔线。 那么如果已经绘制了分隔线,是否可以防止绘制分隔线? 展开项目时,分隔线会根据视图移动。?

下面是我用于分隔线的 RecyclerView 装饰类,

public  class Separatordecoration extends RecyclerView.Itemdecoration {

    private final Paint mPaint;

    /**
     * Create a decoration that draws a line in the given color and width between the items in the view.
     * @param context  a context to access the resources.
     * @param color    the color of the separator to draw.
     * @param heightDp the height of the separator in dp.
     */
    public Separatordecoration(@NonNull Context context,@ColorInt int color,@FloatRange(from = 0,fromInclusive = false) float heightDp) {
        mPaint = new Paint();
        mPaint.setColor(color);
        final float thickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,heightDp,context.getResources().getdisplayMetrics());
        mPaint.setstrokeWidth(thickness);
    }

    @Override
    public void getItemOffsets(Rect outRect,View view,RecyclerView parent,RecyclerView.State state) {
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
        // we want to retrieve the position in the list
        final int position = params.getViewAdapterPosition();
        // and add a separator to any view but the last one
        if (position <state.getItemCount()) {
            outRect.set(40,40,(int) mPaint.getstrokeWidth()); // left,top,right,bottom
        } else {
            outRect.setEmpty(); // 0,0
        }
    }

    @Override
    public void onDrawOver(@NonNull Canvas c,@NonNull RecyclerView parent,@NonNull RecyclerView.State state) {
        final int offset = (int) (mPaint.getstrokeWidth() / 2);

        // this will iterate over every visible view
        for (int i = 0; i < parent.getChildCount(); i++) {
            // get the view
            final View view = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
            // get the position
            final int position = params.getViewAdapterPosition();

            // and finally draw the separator
            if (position < parent.getChildCount()) {
                final int ty = (int)(view.getTranslationY() + 0.5f);
                final int top = view.getBottom() - params.bottomMargin + ty;
                final int bottom = top + (int) mPaint.getstrokeWidth();
                c.drawLine(view.getLeft(),view.getBottom() + offset,view.getRight(),mPaint);
            }

        }
    }
}

下面是我的 RecyclerView Adapter 类,



public class displayNotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

        private Context context;
        private List<NotificationDetails> notificationRecords;

        private DeleteNotificationListener deleteNotificationListener;


        private String TAG = displayNotificationAdapter.class.getSimpleName();


        

        interface DeleteNotificationListener {
            void updateNotificationList(List<NotificationDetails> details);
        }

        public displayNotificationAdapter(Context context,DeleteNotificationListener listener,List < NotificationDetails > notificationRecordsList) {
            this.context = context;
            this.deleteNotificationListener = listener;
            this.notificationRecords = notificationRecordsList;
        }


        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder (@NonNull ViewGroup parent,int viewType){
            LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
            AndroidLogger.log(5,TAG,"oncreate");
            View listItem = layoutInflater.inflate(R.layout.display_notification_recycler_view_list_item,parent,false);
            return new NotificationViewHolder(listItem);
        }

        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onBindViewHolder (@NonNull RecyclerView.ViewHolder holder,int position){
            
            NotificationDetails notification = notificationRecords.get(position);
            NotificationViewHolder viewHolder = (NotificationViewHolder) holder;
            String currentDateString = DateFormat.getDateInstance().format(Long.parseLong(notification.getTimeStamp()));
           
            String filePath=generateFilePath(notification.getFileName());
            Bitmap myBitmap = BitmapFactory.decodeFile(filePath);
            @SuppressLint("SimpleDateFormat")
            DateFormat dateFormat = new SimpleDateFormat("hh:mm aa");
            
            
            String time = dateFormat.format(Long.parseLong(notification.getTimeStamp()));
           
            if (notification.isExpanded()) {
                viewHolder.expandCollapseImageView.setimageDrawable(context.getDrawable(ImageDrawable.getDrawable("Up Arrow")));
                expandView(viewHolder.notificationImageview);
               
            }
            else {
                viewHolder.expandCollapseImageView.setimageDrawable(context.getDrawable(ImageDrawable.getDrawable("Down Arrow")));
                collapseView(viewHolder.notificationImageview);
            }
            viewHolder.notificationImageview.setimageBitmap(myBitmap);
            viewHolder.notificationTextView.setText(notification.getMessage());
            viewHolder.notificationTimeTextView.setText(time);
            Calendar Now = Calendar.getInstance();
            Calendar date = Calendar.getInstance();
            date.setTimeInMillis(Long.parseLong(notification.getTimeStamp()));
           
            viewHolder.expandCollapseImageView.setonClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(notification.isExpanded()) {
                        notification.setExpanded(false);
                        viewHolder.expandCollapseImageView.setimageDrawable(context.getDrawable(ImageDrawable.getDrawable("Down Arrow")));
                       
                        viewHolder.notificationTextView.setMaxLines(1);
                        notifyItemChanged(position);
                    }
                    else {
                        notification.setExpanded(true);
                        viewHolder.expandCollapseImageView.setimageDrawable(context.getDrawable(ImageDrawable.getDrawable("Up Arrow")));
                      
                        viewHolder.notificationTextView.setMaxLines(Integer.MAX_VALUE);
                        notifyItemChanged(position);
                    }
                }
            });

            if (Now.get(Calendar.DATE) == date.get(Calendar.DATE))
                viewHolder.notificationDateTextView.setText("Today");
            else if (Now.get(Calendar.DATE) - date.get(Calendar.DATE) == 1)
                viewHolder.notificationDateTextView.setText("Yesterday");
            else
                viewHolder.notificationDateTextView.setText(currentDateString);
            if(notification.getTitle()==null)
                viewHolder.notificationTitleTextView.setText("title");
            else
                viewHolder.notificationTitleTextView.setText(notification.getTitle());
        }

    private String generateFilePath(String fileName) {
        
        File imageFileDirectory = context.getDir("image",Context.MODE_PRIVATE); //Creating an internal dir;
        if (!imageFileDirectory.exists()) {
            imageFileDirectory.mkdirs();
        }
        /*
         * app server provide "U" file name after we set read status they provide same file name as "R"
         */
        String createFilePath = imageFileDirectory + "/" + fileName;
       
        return createFilePath;
    }


    public void removeSingleNotification ( int position){
            DatabaseHelper databaseHelper = new DatabaseHelper(context);
            databaseHelper.deleteSingleNotificationRecord(notificationRecords.get(position).getId());
            notificationRecords.remove(position);
            deleteNotificationListener.updateNotificationList(notificationRecords);
            notifyDataSetChanged();
        }
       
         
        private void removeFromList (String id) {
            for (NotificationDetails detail : notificationRecords) {
                if (detail.getId().equalsIgnoreCase(id))
                    notificationRecords.remove(detail);
            }
        }


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

        public  void expandView(final View v) {
           
            int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getWidth(),View.MeasureSpec.EXACTLY);
            int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
            v.measure(matchParentMeasureSpec,wrapContentMeasureSpec);
            final int targetHeight = v.getMeasuredHeight();

        // Older versions of android (pre API 21) cancel animations for views with a height of 0.
            v.getLayoutParams().height = 1;
            v.setVisibility(View.VISIBLE);
            Animation a = new Animation()
            {
                @Override
                protected void applyTransformation(float interpolatedTime,Transformation t) {
                    v.getLayoutParams().height = interpolatedTime == 1
                            ? ViewGroup.LayoutParams.WRAP_CONTENT
                            : (int)(targetHeight * interpolatedTime);
                    v.requestLayout();
            }

            @Override
            public boolean willChangeBounds() {
                return true;
            }
        };

        // Expansion speed of 1dp/ms
       a.setDuration((int)(targetHeight / v.getContext().getResources().getdisplayMetrics().density));
        
            v.startAnimation(a);
    }

    public  void collapseView(final View v) {
        //collapse(pos);
        final int initialHeight = v.getMeasuredHeight();

        Animation a = new Animation()
        {
            @Override
            protected void applyTransformation(float interpolatedTime,Transformation t) {
                if(interpolatedTime == 1){
                    v.setVisibility(View.GONE);
                }else{
                    v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
                    v.requestLayout();
                }
            }

            @Override
            public boolean willChangeBounds() {
                return true;
            }
        };

        // Collapse speed of 1dp/ms
        a.setDuration((int)(initialHeight / v.getContext().getResources().getdisplayMetrics().density));
       
        v.startAnimation(a);
    }
   
    public static class NotificationViewHolder extends RecyclerView.ViewHolder {
        private TextView notificationTextView,notificationDateTextView,notificationTimeTextView,notificationTitleTextView;
        private ImageView notificationImageview,expandCollapseImageView;
        private ConstraintLayout parent;
        public NotificationViewHolder(@NonNull View itemView) {
            super(itemView);
            notificationTextView = itemView.findViewById(R.id.notification_text_view);
            notificationDateTextView = itemView.findViewById(R.id.notification_date_text_view);
            notificationTimeTextView = itemView.findViewById(R.id.notification_time_text_view);
            notificationTitleTextView = itemView.findViewById(R.id.notification_title_text_view);
            notificationImageview = itemView.findViewById(R.id.notification_image_view);
            expandCollapseImageView = itemView.findViewById(R.id.expand_collapse_arrow);
            parent = itemView.findViewById(R.id.notification_parent);
        }
    }
}

更新 我无法解决这个问题。因此,我没有使用 RecyclerView.Itemdecoration,而是使用了如下所示的 View 内部布局

<View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:id="@+id/view_div"
        android:background="@color/grey"

像上面那样做可以解决问题。 [这是我的屏幕包含问题][1]][1]

https://i.stack.imgur.com/CBY80.jpg

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)