<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="ru.trinitydigital.textselecting.MainActivity" android:id="@+id/container"> </RelativeLayout>
package ru.trinitydigital.textselecting; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.RelativeLayout; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RelativeLayout container = (RelativeLayout) findViewById(R.id.container); container.addView(new WordAnswerView(this, "hello", convertDpToPx(30))); } }
public class WordAnswerView extends TextView { // private final String originalText; // , ( ) private float tracking = convertDpToPx(16); // private int selectionColor = Color.parseColor("#5591F6"); // private static final int NO_SELECTION = -1; // ( ) private int selectionBegin = NO_SELECTION, selectionEnd = NO_SELECTION; // , private SelectionTrackingSpan selectionTrackingSpan = new SelectionTrackingSpan(); // , , private int baseWidth; }
public WordAnswerView(Context context, CharSequence text, float textSizePx) { super(context); // originalText = text.toString(); setTextSize(textSizePx); setTextColor(Color.BLACK); // , , // setTypeface(Typeface.MONOSPACE); setPadding((int) tracking, 0, (int) tracking, 0); // , SpannableString s = new SpannableString(originalText); s.setSpan(selectionTrackingSpan, 0, originalText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); setText(s); }
public WordAnswerView(Context context, CharSequence text, float textSizePx) { // … setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_UP: // , int index = (int)(event.getX() / baseWidth); // if (selectionBegin == index && selectionEnd == NO_SELECTION) { selectionBegin = NO_SELECTION; selectionEnd = NO_SELECTION; invalidate(); break; } if (selectionBegin == NO_SELECTION) { selectionBegin = index; } else if (selectionEnd == NO_SELECTION) { selectionEnd = index; if (selectionBegin > selectionEnd) { int tmp = selectionBegin; selectionBegin = selectionEnd; selectionEnd = tmp; } } else { selectionBegin = index; selectionEnd = NO_SELECTION; } invalidate(); break; } return false; } }); }
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); baseWidth = w / originalText.length(); }
public class SelectionTrackingSpan extends ReplacementSpan { @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { // + return (int)(paint.measureText(text, start, end) + tracking * (end - start)); } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { float dx = x; for (int i = start; i < end; i++) { // , if (i < selectionBegin || i >= (selectionEnd != NO_SELECTION ? selectionEnd + 1 : selectionBegin + 1)) paint.setColor(Color.BLACK); else paint.setColor(selectionColor); canvas.drawText(text, i, i + 1, dx, y, paint); dx += paint.measureText(text, i, i + 1) + tracking; } } }
Source: https://habr.com/ru/post/340232/
All Articles