如何平滑地执行放大和缩小以及在 TEXTVIEW 上的特定缩放位置进行缩放?

How to perform Zoom IN and OUT Smoothly and Zooming in specific Zoom location on a TEXTVIEW?

我即将对包含文本的 TextView 执行放大和缩小操作。我可以放大和缩小,但我需要使缩放功能更加流畅(例如在 Chrome 浏览器中缩放页面)。在执行放大和缩小操作(使用捏合缩放方法)时,我正在以居中对齐的方式缩放文本内容,我想缩放我正在放大的内容。 附上我自己做的代码,请各位大侠指教

这是我的 activity 文件:

 public class ZoomTextView extends TextView {
     private static final String TAG = "ZoomTextView";
     private ScaleGestureDetector mScaleDetector;

     private float mScaleFactor = 1.f;
     private float defaultSize;

     private float zoomLimit = 3.0f;


     public ZoomTextView(Context context) {
         super(context);
         initialize();
     }

     public ZoomTextView(Context context, AttributeSet attrs) {
         super(context, attrs);
         initialize();
     }

     public ZoomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         initialize();
     }

     private void initialize() {
         defaultSize = getTextSize();
         mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());

     }

     /***
      * @param zoomLimit
      * Default value is 3, 3 means text can zoom 3 times the default size
      */

     public void setZoomLimit(float zoomLimit) {
         this.zoomLimit = zoomLimit;
     }

     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }

     @Override
     public boolean onTouchEvent(@NonNull MotionEvent ev) {
         super.onTouchEvent(ev);
         mScaleDetector.onTouchEvent(ev);
         return true;
     }

     /*Scale Gesture listener class,
     mScaleFactor is getting the scaling value
     and mScaleFactor is mapped between 1.0 and and zoomLimit
     that is 3.0 by default. You can also change it. 3.0 means text
     can zoom to 3 times the default value.*/

     private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
         @Override
         public boolean onScale(ScaleGestureDetector detector) {
             mScaleFactor *= detector.getScaleFactor();
             mScaleFactor = Math.max(1.0f, Math.min(mScaleFactor, zoomLimit));
             setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultSize * mScaleFactor);
             Log.e(TAG, String.valueOf(mScaleFactor));
             return true;
         }
     } }

这是我的 .xml 文件:

 <noman.zoomtextview.ZoomTextView
     android:layout_width="match_parent"
     android:layout_height="match_parent"

     android:layout_alignParentTop="true"
     android:layout_alignParentLeft="true"
     android:text="@string/sample_string"/> </RelativeLayout>

提前致谢。

我觉得你应该用放大镜,这样

放大镜可以编程方式用于任意视图,如下所示:

View view = findViewById(R.id.view);
Magnifier magnifier = new Magnifier(view);
magnifier.show(view.getWidth() / 2, view.getHeight() / 2);

这里的View可以替换成TextView或者任何特定的view

如果您不介意添加另一个库,请尝试手势视图布局

更具体地说,https://static.javadoc.io/com.alexvasilkov/gesture-views/2.5.2/com/alexvasilkov/gestures/views/GestureFrameLayout.html

基本上,您将文本视图包装在 XML 中的 GestureFrameLayout 中。 它会根据您手指的位置和手势自动检测缩放、捏合和平移。开箱即用不需要额外编码(除非你想实现非默认功能,如旋转、裁剪等)

用法示例在这里https://github.com/alexvasilkov/GestureViews/wiki/Usage

<com.alexvasilkov.gestures.views.GestureFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- GestureFrameLayout can contain only one child -->

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Layout content goes here -->

</FrameLayout>

我已经为可以有多个子视图(包括任何类型的视图和文本视图)的视图进行了缩放 In/Out。

My Project

我使用 ScaleX 和 ScaleY api 缩放父视图。

private fun applyScaleAndTranslationToChild() {
        child().scaleX = scaleFactor
        child().scaleY = scaleFactor
        child().pivotX = 0f  // default is to pivot at view center
        child().pivotY = 0f  // default is to pivot at view center
        child().translationX = translateX
        child().translationY = translateY
    }

以上方法用于应用放大和缩小,并且缩放的焦点也是固定的。

我使用 ScaleGestureListener 来获取比例(捏合手势被这个捕获)

inner class ScaleListner : ScaleGestureDetector.SimpleOnScaleGestureListener() {

        override fun onScale(scaleDetector: ScaleGestureDetector?): Boolean {
            val scaleFactor = scaleDetector!!.scaleFactor
            setScaleAndTranslation(scaleFactor, scaleDetector.focusX, scaleDetector.focusY)
            return true
        }

        override fun onScaleEnd(detector: ScaleGestureDetector?) {
            super.onScaleEnd(detector)
            setLayoutParamOfChild()
        }

        private fun setScaleAndTranslation(scaleFactor: Float, focusX: Float, focusY: Float) {
            if (lastScaleFactor == 0f || Math.signum(scaleFactor) == Math.signum(lastScaleFactor)) {
                val prevScale = this@ZoomView.scaleFactor
                this@ZoomView.scaleFactor *= scaleFactor
                this@ZoomView.scaleFactor = Math.max(MIN_ZOOM, Math.min(this@ZoomView.scaleFactor, MAX_ZOOM))
                lastScaleFactor = scaleFactor
                val adjustedScaleFactor = this@ZoomView.scaleFactor / prevScale
                // added logic to adjust translateX and translateY for pinch/zoom pivot point
                translateX += (translateX - focusX) * (adjustedScaleFactor - 1)
                translateY += (translateY - focusY) * (adjustedScaleFactor - 1)
            } else {
                lastScaleFactor = 0f
            }
            isSingleTapConfirmed = false
        }
    }

参考我的问题,所有细节都在这里。