Tôi đã tạo một lần xem hình tùy chỉnh. Nó hoạt động tốt nếu bạn sử dụng nó trong scrollview. Nhưng khi tôi cố gắng sử dụng nó trong một recyclerview có một hành vi kỳ lạ tôi quan sát thấy. Hình ảnh không được vẽ và hiển thị khoảng cách (xem hình ảnh thứ nhất) trừ khi bạn cuộn xuống (xem hình ảnh thứ 2). Điều tương tự cũng xảy ra khi bạn cuộn lên.RecyclerView với các mục có hình dạng tùy chỉnh
Tôi muốn biết cách tránh những khoảng trống này. Bạn có thể vui lòng chỉ cho tôi nơi tôi đang làm sai? Cảm ơn đã giúp đỡ.
trạng thái ban đầu hoặc sau khi di chuyển lên:
Sau khi di chuyển xuống:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
/**
* Created by santalu on 7/4/17.
*/
public class DiagonalImageView extends AppCompatImageView {
public static final int TOP = 0;
public static final int MIDDLE = 1;
public static final int BOTTOM = 2;
private final Path mClipPath = new Path();
private final Path mLinePath = new Path();
private final Paint mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mPosition;
private int mOverlap;
private int mLineColor;
private int mLineSize;
private boolean mMaskEnabled = true;
public DiagonalImageView(Context context) {
super(context);
init(context, null);
}
public DiagonalImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if (attrs == null) {
return;
}
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ShowCaseImageView);
try {
mPosition = a.getInt(R.styleable.DiagonalImageView_di_position, TOP);
mOverlap = a.getDimensionPixelSize(R.styleable.DiagonalImageView_di_overlap, 0);
mLineSize = a.getDimensionPixelSize(R.styleable.DiagonalImageView_di_lineSize, 0);
mLineColor = a.getColor(R.styleable.DiagonalImageView_di_lineColor, Color.BLACK);
mLinePaint.setColor(mLineColor);
mLinePaint.setStyle(Style.STROKE);
mLinePaint.setStrokeWidth(mLineSize);
} finally {
a.recycle();
}
}
public void setPosition(int position, boolean maskEnabled) {
mMaskEnabled = maskEnabled;
setPosition(position);
}
public void setPosition(int position) {
if (mPosition != position) {
mClipPath.reset();
mLinePath.reset();
}
mPosition = position;
}
@Override protected void onDraw(Canvas canvas) {
int saveCount = canvas.getSaveCount();
canvas.clipPath(mClipPath);
super.onDraw(canvas);
canvas.drawPath(mLinePath, mLinePaint);
canvas.restoreToCount(saveCount);
}
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (!changed) {
return;
}
if (mMaskEnabled && mClipPath.isEmpty()) {
int width = getMeasuredWidth();
int height = getMeasuredHeight();
if (width <= 0 || height <= 0) {
return;
}
switch (mPosition) {
case TOP:
mClipPath.moveTo(0, 0);
mClipPath.lineTo(width, 0);
mClipPath.lineTo(width, height - mOverlap);
mClipPath.lineTo(0, height);
mLinePath.moveTo(0, height);
mLinePath.lineTo(width, height - mOverlap);
break;
case MIDDLE:
mClipPath.moveTo(0, mOverlap);
mClipPath.lineTo(width, 0);
mClipPath.lineTo(width, height - mOverlap);
mClipPath.lineTo(0, height);
mLinePath.moveTo(0, height);
mLinePath.lineTo(width, height - mOverlap);
break;
case BOTTOM:
mClipPath.moveTo(0, mOverlap);
mClipPath.lineTo(width, 0);
mClipPath.lineTo(width, height);
mClipPath.lineTo(0, height);
break;
}
mClipPath.close();
mLinePath.close();
}
}
}
tôi bao gồm các ứng dụng mẫu ở đây để chứng minh vấn đề này nếu bạn quan tâm
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.santalu.showcaseimageview.ShowCaseImageView;
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int overlap = getResources().getDimensionPixelSize(R.dimen.overlap_size);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new OverlapItemDecoration(-overlap));
recyclerView.setAdapter(new SampleAdapter(this));
}
static class SampleAdapter extends RecyclerView.Adapter<SampleAdapter.ViewHolder> {
private final Context mContext;
SampleAdapter(Context context) {
mContext = context;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item, parent, false));
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override public int getItemCount() {
return 7;
}
class ViewHolder extends RecyclerView.ViewHolder {
DiagonalImageView image;
//int overlap;
ViewHolder(View itemView) {
super(itemView);
image = (DiagonalImageView) itemView.findViewById(R.id.image);
//overlap = -mContext.getResources().getDimensionPixelSize(R.dimen.overlap_size);
}
void bind(int position) {
boolean maskEnabled = getItemCount() > 1;
//MarginLayoutParams params = (MarginLayoutParams) image.getLayoutParams();
if (position == 0) {
image.setPosition(ShowCaseImageView.TOP, maskEnabled);
//params.setMargins(0, 0, 0, 0);
} else if (position == getItemCount() - 1) {
image.setPosition(ShowCaseImageView.BOTTOM, maskEnabled);
//params.setMargins(0, overlap, 0, 0);
} else {
image.setPosition(ShowCaseImageView.MIDDLE, maskEnabled);
//params.setMargins(0, overlap, 0, 0);
}
//image.setLayoutParams(params);
}
}
}
static class OverlapItemDecoration extends RecyclerView.ItemDecoration {
private int mOverlap;
OverlapItemDecoration(int overlap) {
mOverlap = overlap;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (parent.getChildAdapterPosition(view) != 0) {
outRect.top = mOverlap;
}
}
}
}
item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.santalu.diagonalimageview.DiagonalImageView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="@dimen/image_height"
android:scaleType="centerCrop"
android:src="@drawable/demo"
app:csi_lineColor="@color/deep_orange"
app:csi_lineSize="@dimen/line_size"
app:csi_overlap="@dimen/overlap_size"/>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Cảm ơn đã nhận xét. Tôi biết thư viện này. Nhưng như bạn có thể thấy từ ảnh chụp màn hình tôi cung cấp các mục recyclerview chồng chéo nhau và tất cả các mục có chia riêng của họ (đường màu cam). Và đường dẫn clip của tưởng tượng và đường phân chia được tính bằng chiều cao chồng chéo không phải là góc để đảm bảo mỗi mục đều tôn trọng các liên kết của chúng và được vẽ chính xác. Tôi chỉ muốn biết có gì sai với chế độ xem của tôi hoặc triển khai recyclerview. Nhưng cảm ơn cho đề xuất – santalu
Bên cạnh đó cùng một vấn đề xảy ra với thư viện này quá. Hãy thử sử dụng nó trong recyclerview. – santalu
bạn đã đặt vị trí đường chéo, trong XML phải giống như đường chéo này: diagonal_position = "bottom". Tôi không chắc chắn, nhưng nếu bạn kiểm tra chỉ số cuối cùng hơn bạn có thể sử dụng bố trí khác nhau cho nó, nơi trong đó vị trí chéo được thiết lập để dưới cùng. – farhana