Last active
November 8, 2019 11:25
-
-
Save ok3141/37d7ea94f98878b9350f3ce1bd997194 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.annotation.SuppressLint; | |
import android.content.Context; | |
import android.graphics.Bitmap; | |
import android.graphics.Canvas; | |
import android.graphics.drawable.BitmapDrawable; | |
import android.graphics.drawable.Drawable; | |
import android.text.Editable; | |
import android.text.Spannable; | |
import android.text.SpannableStringBuilder; | |
import android.text.Spanned; | |
import android.text.method.LinkMovementMethod; | |
import android.text.style.ClickableSpan; | |
import android.text.style.ImageSpan; | |
import android.util.AttributeSet; | |
import android.util.TypedValue; | |
import android.view.Gravity; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.ImageView; | |
import android.widget.LinearLayout; | |
import android.widget.TextView; | |
import androidx.annotation.NonNull; | |
import androidx.appcompat.widget.AppCompatEditText; | |
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; | |
@SuppressWarnings({"CodeBlock2Expr", "RedundantSuppression"}) | |
public class TagEditText extends AppCompatEditText { | |
private static final String SEPARATOR = ","; | |
private boolean selfUpdate; | |
private String lastText; | |
public TagEditText(Context context) { | |
super(context); | |
init(); | |
} | |
public TagEditText(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
init(); | |
} | |
public TagEditText(Context context, AttributeSet attrs, int defStyleAttr) { | |
super(context, attrs, defStyleAttr); | |
init(); | |
} | |
private void init() { | |
setMovementMethod(LinkMovementMethod.getInstance()); | |
} | |
@Override | |
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { | |
if (selfUpdate) { | |
return; | |
} | |
if (text == null) { | |
return; | |
} | |
if (text.toString().equals(lastText)) { | |
return; | |
} | |
SpannableStringBuilder sb = new SpannableStringBuilder(); | |
String fullString = text.toString(); | |
if (fullString.length() > 0) { | |
String[] strings = fullString.split(SEPARATOR); | |
for (int i = 0; i < strings.length; i++) { | |
String string = strings[i]; | |
sb.append(string); | |
if (fullString.charAt(fullString.length() - 1) != SEPARATOR.charAt(0) && i == strings.length - 1) { | |
break; | |
} | |
Drawable drawable = convertViewToDrawable(createTokenView(string)); | |
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); | |
int startIdx = sb.length() - (string.length()); | |
int endIdx = sb.length(); | |
sb.setSpan(new ImageSpan(drawable), startIdx, endIdx, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); | |
MyClickableSpan myClickableSpan = new MyClickableSpan(startIdx, endIdx); | |
sb.setSpan(myClickableSpan, Math.max(endIdx - 2, startIdx), endIdx, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); | |
if (i < strings.length - 1) { | |
sb.append(SEPARATOR); | |
} else if (fullString.charAt(fullString.length() - 1) == SEPARATOR.charAt(0)) { | |
sb.append(SEPARATOR); | |
} | |
} | |
} | |
lastText = fullString; | |
selfUpdate = true; | |
setText(sb); | |
selfUpdate = false; | |
setSelection(sb.length()); | |
} | |
@NonNull | |
public View createTokenView(@NonNull CharSequence text) { | |
int closeSize = getResources().getDimensionPixelSize(R.dimen.tag_close_size); | |
int spacing = getResources().getDimensionPixelSize(R.dimen.tag_spacing); | |
TextView textView = new TextView(getContext()); | |
textView.setText(text); | |
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); | |
ImageView imageView = new ImageView(getContext()); | |
imageView.setImageResource(R.drawable.ic_close_24dp); | |
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); | |
LinearLayout result = new LinearLayout(getContext()); | |
result.setOrientation(LinearLayout.HORIZONTAL); | |
result.setGravity(Gravity.CENTER_VERTICAL); | |
result.setBackgroundResource(R.drawable.tag); | |
result.setPadding(2 * spacing, spacing, 2 * spacing, spacing); | |
ViewGroup.MarginLayoutParams textLp = new ViewGroup.MarginLayoutParams(WRAP_CONTENT, WRAP_CONTENT); | |
textLp.leftMargin = spacing; | |
textLp.rightMargin = spacing; | |
result.addView(textView, textLp); | |
ViewGroup.MarginLayoutParams imageLp = new ViewGroup.MarginLayoutParams(closeSize, closeSize); | |
imageLp.leftMargin = spacing; | |
imageLp.rightMargin = spacing; | |
result.addView(imageView, imageLp); | |
return result; | |
} | |
@NonNull | |
public Drawable convertViewToDrawable(View view) { | |
int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); | |
view.measure(spec, spec); | |
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); | |
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888); | |
Canvas canvas = new Canvas(bitmap); | |
canvas.translate(-view.getScrollX(), -view.getScrollY()); | |
view.draw(canvas); | |
view.setDrawingCacheEnabled(true); | |
Bitmap cacheBmp = view.getDrawingCache(); | |
Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true); | |
view.destroyDrawingCache(); | |
return new BitmapDrawable(getContext().getResources(), viewBmp); | |
} | |
private class MyClickableSpan extends ClickableSpan { | |
int startIdx; | |
int endIdx; | |
public MyClickableSpan(int startIdx, int endIdx) { | |
super(); | |
this.startIdx = startIdx; | |
this.endIdx = endIdx; | |
} | |
@Override | |
@SuppressLint("SetTextI18n") | |
public void onClick(@NonNull View view) { | |
Editable s = getText(); | |
if (s != null) { | |
CharSequence s1 = s.subSequence(0, startIdx); | |
CharSequence s2 = s.subSequence(Math.min(endIdx + 1, s.length() - 1), s.length()); | |
setText(s1 + "" + s2); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://stackoverflow.com/questions/11318551