2015-03-31 18 views
6

Miałem dość podkreślenia określonego słowa w tekście za pomocą kropkowanej lub przerywanej linii z, a także z możliwością kliknięcia.Niestandardowy tekst podkreślenia zakresu z kropkowaną linią Androida

Nie znalazłem rozwiązania, czy ktoś może mi pomóc, proszę.

SpannableStringBuilder sb = new SpannableStringBuilder (tekst); Lista 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

czy znalazłeś już rozwiązanie? – JU5T1C3

Odpowiedz

2

EDIT: I zostały zaktualizowane rozwiązanie. Czasami metoda drawBackground w rozwiązaniu z LineBackgroundSpan nie została wywołana z żadnego powodu. Nowa wersja działa cały czas i wygląda znacznie jaśniej.

Poznałem ten sam problem i rozwiązać go łącząc to rozwiązania:

Kod wynik wygląda tak:

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); 
    } 
} 

Aby podkreślić wyglądają tak samo na wszystkich gęstościach ustawić, że dimens w 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); 

I to jak go używać:

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

I mieć pewność, że po wyłączeniu akceleracji sprzętowej na TextView które pokaże rozpiętość przęsła. https://stackoverflow.com/a/24467362/5373069

EDIT: jeśli widzisz sposobów poprawy tego rozwiązania chciałbym docenić jakieś dobre punkty.

+0

'mLengthIsCached' powinno być ustawione na 'true', gdy' mSpanLength' jest już obliczone – SILINIK

+0

Hmph, to nie działa dla mnie. Próba UnderlineSpan na tym samym łańcuchu działa. –