2015-03-31 145 views
6

我很累人在文本中用虛線或虛線劃出一個特定的單詞,並且還可點擊跨度。自定義跨度帶虛線的下劃線文本Android

我還沒有找到有人可以幫助我的解決方案。

SpannableStringBuilder sb = new SpannableStringBuilder(text); List listmot = new ArrayList();

 listmot=db.getAlldef(); 

     for(int i=0;i<listmot.size();i++) 
     { 


      String mot = (listmot.get(i)).get_mot(); 
      final String def = (listmot.get(i)).get_definition(); 

     Log.v(null, mot); 
     Pattern p = Pattern.compile(mot, Pattern.CASE_INSENSITIVE); 
     Matcher m = p.matcher(text); 
     while (m.find()){ 


     // Typeface tf = Typeface.createFromAsset(getApplicationContext().getAssets(),"fonts/font.ttf"); 
      //sb.setSpan(new CustomTypefaceSpan("",tf), m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 

     sb.setSpan(new ClickableSpan() { 

     @Override 
     public void onClick(View widget) { 
     // Toast.makeText(getApplicationContext(), def,Toast.LENGTH_LONG).show(); 



      int[] values = new int[2]; 
      widget.getLocationOnScreen(values); 
      Log.d("X & Y",values[0]+" "+values[1]); 
      AlertDialog.Builder alertDialog = new AlertDialog.Builder(
        AndroidSQLiteTutorialActivity.this); 
      alertDialog.setMessage(def); 
      alertDialog.setCancelable(true); 

      AlertDialog alert11 = alertDialog.create(); 
      alert11.setCanceledOnTouchOutside(true); 

      alert11.show(); 

     } 
    }, m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 

     } 

     } 



     textjson.setText(sb); 
     textjson.setMovementMethod(LinkMovementMethod.getInstance()); 
+0

您是否找到了解決方案? – JU5T1C3 2015-07-07 09:44:47

回答

2

編輯:我已經更新的解決方案。有時候,drawBackground方法在解決方案與LineBackgroundSpan只是沒有被叫沒有理由。新版本始終工作,看起來更清晰。

我遇到了同樣的問題,我結合這個解決方案解決了這個問題:

結果代碼如下所示:

private static class DottedUnderlineSpan extends ReplacementSpan { 
    private Paint p; 
    private int mWidth; 
    private String mSpan; 

    private float mSpanLength; 
    private boolean mLengthIsCached = false; 

    public DottedUnderlineSpan(int _color, String _spannedText){ 
     p = new Paint(); 
     p.setColor(_color); 
     p.setStyle(Paint.Style.STROKE); 
     p.setPathEffect(new DashPathEffect(new float[]{mDashPathEffect, mDashPathEffect}, 0)); 
     p.setStrokeWidth(mStrokeWidth); 
     mSpan = _spannedText; 
    } 

    @Override 
    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { 
     mWidth = (int) paint.measureText(text, start, end); 
     return mWidth; 
    } 

    @Override 
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { 
     canvas.drawText(text, start, end, x, y, paint); 
     if(!mLengthIsCached) 
      mSpanLength = paint.measureText(mSpan); 

     // https://code.google.com/p/android/issues/detail?id=29944 
     // canvas.drawLine can't draw dashes when hardware acceleration is enabled, 
     // but canvas.drawPath can 
     Path path = new Path(); 
     path.moveTo(x, y + mOffsetY); 
     path.lineTo(x + mSpanLength, y + mOffsetY); 
     canvas.drawPath(path, this.p); 
    } 
} 

爲了讓你的下劃線對一切密度相同的設置夢詩DP

mStrokeWidth = context.getResources().getDimension(R.dimen.stroke_width); 
mDashPathEffect = context.getResources().getDimension(R.dimen.dash_path_effect); 
mOffsetY = context.getResources().getDimension(R.dimen.offset_y); 

這是你如何使用它:

DottedUnderlineSpan dottedUnderlineSpan = new DottedUnderlineSpan(0xFF00FF00, spannedText); 
    spannableString.setSpan(dottedUnderlineSpan, startOfText, endOfText, Spanned.SPAN_INCLUSIVE_INCLUSIVE); 

,並確保您關閉硬件加速上的TextView這將顯示下劃線跨度。 https://stackoverflow.com/a/24467362/5373069

編輯:如果你看到方法來改善這個解決方案,我將不勝感激任何好點。

+0

當mSpanLength已經被計算出來時,'mLengthIsCached'應該被設置爲'true' – SILINIK 2016-01-07 16:08:02

+0

Hmph,它不適用於我。嘗試使用相同的字符串UnderlineSpan確實有效。 – 2017-05-07 10:27:28