android 3 (API <=11) 组件中的新 Selectable TextView [英] new Selectable TextView in android 3 (API <=11) component

查看:37
本文介绍了android 3 (API <=11) 组件中的新 Selectable TextView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

经过漫长而耗时的搜索,我找不到可以在textview中为android API级别<=11选择文本的组件.我写了这个组件,可能对你有帮助:

public class SelectableTextView extends TextView {公共静态 int _SelectedBackgroundColor = 0xffA6D4E1;公共静态 int _SelectedTextColor = 0xff000000;私人 OnTouchListener lastOnTouch;受保护的 int textOffsetStart;受保护的 int textOffsetEnd;私有 OnLongClickListener lastOnLongClick;protected boolean longCliked;受保护的布尔值 isDowned;受保护的 int textSelectedEnd;受保护的 int textSelectedStart;私有静态 SelectableTextView lastInstance;公共 SelectableTextView(上下文上下文){超级(上下文);}公共无效setTextIsSelectable(布尔可选){//待办事项:ANDROID3//if:androidversion>=3//super.setTextIsSelectable(selectable);//别的super.setLongClickable(true);super.setOnLongClickListener(getSelectableLongClick());super.setOnTouchListener(getSelectableOnTouch());}私人 OnLongClickListener getSelectableLongClick() {返回新的 OnLongClickListener() {@覆盖公共布尔 onLongClick(查看 v){longCliked = 真;如果(lastOnLongClick != null){lastOnLongClick.onLongClick(v);}返回真;}};}@覆盖公共无效 setOnTouchListener(OnTouchListener l) {super.setOnTouchListener(l);this.lastOnTouch = l;}@覆盖public void setOnLongClickListener(OnLongClickListener l) {super.setOnLongClickListener(l);this.lastOnLongClick = l;}私有 OnTouchListener getSelectableOnTouch() {返回新的 OnTouchListener() {@覆盖公共布尔 onTouch(查看 v,MotionEvent 事件){int action = event.getAction();如果(动作== MotionEvent.ACTION_DOWN){if (lastInstance == null)lastInstance = SelectableTextView.this;if (lastInstance != null && lastInstance != SelectableTextView.this) {lastInstance.clean();lastInstance = SelectableTextView.this;}int offset = getOffset(event);if ((offset < textOffsetEnd && offset > textOffsetStart)||(offset > textOffsetEnd && offset < textOffsetStart)) {if (textOffsetEnd - offset > offset - textOffsetStart)textOffsetStart = textOffsetEnd;} 别的 {干净的();textOffsetStart = 偏移量;}isDowned = true;} else if (isDowned && longCliked && action == MotionEvent.ACTION_MOVE) {selectTextOnMove(事件);} else if (action == MotionEvent.ACTION_UP) {isDowned = false;longCliked = false;}if (lastOnTouch != null)lastOnTouch.onTouch(v, 事件);返回假;}};}私人无效selectTextOnMove(MotionEvent事件){int offset = getOffset(event);如果(偏移量!= Integer.MIN_VALUE){字符串文本 = getText().toString();SpannableStringBuilder sb = new SpannableStringBuilder(text);BackgroundColorSpan bgc = new BackgroundColorSpan(_SelectedBackgroundColor);ForegroundColorSpan textColor = new ForegroundColorSpan(_SelectedTextColor);int start = textOffsetStart;textOffsetEnd = 偏移量;int end = 偏移量;如果(开始>结束){int temp = 开始;开始=结束;结束 = 温度;}int[] curectStartEnd = curectStartEnd(text, start, end);开始 = curectStartEnd[0];end = curectStartEnd[1];SelectableTextView.this.textSelectedStart = start;SelectableTextView.this.textSelectedEnd = end;sb.setSpan(bgc, 开始, 结束, Spannable.SPAN_INCLUSIVE_INCLUSIVE);sb.setSpan(textColor, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);setText(sb);}}private int[] curectStartEnd(String text, int start, int end) {int length = text.length();while (start < length && start > 0 && text.charAt(start) != ' ') {开始 - ;}while (end < length && text.charAt(end) != ' ') {结束++;}返回新的 int[] { 开始,结束 };}私人 int getOffset(MotionEvent 事件){布局 layout = getLayout();如果(布局==空)返回 Integer.MIN_VALUE;float x = event.getX() + getScrollX();浮动 y = event.getY() + getScrollY();int line = layout.getLineForVertical((int) y);int offset = layout.getOffsetForHorizo​​ntal(line, x);返回偏移量;}受保护的无效清洁(){如果 (this.getText() != null) {this.setText(this.getText().toString());textSelectedStart = 0;textSelectedEnd = 0;}}@覆盖公共 int getSelectionStart() {返回 textSelectedStart;}@覆盖公共 int getSelectionEnd() {返回 textSelectedEnd;}}

getOffset 获取 Touched 用户使用该组件设置这些属性的选定文本偏移量:

 SelectableTextView textView1 = new SelectableTextView(context);textView1.setClickable(false);textView1.setCursorVisible(false);textView1.setOnTouchListener(getOnTextTouch());//文本选择触摸后新增textView1.setEnabled(this.selectable);textView1.setTextIsSelectable(this.selectable);

谁能升级这个组件?

这是git hub中的代码

解决方案

因为这个

还要添加以下两个构造函数一个>

 public SelectableTextView(Context context,AttributeSet attrs){超级(上下文,属性);}public SelectableTextView(Context context,AttributeSet attrs,int defStyle){超级(上下文,属性,defStyle);}

我还在代码中添加了以下内容:

 @SuppressLint("NewApi")公共无效setTextIsSelectable(布尔可选){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)super.setTextIsSelectable(true);别的{super.setLongClickable(true);super.setOnLongClickListener(getSelectableLongClick());super.setOnTouchListener(getSelectableOnTouch());}}

我是这样使用的,没有 OnTouchListener:

txt_copyFrom.setClickable(false);txt_copyFrom.setCursorVisible(false);txt_copyFrom.setEnabled(true);txt_copyFrom.setTextIsSelectable(true);txt_copyFrom.setOnLongClickListener(new OnLongClickListener(){@覆盖公共布尔 onLongClick(查看 v){int start=txt_copyFrom.getSelectionStart();int end=txt_copyFrom.getSelectionEnd();mSelectedText=txt_copyFrom.getText().toString().substring(start, end);Log.d(TAG, "所选文本:"+mSelectedText);返回真;}});

使用 XML:

我想我必须在 OnLongClickListener 中为 Activity 本身的 TextView 设置一个 OnTouchListener.

尝试将 Logs 放在 SelectableTextView 中,它似乎不起作用......我发现 LongClickListener 被调用,但 TouchListener 甚至没有被调用......

在 OnLongClickListener 中设置 OnTouchListener 做了这个

After a long and time consuming search, I can't find a component that can select text in textview for android API level <=11. I have written this component that may be of help to you :

public class SelectableTextView extends TextView {

public static int _SelectedBackgroundColor = 0xffA6D4E1;
public static int _SelectedTextColor = 0xff000000;
private OnTouchListener lastOnTouch;
protected int textOffsetStart;
protected int textOffsetEnd;
private OnLongClickListener lastOnLongClick;
protected boolean longCliked;
protected boolean isDowned;
protected int textSelectedEnd;
protected int textSelectedStart;
private static SelectableTextView lastInstance;

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

public void setTextIsSelectable(boolean selectable) {
    // TODO:ANDROID3
    // if:androidversion>=3
    // super.setTextIsSelectable(selectable);
    // else
    super.setLongClickable(true);
    super.setOnLongClickListener(getSelectableLongClick());
    super.setOnTouchListener(getSelectableOnTouch());
}

private OnLongClickListener getSelectableLongClick() {
    return new OnLongClickListener() {

        @Override
        public boolean onLongClick(View v) {
            longCliked = true;
            if (lastOnLongClick != null) {
                lastOnLongClick.onLongClick(v);
            }
            return true;
        }
    };
}

@Override
public void setOnTouchListener(OnTouchListener l) {
    super.setOnTouchListener(l);
    this.lastOnTouch = l;
}

@Override
public void setOnLongClickListener(OnLongClickListener l) {
    super.setOnLongClickListener(l);
    this.lastOnLongClick = l;
}

private OnTouchListener getSelectableOnTouch() {
    return new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getAction();

            if (action == MotionEvent.ACTION_DOWN) {
                if (lastInstance == null)
                    lastInstance = SelectableTextView.this;
                if (lastInstance != null && lastInstance != SelectableTextView.this) {
                    lastInstance.clean();
                    lastInstance = SelectableTextView.this;
                }

                int offset = getOffset(event);
                if ((offset < textOffsetEnd && offset > textOffsetStart)
                        || (offset > textOffsetEnd && offset < textOffsetStart)) {
                    if (textOffsetEnd - offset > offset - textOffsetStart)
                        textOffsetStart = textOffsetEnd;
                } else {
                    clean();
                    textOffsetStart = offset;
                }
                isDowned = true;
            } else if (isDowned && longCliked && action == MotionEvent.ACTION_MOVE) {
                selectTextOnMove(event);
            } else if (action == MotionEvent.ACTION_UP) {
                isDowned = false;
                longCliked = false;
            }
            if (lastOnTouch != null)
                lastOnTouch.onTouch(v, event);
            return false;
        }

    };
}

private void selectTextOnMove(MotionEvent event) {
    int offset = getOffset(event);
    if (offset != Integer.MIN_VALUE) {
        String text = getText().toString();
        SpannableStringBuilder sb = new SpannableStringBuilder(text);
        BackgroundColorSpan bgc = new BackgroundColorSpan(_SelectedBackgroundColor);
        ForegroundColorSpan textColor = new ForegroundColorSpan(_SelectedTextColor);

        int start = textOffsetStart;
        textOffsetEnd = offset;
        int end = offset;
        if (start > end) {
            int temp = start;
            start = end;
            end = temp;
        }
        int[] curectStartEnd = curectStartEnd(text, start, end);
        start = curectStartEnd[0];
        end = curectStartEnd[1];
        SelectableTextView.this.textSelectedStart = start;
        SelectableTextView.this.textSelectedEnd = end;
        sb.setSpan(bgc, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        sb.setSpan(textColor, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);

        setText(sb);
    }
}

private int[] curectStartEnd(String text, int start, int end) {
    int length = text.length();

    while (start < length && start > 0 && text.charAt(start) != ' ') {
        start--;
    }
    while (end < length && text.charAt(end) != ' ') {
        end++;
    }
    return new int[] { start, end };
}

private int getOffset(MotionEvent event) {
    Layout layout = getLayout();
    if (layout == null)
        return Integer.MIN_VALUE;
    float x = event.getX() + getScrollX();
    float y = event.getY() + getScrollY();
    int line = layout.getLineForVertical((int) y);
    int offset = layout.getOffsetForHorizontal(line, x);
    return offset;
}

protected void clean() {
    if (this.getText() != null) {
        this.setText(this.getText().toString());
        textSelectedStart = 0;
        textSelectedEnd = 0;
    }
}

@Override
public int getSelectionStart() {
    return textSelectedStart;
}

@Override
public int getSelectionEnd() {
    return textSelectedEnd;
}

}

getOffset get the selected offset of text that Touched user for using this component set these attributes:

        SelectableTextView textView1 = new SelectableTextView(context);
    textView1.setClickable(false);
    textView1.setCursorVisible(false);
    textView1.setOnTouchListener(getOnTextTouch());//new after text select touch
    textView1.setEnabled(this.selectable);
    textView1.setTextIsSelectable(this.selectable);

Can anyone upgrade this component?

This is the code in git hub

解决方案

Also add the following two constructors because of this

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

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

I have also added the following to the code:

    @SuppressLint("NewApi")
public void setTextIsSelectable(boolean selectable) {
    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
        super.setTextIsSelectable(true);
    else
    {   
        super.setLongClickable(true);
        super.setOnLongClickListener(getSelectableLongClick());
        super.setOnTouchListener(getSelectableOnTouch());
    }
}

I used it like this,without an OnTouchListener:

txt_copyFrom.setClickable(false);
txt_copyFrom.setCursorVisible(false);
txt_copyFrom.setEnabled(true);
txt_copyFrom.setTextIsSelectable(true);
txt_copyFrom.setOnLongClickListener(new OnLongClickListener(){

    @Override
    public boolean onLongClick(View v) {
        int start=txt_copyFrom.getSelectionStart();
        int end=txt_copyFrom.getSelectionEnd();

        mSelectedText=txt_copyFrom.getText().toString().substring(start, end);
        Log.d(TAG, "Selected text: "+mSelectedText);
        return true;
    }

});

with the XML:

<com.example.clipboardtest.SelectableTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Old Buccaneer1The Old Sea-dog at the Admiral BenbowSquire Trelawney, Dr. Livesey, and the rest of these gentlemen having asked me to write down the whole particulars about Treasure Island, from the beginning to the end, keeping nothing back but the bearings of the island, and that only because there is still treasure not yet lifted, I take up my pen in the year of grace 17--and go back to the time when my father kept the Admiral Benbow inn and the brown old seaman with the sabre cut first took up his lodging under our roof."
    android:id="@+id/txt_copyfrom"
/>         

I guess I have to set an OnTouchListener within the OnLongClickListener for the TextView in the Activity itself.

Tried putting Logs all over the place in SelectableTextView,it does not seem to be working...I find that the LongClickListener is called but the TouchListener is not even called...

Setting the OnTouchListener inside the OnLongClickListener did this

这篇关于android 3 (API &lt;=11) 组件中的新 Selectable TextView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆