使用分隔符实现RecyclerView缩放

时间:2017-07-24 00:47:19

标签: android

我制作了一个缩放的Recyclerview,但是分割器不会随着视图一起缩放,所以即使Recyclerview的内容正在缩放,分割线也会保持相同的高度。如何使用recyclerview使分割器变焦?提前谢谢!

主要活动:

recyclerView = (ZoomRecyclerView) findViewById(R.id.recyclerView);

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);

recyclerViewAdapter = new RecyclerViewAdapter(listOfData);
if (recyclerView!= null) {
    recyclerView.setAdapter(recyclerViewAdapter);
}

Drawable divider = ContextCompat.getDrawable(this, R.drawable.divider);
RecyclerViewDecorator recyclerViewDecorator = new RecyclerViewDecorator(divider);
recyclerView.addItemDecoration(recyclerViewDecorator);

divider.xml可绘制文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size android:height="2dp"></size>
    <solid android:color="@android:color/black"></solid>
</shape>

Recycler View装饰器:

public class RecyclerViewDecorator extends RecyclerView.ItemDecoration {

private Drawable divider;

public RecyclerViewDecorator(Drawable divider) {
    this.divider = divider;
}

@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
    int dividerLeft = parent.getPaddingLeft();
    int dividerRight = parent.getWidth() - parent.getPaddingRight();
    int dividerTop;
    int dividerBottom;

    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount - 1; i++) {
        View child = parent.getChildAt(i);

        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

        dividerTop = child.getBottom() + params.bottomMargin;
        dividerBottom = dividerTop + divider.getIntrinsicHeight();

        divider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
        divider.draw(canvas);
    }
}

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

    if (parent.getChildAdapterPosition(view) == 0) {
        return;
    }

    outRect.top = divider.getIntrinsicHeight();
}
}

缩放回收器视图:

public class ZoomRecyclerView extends RecyclerView {
private ScaleGestureDetector scaleGestureDetector;
private static final String TAG = ZoomRecyclerView.class.getSimpleName();

private float scaleFactor = 1.f;
private static final float minScale = 1.0f;
private static final float maxScale = 3.0f;

public ZoomRecyclerView(Context context, AttributeSet attrs) {
    super(context, attrs);
    scaleGestureDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.OnScaleGestureListener() {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            scaleFactor *= detector.getScaleFactor();

            //makes sure user does not zoom in or out past a certain amount
            scaleFactor = Math.max(minScale, Math.min(scaleFactor, maxScale));

            //refresh the view and compute the size of the view in the screen
            requestLayout();

            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {

        }
    });
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    super.onTouchEvent(event);

    //notify the scaleGestureDetector that an event has happened
    scaleGestureDetector.onTouchEvent(event);

    return true;
}

@Override
protected void dispatchDraw(@NonNull Canvas canvas) {
    canvas.save();

    //scales the display, centered on where the user is touching the display
    canvas.scale(scaleFactor, scaleFactor, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY());

    super.dispatchDraw(canvas);
    canvas.restore();

}

}

1 个答案:

答案 0 :(得分:0)

最后想出来,以防万一其他人面临同样的问题。而不是ItemDecorator中的onDraw()函数,它应该是onDrawOver()。这是因为onDraw()在视图之前绘制了分隔符,而onDrawOver()在视图之后绘制了分隔符,因此当视图缩放时,分隔符将随之改变。