我怎样才能有可点击的Spannables的EditText,仍然可以通过longClickselect?

我有TextViewtypes跨度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); 

现在我想将这些string应用于EditText而不是TextViews。 一切都很好,可点击的string现在不再被点击了。 我想知道如何将这种跨度的点击传递给他们指定的clicklistener?

更新:我主要关心编辑文本是我想让用户select文本的一部分,并与他分享,同时他/她可以点击ClickableSpans。

Related of "我怎样才能有可点击的Spannables的EditText,仍然可以通过longClickselect?"

您需要将TextView的/ EditText的移动方法设置为LinkMovementMethod才能够获得点击链接。 不幸的是,禁用了select仅在将移动方法设置为ArrowKeyMovementMethod的情况下才起作用的文本的能力。 http://developer.android.com/reference/android/text/method/LinkMovementMethod.html http://developer.android.com/reference/android/text/method/ArrowKeyMovementMethod.html

为了解决这个问题,我创build了一个inheritance自ArrowKeyMovementMethod的自定义MovementMethod类,并添加了单击链接的function。 :

 /** * 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()); 

上面的代码只适用于未格式化的文本,这意味着一旦您决定使用文本样式(粗体,斜体等)或不同的字体大小格式化文本,它不会再find点击链接。 我确实有处理格式化文本的代码,但由于这不是问题的一部分,所以我尽可能缩短了示例代码。

下面的代码示例应该为你工作,我也testing过了,它给你点击ClickableSpanString事件

可能是你忘了添加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); 
 //try this way,hope this will help you... **activity.xml** code <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <EditText android:id="@+id/edtText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusableInTouchMode="false" android:focusable="false" android:editable="false"/> <EditText android:id="@+id/edtText2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusableInTouchMode="false" android:focusable="false" android:editable="false"/> <EditText android:id="@+id/edtText3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusableInTouchMode="false" android:focusable="false" android:editable="false"/> </LinearLayout> **Activity** code private EditText edtText1; private EditText edtText2; private EditText edtText3; @Override protected void onCreate(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 = "Demo EditText First"; edtText1.setText(setSpanColor(string1, "First",R.color.orange,new SpannableClickListener(){ @Override public void onClickListener(View view) { view.performClick(); } })); edtText1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MyActivity.this,"EditText First Click",Toast.LENGTH_SHORT).show(); } }); String string2 = "Demo EditText Second"; edtText2.setText(setSpanColor(string2, "Second",R.color.orange,new SpannableClickListener(){ @Override public void onClickListener(View view) { view.performClick(); } })); edtText2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MyActivity.this,"EditText Second Click",Toast.LENGTH_SHORT).show(); } }); String string3 = "Demo EditText Third"; edtText3.setText(setSpanColor(string3, "Third",R.color.orange,new SpannableClickListener(){ @Override public void onClickListener(View view) { view.performClick(); } })); edtText3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MyActivity.this,"EditText Third Click",Toast.LENGTH_SHORT).show(); } }); } private SpannableStringBuilder setSpanColor(final String str,final String text,final int color,final SpannableClickListener listener) { SpannableStringBuilder ssb = new SpannableStringBuilder(str); if (str.contains(text)) { ssb.setSpan(new ClickableSpan() { @Override public void onClick(View view) { listener.onClickListener(view); } @Override public void updateDrawState(TextPaint ds) { ds.setColor(getResources().getColor(color)); } }, str.indexOf(text), str.indexOf(text) + text.length(), 0); } return ssb; } interface SpannableClickListener{ public void onClickListener(View view); } }