【问题标题】:How I can to do a custom TextView selectable in Android?如何在 Android 中选择自定义 TextView?
【发布时间】:2019-11-21 23:15:58
【问题描述】:

我在 Android 中有一个自定义的TextView,我试图做到这一点“可选择”,但它不起作用。

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#e5d8bf"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <org.deiverbum.app.utils.ZoomTextView
            android:id="@+id/tv_Zoomable"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/app_name"
            android:fontFamily="@font/roboto_regular"
            android:textColor="#272626"
            android:textIsSelectable="true"
            android:textSize="@dimen/default_font" />
    </ScrollView>
</RelativeLayout>

我尝试以编程方式执行此操作,但一无所获...

    mTextView.setTextIsSelectable(true);

我在类的构造函数中尝试:

public class ZoomTextView extends android.support.v7.widget.AppCompatTextView implements View.OnTouchListener {
    //....

    public ZoomTextView(Context context) {
        super(context);
        this.setTextIsSelectable(true);
    }

    public ZoomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setTextIsSelectable(true);
    }

    public ZoomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.setTextIsSelectable(true);
    }

    // ....

我怎样才能做到这个自定义文本视图可选?

编辑:新的自定义类

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;    

public class ZoomTextView extends android.support.v7.widget.AppCompatTextView implements View.OnTouchListener {
    final static float STEP = 200;
    private static final String TAG = "ZoomTextView";
    float mRatio = 13.0f;
    int mBaseDist;
    float mBaseRatio;
    private float zoomLimit = 7.0f;


    public ZoomTextView(Context context) {
        super(context);
        this.setTextIsSelectable(true);
        //    initialize();
    }

    public ZoomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setTextIsSelectable(true);

        //     initialize();
    }

    public ZoomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.setTextIsSelectable(true);
        //       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;
    }
*/
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        if (event.getPointerCount() == 2) {
            int action = event.getAction();
            int pureaction = action & MotionEvent.ACTION_MASK;
            if (pureaction == MotionEvent.ACTION_POINTER_DOWN) {
                mBaseDist = getDistance(event);
                mBaseRatio = mRatio;
            } else {
                float delta = (getDistance(event) - mBaseDist) / STEP;
                float multi = (float) Math.pow(2, delta);
                mRatio = Math.min(1024.0f, Math.max(0.1f, mBaseRatio * multi));
                this.setTextSize(mRatio + 13);
            }
        }
        return true;

    }

    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));
    }

    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }
    protected void onDraw (Canvas canvas) {
        super.onDraw(canvas);
    }


    @Override
    public void setTextIsSelectable(boolean selectable) {
        super.setTextIsSelectable(selectable);
    }

    @Override
    public boolean isTextSelectable() {
        return super.isTextSelectable();
    }
    
}

【问题讨论】:

  • 您想像点击一样选择文本视图并执行一些操作吗?还是禁用选择?
  • @Jacks 我想做 TextView selectable,选择他的部分内容复制到剪贴板。
  • 答案已更新,请尝试从 Activity 或直接在自定义视图类中设置真或假
  • 你能在这里编辑你最新的 ZoomTextView 课程吗?
  • @Jacks 我在问题末尾添加了新版本的课程。

标签: android textview android-custom-view


【解决方案1】:

您的onTouchEvent() 干扰了自定义视图中文本的可选择性。您可以通过将以下内容添加到onTouchEvent() 的开头来使自定义视图文本可选:

super.onTouchEvent(event);

这可能足以解决您的问题,但它可能会破坏您在onTouchEvent() 中尝试做的其他事情。尝试以下方法来合并文本选择和缩放:

public boolean onTouchEvent(@NonNull MotionEvent event) {
    if (event.getPointerCount() == 2) {
        int action = event.getAction();
        int pureaction = action & MotionEvent.ACTION_MASK;
        if (pureaction == MotionEvent.ACTION_POINTER_DOWN) {
            mBaseDist = getDistance(event);
            mBaseRatio = mRatio;
        } else {
            float delta = (getDistance(event) - mBaseDist) / STEP;
            float multi = (float) Math.pow(2, delta);
            mRatio = Math.min(1024.0f, Math.max(0.1f, mBaseRatio * multi));
            this.setTextSize(mRatio + 13);
        }
    } else {
        return super.onTouchEvent(event);
    }
    return true;
}

如果您不清楚 Android 触摸事件的工作原理,请查看以下内容:

Input Events Overview
How are Android touch events delivered?

【讨论】:

  • onTouchEvent() 中我更改了TextView 的字体大小。此类用于一种 pinch to zoom 以增加或减少字体大小。 .
  • 哇,它现在工作正常。我可以选择并且可以通过捏缩放来更改字体大小。非常感谢!
【解决方案2】:

为此,您可以覆盖以下方法并在实现活动中使用它。

public class CustomTextView extends TextView {

    public CustomTextView(Context context) {
        super(context);
    }

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

    public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    protected void onDraw (Canvas canvas) {
        super.onDraw(canvas);
    }

    @Override
    public void setTextIsSelectable(boolean selectable) {
        super.setTextIsSelectable(selectable);
    }

    @Override
    public boolean isTextSelectable() {
        return super.isTextSelectable();
    }
}

如果您从 Activity 进行更改,这是正确的方法,您可以执行以下操作。

声明部分

CustomTextView customTextView;

在实现部分。

 customTextView = findViewById(R.id.customText);
            customTextView.setTextIsSelectable(true);

XML 文件应该是这样的。

 <com.app.yourapp.CustomTextView
        android:id="@+id/customText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CUSTOM"/>

【讨论】:

  • 谢谢杰克。我将这些方法添加到自定义类中,但不起作用。我从 XML 和代码中设置了可选项,但没有任何反应:(
  • 只能从答案中显示的代码中设置。不需要从 xml 集中选择。
  • 是的,我明白了。我尝试了两个选项:从 XML 中设置可选,而不是从 XML 中设置可选并且不起作用。
【解决方案3】:

试试这个:

mTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mTextView.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
            }
        });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    • 2017-08-18
    • 2017-02-22
    • 1970-01-01
    相关资源
    最近更新 更多