问题描述
在展开和折叠我的 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 (将#修改为@)