我如何才能在 Android 中选择自定义 TextView?

How I can to do a custom TextView selectable in Android?

我在 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);

然后我在 class 的构造函数中尝试:

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

    // ....

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

编辑:新习惯 class

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

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

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"/>

您的 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?

试试这个:

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