-1

I have a custom TextView in Android and i trying to do this "selectable", but it's not working.

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>

I try to do that programatically and nothing...

    mTextView.setTextIsSelectable(true);

And I try in te constructor of the 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);
    }

    // ....

How i can to do this custom textview selectable?

Edit: New custum 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();
    }
    
}
Community
  • 1
  • 1
A. Cedano
  • 557
  • 7
  • 39

3 Answers3

1

For this you can override the below methods and make use of it in the implementation 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();
    }
}

if you are making the changes from the Activity which is the right approach you can do the following.

Declaration part

CustomTextView customTextView;

In the implementation part.

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

XML file would be like this.

 <com.app.yourapp.CustomTextView
        android:id="@+id/customText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CUSTOM"/>
Jacks
  • 803
  • 1
  • 6
  • 16
  • Thanks Jacks. I added these methods to the custom class, but is not working. I set selectable from XML and from code and nothing happens :( – A. Cedano Nov 22 '19 at 10:30
  • Only from code as shown in the answer you can set. From xml set selectable is not needed. – Jacks Nov 22 '19 at 11:14
  • Yes, I understand. I tryed the two options: setting selectable from XML and not settiing selectable from XML and not works. – A. Cedano Nov 22 '19 at 11:16
1

Your onTouchEvent() is interfering with the selectability of the text in the custom view. You can make the custom view text selectable by adding the following to the start of onTouchEvent():

super.onTouchEvent(event);

This may be enough to solve your problem, but it may break what else you are trying to do in onTouchEvent(). Try the following to incorporate text selection and zooming:

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

If you are unclear how the Android touch events work take a look at these:

Input Events Overview
How are Android touch events delivered?

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • In `onTouchEvent()` I change the font size of the TextView. This class is for one spece of *pinch to zoom* for increase or decrease the font size. . – A. Cedano Dec 06 '19 at 17:18
  • Wow it's working fine now. I can select and I can to change the font size doing pinch to zoom. Thanks a lot! – A. Cedano Dec 08 '19 at 11:59
0

Try this:

mTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mTextView.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
            }
        });
Tahir Ferli
  • 636
  • 4
  • 16