Android custom dotted text range

I'm tired of underlining a specific word in the text with a dotted or dashed line, as well as a Clickable Span.

I did not find a solution, someone can help me, please.

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()); 
+6
source share
1 answer

EDIT: I have an updated solution. Sometimes the drawBackground method in a solution with LineBackgroundSpan was simply not called without any reason. The new version works all the time and looks much clearer.

I met the same problem and I solved it by combining these solutions:

The result code is as follows:

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

To make your underline look the same at all densities, set the dimensions in 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); 

And here is how you use it:

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

And make sure you turn off hardware acceleration in textView , which will show the underline interval. fooobar.com/questions/36881 / ...

EDIT: if you see ways to improve this solution, I would appreciate any good points.

+2
source

Source: https://habr.com/ru/post/984518/


All Articles