Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何使EditText具有可单击的可扩展项,并且仍然可以通过长单击进行选择?_Android_Android Edittext_Onclicklistener_Spannablestring - Fatal编程技术网

Android 如何使EditText具有可单击的可扩展项,并且仍然可以通过长单击进行选择?

Android 如何使EditText具有可单击的可扩展项,并且仍然可以通过长单击进行选择?,android,android-edittext,onclicklistener,spannablestring,Android,Android Edittext,Onclicklistener,Spannablestring,我有一个文本视图,其跨度类型为ClickableStringSpan,定义如下: public class ClickableStringSpan extends ClickableSpan { private View.OnClickListener mListener; int color; public ClickableStringSpan(View.OnClickListener listener,int color) { mListener =

我有一个文本视图,其跨度类型为ClickableStringSpan,定义如下:

public class ClickableStringSpan extends ClickableSpan {
    private View.OnClickListener mListener;
    int color;
    public ClickableStringSpan(View.OnClickListener listener,int color) {
        mListener = listener;
        this.color = color;

    }

    @Override
    public void onClick(View v) {
        mListener.onClick(v);
    }

       @Override public void updateDrawState(TextPaint ds) {
           super.updateDrawState(ds);
           ds.setUnderlineText(false);
           ds.setColor(color);
       }
}
我在我的文本上设置了可单击的跨距,如下所示:

spanStr.setSpan(new ClickableString(new linkedTextClickListener(), linkColor),
                        startIndex, endIndex,
                        SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
现在我想将这些字符串应用于EditText,而不是TextView。一切都很好,只是现在不再单击可单击的字符串。我想知道如何将这种跨度上的单击传递给指定的clicklistener


更新:我主要关心的是编辑文本,我希望允许用户选择文本的某些部分并共享它,同时他/她可以单击可单击的跨度。

下面的代码示例应该适用于您,我还测试了它,它为您提供了
可单击的跨度字符串的单击事件。

可能是您忘记添加
setMovementMethod

    EditText spanEditText = (EditText)rootView.findViewById(R.id.edtEmailId);

    // this is the text we'll be operating on  
    SpannableStringBuilder text = new SpannableStringBuilder("World Super Power God LOVE");  

    // make "World" (characters 0 to 5) red  
    text.setSpan(new ForegroundColorSpan(Color.RED), 0, 5, 0); 

    // make "Super" (characters 6 to 11) one and a half time bigger than the textbox  
    text.setSpan(new RelativeSizeSpan(1.5f), 6, 11, 0);  

    // make "Power" (characters 12 to 17) display a toast message when touched  
    final Context context = getActivity().getApplicationContext();  
    ClickableSpan clickableSpan = new ClickableSpan() {  
        @Override  
        public void onClick(View view) {  
            Toast.makeText(context, "Power", Toast.LENGTH_LONG).show();  
        }  
    };  
    text.setSpan(clickableSpan, 12, 17, 0);  

    // make "God" (characters 18 to 21) struck through  
    text.setSpan(new StrikethroughSpan(), 18, 21, 0);  

    // make "LOVE" (characters 22 to 26) twice as big, green and a link to this site.  
    // it's important to set the color after the URLSpan or the standard  
    // link color will override it.  
    text.setSpan(new RelativeSizeSpan(2f), 22, 26, 0);  
    text.setSpan(new ForegroundColorSpan(Color.GREEN), 22, 26, 0);  

    // make our ClickableSpans and URLSpans work  
    spanEditText.setMovementMethod(LinkMovementMethod.getInstance());  

    // shove our styled text into the TextView          
    spanEditText.setText(text, BufferType.EDITABLE);
//试试这个方法,希望对你有帮助。。。
**activity.xml**代码
**活动**代码
私人编辑文本edtText1;
私人编辑文本edtText2;
私人编辑文本edtText3;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
edtText1=(EditText)findViewById(R.id.edtText1);
edtText2=(EditText)findViewById(R.id.edtText2);
edtText3=(EditText)findViewById(R.id.edtText3);
String string1=“先演示编辑文本”;
edtText1.setText(setSpanColor(string1,“First”,R.color.orange,新的spannableclicklinklistener()){
@凌驾
公共void onClickListener(视图){
view.performClick();
}
}));
edtText1.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
Toast.makeText(MyActivity.this,“编辑文本第一次点击”,Toast.LENGTH_SHORT.show();
}
});
String string2=“演示编辑文本秒”;
edtText2.setText(setSpanColor(string2,“Second”,R.color.orange,新的spannableclicklinklistener()){
@凌驾
公共void onClickListener(视图){
view.performClick();
}
}));
edtText2.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
Toast.makeText(MyActivity.this,“编辑文本第二次点击”,Toast.LENGTH_SHORT.show();
}
});
String string3=“Demo EditText Third”;
edtText3.setText(setSpanColor(string3,“Third”,R.color.orange,新的spannableclicklinklistener()){
@凌驾
公共void onClickListener(视图){
view.performClick();
}
}));
edtText3.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
Toast.makeText(MyActivity.this,“第三次单击EditText”,Toast.LENGTH_SHORT.show();
}
});
}
专用SpannableStringBuilder setPanColor(最终字符串str、最终字符串文本、最终int颜色、最终spannableclicklinklistener侦听器){
SpannableStringBuilder ssb=新的SpannableStringBuilder(str);
如果(str.contains(text)){
ssb.设置范围(新的可点击范围(){
@凌驾
公共void onClick(视图){
onClickListener(视图);
}
@凌驾
public void updateDrawState(TextPaint ds){
setColor(getResources().getColor(color));
}
},str.indexOf(文本),str.indexOf(文本)
+text.length(),0);
}
返回ssb;
}
接口SpannableClickListener{
公共void onClickListener(视图);
}
}

您需要将TextView/EditText的移动方法设置为LinkMovementMethod,以便能够获得单击的链接。不幸的是,这禁用了选择文本的功能,只有将移动方法设置为ArrowKeyMovementMethod时,该功能才起作用。

为了解决这个问题,我创建了一个自定义MovementMethod类,该类继承自ArrowKeyMovementMethod,并添加了单击链接的功能:

/**
 * ArrowKeyMovementMethod does support selection of text but not the clicking of links.
 * LinkMovementMethod does support clicking of links but not the selection of text.
 * This class adds the link clicking to the ArrowKeyMovementMethod.
 * We basically take the LinkMovementMethod onTouchEvent code and remove the line
 *      Selection.removeSelection(buffer);
 * which deselects all text when no link was found.
 */
public class EnhancedMovementMethod extends ArrowKeyMovementMethod {

    private static EnhancedMovementMethod sInstance;

    public static MovementMethod getInstance() {
        if (sInstance == null) {
            sInstance = new EnhancedMovementMethod ();
        }
        return sInstance;
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        int action = event.getAction();

        if (action == MotionEvent.ACTION_UP ||
            action == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();

            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);

            if (link.length != 0) {
                if (action == MotionEvent.ACTION_UP) {
                    link[0].onClick(widget);
                }
                else if (action == MotionEvent.ACTION_DOWN) {
                    Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
                }

                return true;
            }
            /*else {
                Selection.removeSelection(buffer);
            }*/
        }

        return super.onTouchEvent(widget, buffer, event);
    }

}
您只需设置EditText的移动方式即可:

yourEditTExt.setMovementMethod(EnhancedMovementMethod.getInstance());
上面的代码只适用于未格式化的文本,这意味着一旦您决定使用文本样式(粗体、斜体等)或不同的字体大小格式化文本,它将无法再找到已单击的链接。我确实有处理格式化文本的代码,但因为这不是问题的一部分,所以我尽量缩短了示例代码

以上答案很有帮助。希望以下内容也能帮助您:


我对EditText的主要兴趣是因为我想通过长时间单击来选择它的文本。然而,这样文本就不可选择了:(仍然是同样的问题。文本在编辑文本中不再可选择。你打算奖励奖金还是让它过期?@EmanuelMoecklin你能再发布一次你的答案吗?我有一段时间不在网上:)我会检查它并让你知道结果,尊敬的;)我试过了,效果很好,但我有一些问题。你能帮我吗?这里描述了我的问题:@user3132352:请看我的评论。虽然这个代码片段可以解决这个问题,但它确实有助于提高您文章的质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。还请尽量不要用解释性注释挤满你的代码,这会降低代码和解释的可读性!
yourEditTExt.setMovementMethod(EnhancedMovementMethod.getInstance());
    android:linksClickable="true"
    android:autoLink="web"

 val message: String = String.format(
        getString(R.string.message_content),
        firstNameEditText.text,
        lastNameEditText.text,
        dateTextView.text,
        timeTextView.text
    )

    val gMapURL = getString(R.string.google_map_location)

    // Setup my Spannable with clickable URLs
    val spannable: Spannable = SpannableString(gMapURL)
    Linkify.addLinks(spannable, Linkify.WEB_URLS)

    // Append a zero-width space to the Spannable
    val gText = TextUtils.concat(spannable, "\u200B")

    val finalText = TextUtils.concat(message, gText)
    messageContentEditText.setText(finalText)