【问题标题】:Zoomable TextView in ScrollViewScrollView 中的可缩放 TextView
【发布时间】:2014-05-24 19:32:51
【问题描述】:

我想做一个TextView,它可以根据捏缩放来改变文本的大小。 TextViewScrollView 内。我有TextView 可以在捏合时进行缩放,但只有当您几乎完全水平地移动手指时。如果捏缩放有垂直组件,则默认为滚动而不是缩放

有没有办法在 ScrollView 上有超过 1 个指针时禁用滚动,然后在指针计数返回 1 或 0 时重新启用滚动?是创建CustomScrollView 小部件的最佳方法还是有更简单的方法?

【问题讨论】:

  • 您实际上是在缩放还是只是更改文本大小?此外,由于 TextView 已经具有滚动功能,因此将其放入 ScrollView 可能会导致问题。只需使用带有 maxLines 属性的 TextView。
  • 我使用的“捏缩放”实际上并没有缩放,它只是改变了文本大小,因为我想保持 TextView 的宽度不变并扩展高度。 ScrollView 不会对我造成任何问题,但即使我将其更改为滚动 TextView,问题仍然保持不变。

标签: android textview scrollview pinchzoom


【解决方案1】:

受此答案的启发https://stackoverflow.com/a/14577399/2014236

scaleGD = new ScaleGestureDetector(this, new simpleOnScaleGestureListener());
mTextView.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getPointerCount() == 1){
            //stuff for 1 pointer
        }else{ //when 2 pointers are present
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // Disallow ScrollView to intercept touch events.
                v.getParent().requestDisallowInterceptTouchEvent(true);
                scaleGD.onTouchEvent(event);
                break;

            case MotionEvent.ACTION_MOVE:
                // Disallow ScrollView to intercept touch events.
                v.getParent().requestDisallowInterceptTouchEvent(true);
                scaleGD.onTouchEvent(event);
                break;

            case MotionEvent.ACTION_UP:
                // Allow ScrollView to intercept touch events.
                v.getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }
        }
        return true;
    }
});

编辑:

//later in the code
public class simpleOnScaleGestureListener extends SimpleOnScaleGestureListener {

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        float size = codedText.getTextSize();
        float factor = detector.getScaleFactor();
        int increase = 0;
        if(factor > 1.0f)
            increase = 2;
        else if(factor < 1.0f)
            increase = -2;

        size += increase;

        codedText.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
        plainText.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);            
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //remembering the favourable text size
        Editor edit = sp.edit();
        edit.putFloat("TXTSIZE", size);
        edit.commit();
        return true;
    }
}

绝不是完美的,但对我来说已经足够好 - 请随时进行改进。

【讨论】:

  • 你能提供更改字体的代码吗,因为我无法弄清楚
  • 对于我的应用来说并不完美但足够好,因为这种体验在应用的生命周期中只可能发生一次或两次。修改是否解决了您的问题?
  • 它是一个 SharedPreferences 对象。这会将大小存储在代码中的其他位置,我下次将大小设置为此值,因此用户不必每次都缩放
  • 当我放置到手指而不移动它时,文本大小会发生变化。你能解决它吗?
  • 老实说,这是一个非常“滞后”的解决方案,您有什么改进的方法吗? @Uwais A
【解决方案2】:

我觉得用起来比较简单:

   textView.setOnTouchListener(new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            if(event.getPointerCount() == 1) {
                Log.d("Scroll","1-pointer touch");
                v.getParent().requestDisallowInterceptTouchEvent(false);

            }
            if(event.getPointerCount() == 2){
                Log.d("Zoom","2-pointer touch");
                v.getParent().requestDisallowInterceptTouchEvent(true);

            }
            return false;
        }
    });

【讨论】:

  • 它不再起作用了,我在滚动视图内的 textView 上使用了您的解决方案,它不起作用,抱歉
【解决方案3】:

这是来自 android-dev 博客的一个很好的示例代码,展示了如何实现手指捏合。

Android touch example

您不能禁用滚动条的滚动功能,除非您不覆盖 onTouchEvent 方法以在您的条件下返回 false。这里有几个线程可以帮助您了解如何禁用滚动视图中的滚动。

How to disable scrolling in ScrollView when the viewSwitcher is enabled?

How to disable ScrollView scrolling?

Disable ScrollView Programmatically?

谢谢你:)

【讨论】:

    【解决方案4】:

    我正在使用这个解决方案。 此vídeo中的缩放算法的功劳

    使用不带 ScrollView 的 TextView,只需使用 android:scrollbars="vertical"

            <TextView
            android:id="@+id/activity_content_text_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_weight="1"
            android:gravity="fill"
            android:textSize="8pt"
            android:scrollbars="vertical"
            />
    

    Java:

    public class MainActivity extends Activity implements View.OnTouchListener {
    
       private TextView textContent = null;
       private final static float move = 200;
       private float ratio = 1.0f;
       private int baseDist;
       private float baseRatio;
    
       @Override
       protected void onCreate(@Nullable Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.teste_layout);
           textContent = findViewById(R.id.activity_content_text_content);
           textContent.setText("Lorem ipsum dolor sit amet......");
    
           textContent.setMovementMethod(new ScrollingMovementMethod());
           textContent.setOnTouchListener(this);
        }
    
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return onTouchEvent(event);
        }
    
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if(event.getPointerCount() == 2){
    
                int action = event.getAction();
                int mainAction = action&MotionEvent.ACTION_MASK;
    
                if(mainAction == MotionEvent .ACTION_POINTER_DOWN){
                        baseDist = getDisTance(event);
                        baseRatio = ratio;
                    } else {
                        float scale = (getDisTance(event)-baseDist)/move;
                        float factor = (float)Math.pow(2, scale);
                    ratio = Math.min(1024.0f, Math.max(0.1f, baseRatio*factor));
                    textContent.setTextSize(ratio+15);
                }
            } else {
                return false;
            }
            return true;
        }
    
        private int getDisTance(MotionEvent event) {
            int dx = (int) (event.getX(0)-event.getX(1));
            int dy = (int) (event.getY(0)-event.getY(1));
            return (int) (Math.sqrt(dx*dx+dy*dy));
        }
    }
    

    开发者Frevo Studios

    【讨论】:

    • 能否请您从您的回答中删除所有不相关的链接,否则将被视为垃圾邮件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多