2015-03-31 48 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