首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在RecyclerView中对整个内容进行缩放?

如何在RecyclerView中对整个内容进行缩放?
EN

Stack Overflow用户
提问于 2016-07-05 11:26:03
回答 3查看 4.4K关注 0票数 6

我需要放大/缩小RecyclerView的全部内容。实际上,我需要根据宽度调整所有子视图的大小,并调整每个项中的文本大小。

代码语言:javascript
运行
复制
public class ViewHolder {

    Button btn;

    ...
}

当用户进行缩放时,按钮的文本应该减少到8sp,如果用户继续放大,则会消失。

所以,现在我进退两难:我需要做什么?调整适配器中的项的大小,或在LayoutManager中调整它们的大小,并更新整个适配器。

这两种场景似乎都会影响视觉效果的表现,所以我需要帮助。也许你能给我一个更好的解决方案。

对于2016年11月21日的情况,我找不到任何解决方案。

因此,我决定写我自己的视图,并在每个缩放比例因子变化中重新测量可见视图。

EN

回答 3

Stack Overflow用户

发布于 2016-11-21 10:51:02

您使用哪个适配器?

我尝试了水平LinearLayoutManager,并在适配器中调整了条目的大小:

代码语言:javascript
运行
复制
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
           ...
           final ViewGroup.LayoutParams layoutParams = viewHolder.rootView.getLayoutParams();
           layoutParams.width = getItemWidth(position);   //width calculation using current zoom level
           layoutParams.height = mItemLayoutHeight;
           viewHolder.rootView.setLayoutParams(layoutParams);
           ...

和setZoom(..)活动/片段的方法如下所示:

代码语言:javascript
运行
复制
        public void setZoom(float newValue) {
           int dScroll = (int) ((ADAPTER_ZOOM - newValue) * getResources().getDisplayMetrics().widthPixels/2f);   //assume you Recycler view uses whole display 
           ADAPTER_ZOOM = newValue;
           resetBoundaries();
           //
           epgAdapter.notifyDataSetChanged();
           //
           epgRecyclerView.scrollBy(dScroll, 0);
        }

但是,由于我的自定义LayoutManager性能很差,似乎在LinearLayoutManager中有一个优化列表。

票数 0
EN

Stack Overflow用户

发布于 2021-09-06 12:10:26

要全面实施,请参阅:

github.com/mosayeb-masoumi/zoom_whole_recyclerview

票数 0
EN

Stack Overflow用户

发布于 2017-06-07 06:01:01

使用此代码。它可以很好地放大回收视图的所有内容。

代码语言:javascript
运行
复制
import android.content.Context;
import android.graphics.Canvas;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;

/**
@author yogesh
* */
public class PinchRecyclerView extends RecyclerView {
    private static final int INVALID_POINTER_ID = -1;
    private int mActivePointerId = INVALID_POINTER_ID;
    private ScaleGestureDetector mScaleDetector;
    private float mScaleFactor = 1.f;
    private float maxWidth = 0.0f;
    private float maxHeight = 0.0f;
    private float mLastTouchX;
    private float mLastTouchY;
    private float mPosX;
    private float mPosY;
    private float width;
    private float height;


    public PinchRecyclerView(Context context) {
        super(context);
        if (!isInEditMode())
            mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
    }

    public PinchRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (!isInEditMode())
            mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
    }

    public PinchRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (!isInEditMode())
            mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        try {
            return super.onInterceptTouchEvent(ev);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent ev) {
        super.onTouchEvent(ev);
        final int action = ev.getAction();
        mScaleDetector.onTouchEvent(ev);
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                final float x = ev.getX();
                final float y = ev.getY();
                mLastTouchX = x;
                mLastTouchY = y;
                mActivePointerId = ev.getPointerId(0);
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                /* this line is replaced because here came below isssue
                java.lang.IllegalArgumentException: pointerIndex out of range
                 ref http://stackoverflow.com/questions/6919292/pointerindex-out-of-range-android-multitouch
                */
                //final int pointerIndex = ev.findPointerIndex(mActivePointerId);

                final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                final float x = ev.getX(pointerIndex);
                final float y = ev.getY(pointerIndex);
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;

                if (mPosX > 0.0f)
                    mPosX = 0.0f;
                else if (mPosX < maxWidth)
                    mPosX = maxWidth;

                if (mPosY > 0.0f)
                    mPosY = 0.0f;
                else if (mPosY < maxHeight)
                    mPosY = maxHeight;

                mLastTouchX = x;
                mLastTouchY = y;

                invalidate();
                break;
            }

            case MotionEvent.ACTION_UP: {
                mActivePointerId = INVALID_POINTER_ID;
                break;
            }

            case MotionEvent.ACTION_CANCEL: {
                mActivePointerId = INVALID_POINTER_ID;
                break;
            }

            case MotionEvent.ACTION_POINTER_UP: {
                final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                final int pointerId = ev.getPointerId(pointerIndex);
                if (pointerId == mActivePointerId) {
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    mLastTouchX = ev.getX(newPointerIndex);
                    mLastTouchY = ev.getY(newPointerIndex);
                    mActivePointerId = ev.getPointerId(newPointerIndex);
                }
                break;
            }
        }

        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        canvas.translate(mPosX, mPosY);
        canvas.scale(mScaleFactor, mScaleFactor);
        canvas.restore();
    }

    @Override
    protected void dispatchDraw(@NonNull Canvas canvas) {
        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        if (mScaleFactor == 1.0f) {
            mPosX = 0.0f;
            mPosY = 0.0f;
        }
        canvas.translate(mPosX, mPosY);
        canvas.scale(mScaleFactor, mScaleFactor);
        super.dispatchDraw(canvas);
        canvas.restore();
        invalidate();
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFactor *= detector.getScaleFactor();
            mScaleFactor = Math.max(1.0f, Math.min(mScaleFactor, 3.0f));
            maxWidth = width - (width * mScaleFactor);
            maxHeight = height - (height * mScaleFactor);
            invalidate();
            return true;
        }
    }
}

摘自此StackOverflow答案的代码:Android change recycler view column no. on pinch zoom

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38202268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档