77import android .graphics .BitmapFactory ;
88import android .graphics .PorterDuff ;
99import android .graphics .Typeface ;
10- import android .graphics .drawable .BitmapDrawable ;
1110import android .graphics .drawable .Drawable ;
1211import android .text .Editable ;
13- import android .text .Spannable ;
1412import android .text .SpannableString ;
15- import android .text .SpannableStringBuilder ;
1613import android .text .Spanned ;
1714import android .text .TextUtils ;
1815import android .text .TextWatcher ;
19- import android .text .style .ImageSpan ;
2016import android .util .DisplayMetrics ;
2117import android .util .Log ;
2218import android .view .Gravity ;
3733import com .variabletextinput .R ;
3834import com .variabletextinput .bean .RichTextBean ;
3935import com .variabletextinput .util .ActivityConst ;
36+ import com .variabletextinput .util .BitMapUtil ;
4037import com .variabletextinput .widget .TextSpan ;
4138
4239import static android .view .ViewGroup .LayoutParams .MATCH_PARENT ;
@@ -52,6 +49,7 @@ public class VariableTextInput extends LinearLayout {
5249 private Boolean ignoreNextLocalTextChange = false ;
5350
5451 private Context mContext ;
52+ private SpannableString mSpannableString ;
5553
5654 public VariableTextInput (Context context ) {
5755 super (context );
@@ -64,7 +62,7 @@ public VariableTextInput(Context context) {
6462 editText .setLayoutParams (new ScrollView .LayoutParams (MATCH_PARENT , WRAP_CONTENT ));
6563 editText .setGravity (Gravity .TOP );
6664 editText .setInputType (editText .getInputType () | InputType .TYPE_TEXT_FLAG_CAP_SENTENCES | InputType .TYPE_TEXT_FLAG_AUTO_CORRECT | InputType .TYPE_TEXT_FLAG_MULTI_LINE );
67- editText .setPadding (0 ,0 , 0 , 0 );
65+ editText .setPadding (0 , 0 , 0 , 0 );
6866 // This was used in conjunction with setting raw input type for selecting lock notes.
6967 // However, it causes the keyboard to not come up for editing existing notes.
7068 // Tested while offline using brand new installation on Android 6 emulator, but a user with Android 7 also reported it.
@@ -76,10 +74,22 @@ public VariableTextInput(Context context) {
7674 private int oldHeight = editText .getHeight (); // 保存旧的高度
7775 private int oldWidth = editText .getWidth (); // 保存旧的宽度
7876 private String mPreviousText ;
77+ private int mSpanLength = -1 ;
7978
8079 @ Override
8180 public void beforeTextChanged (CharSequence s , int start , int count , int after ) {
8281 mPreviousText = s .toString ();
82+ if (start == 0 || editText .getText () == null ) return ;
83+ if (count > after ) {
84+ TextSpan [] spans = editText .getText ().getSpans (start + count , start + count , TextSpan .class );
85+ if (spans == null || spans .length == 0 ) return ;
86+ for (TextSpan span : spans ) {
87+ int endSpanIndex = editText .getText ().getSpanEnd (span );
88+ if (endSpanIndex != start + count ) continue ;
89+ mSpanLength = span .getRichTextBean ().content .length () - 1 ;
90+ editText .getText ().removeSpan (span );
91+ }
92+ }
8393 }
8494
8595 @ Override
@@ -89,33 +99,21 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {
8999 if (count == 0 && before == 0 ) {
90100 return ;
91101 }
92- if (editText .getText () != null ) {
93- TextSpan [] spans = editText .getText ().getSpans (0 , editText .getText ().length (), TextSpan .class );
94- ImageSpan [] spansImg = editText .getText ().getSpans (0 , editText .getText ().length (), ImageSpan .class );
95- //整体删除span
96- if (before == 1 && count == 0 ) {
97- for (TextSpan textSpan : spans ) {
98- if (editText .getText ().getSpanEnd (textSpan ) == start && !editText .getText ().toString ().endsWith (textSpan .getRichTextBean ().name )) {
99- editText .getText ().delete (editText .getText ().getSpanStart (textSpan ), editText .getText ().getSpanEnd (textSpan ));
100- }
101- }
102- for (ImageSpan textSpan : spansImg ) {
103- if (editText .getText ().getSpanEnd (textSpan ) == start ) {
104- editText .getText ().delete (editText .getText ().getSpanStart (textSpan ), editText .getText ().getSpanEnd (textSpan ));
105- }
106- }
107- }
102+ String newText = s .toString ().substring (start , start + count );
103+ String oldText = mPreviousText .substring (start , start + before );
104+ // Don't send same text changes
105+ if (count == before && newText .equals (oldText )) {
106+ return ;
108107 }
109- // String newText = s.toString().substring(start, start + count);
110- // String oldText = mPreviousText.substring(start, start + before);
111- // // Don't send same text changes
112- // if (count == before && newText.equals(oldText)) {
113- // return;
114- // }
115108 if (ignoreNextLocalTextChange ) {
116109 ignoreNextLocalTextChange = false ;
117110 return ;
118111 }
112+ if (editText .getText () != null && mSpanLength > -1 ) {
113+ int length = mSpanLength ;
114+ mSpanLength = -1 ;
115+ editText .getText ().replace (start - length , start , "" );
116+ }
119117 WritableMap event = Arguments .createMap ();
120118 event .putString ("text" , s .toString ());
121119 final Context context = getContext ();
@@ -141,18 +139,20 @@ public void afterTextChanged(Editable s) {
141139 event .putMap ("contentSize" , contentSize );
142140 final Context context = getContext ();
143141 if (context instanceof ReactContext ) {
144- Log .d ("输入框高度" , "afterTextChanged: " + event );
142+ Log .d ("输入框高度" , "afterTextChanged: " + event );
145143 ((ReactContext ) context ).getJSModule (RCTEventEmitter .class ).receiveEvent (getId (), "onAndroidContentSizeChange" , event );
146144 }
147145 }
148146 }
149147 });
150148 }
149+
151150 public int pxToDp (int px ) {
152151 DisplayMetrics displayMetrics = getContext ().getResources ().getDisplayMetrics ();
153152 int dpi = displayMetrics .densityDpi ;
154153 return Math .round (px / (dpi / 160f ));
155154 }
155+
156156 @ Override
157157 protected void onLayout (boolean changed , int left , int top , int right , int bottom ) {
158158 super .onLayout (changed , left , top , right , bottom );
@@ -317,26 +317,19 @@ public void setPlaceholder(String placeholder) {
317317 public void setUnderLineColorAndroid (Integer color ) {
318318 editText .setBackgroundTintList (ColorStateList .valueOf (color ));
319319 }
320- public void setFontSize (Integer fontSize ){
320+
321+ public void setFontSize (Integer fontSize ) {
321322 editText .setTextSize (fontSize );
322323 }
323- public void setFontFamily (String fontFamily ){
324+
325+ public void setFontFamily (String fontFamily ) {
324326 int style = Typeface .NORMAL ;
325- if (editText .getTypeface () != null ){
327+ if (editText .getTypeface () != null ) {
326328 style = editText .getTypeface ().getStyle ();
327329 }
328- Typeface newTypeFace = ReactFontManager .getInstance ().getTypeface (fontFamily ,style ,editText .getContext ().getAssets ());
330+ Typeface newTypeFace = ReactFontManager .getInstance ().getTypeface (fontFamily , style , editText .getContext ().getAssets ());
329331 editText .setTypeface (newTypeFace );
330332 }
331- public void insertImage (String imagePath ) {
332- Bitmap bitmap = BitmapFactory .decodeFile (imagePath );
333- Drawable drawable = new BitmapDrawable (getResources (), bitmap );
334- drawable .setBounds (0 , 0 , getWidth (), getHeight ());
335- ImageSpan span = new ImageSpan (drawable , ImageSpan .ALIGN_BASELINE );
336- SpannableString spannableString = new SpannableString ("face" );
337- spannableString .setSpan (span , 0 , 4 , Spannable .SPAN_EXCLUSIVE_EXCLUSIVE );
338- editText .append (spannableString );
339- }
340333
341334 public void handleRichText (ReadableArray args ) {
342335 if (args != null && args .size () > 0 ) {
@@ -406,10 +399,10 @@ public void insertEmoji(RichTextBean richTextBean) {
406399 editText .getText ().insert (startIndex , richTextBean .tag );
407400 }
408401 Bitmap bitmap = BitmapFactory .decodeResource (getResources (), R .drawable .kuxiao );
409- ImageSpan imageSpan = new ImageSpan (mContext , bitmap );
410- SpannableStringBuilder ss = SpannableStringBuilder .valueOf (editText .getText ());
411- ss .setSpan (imageSpan , startIndex , endIndex , Spanned .SPAN_EXCLUSIVE_EXCLUSIVE );
412- editText .setText (ss );
402+ TextSpan imageSpan = new TextSpan (mContext , bitmap , richTextBean );
403+ mSpannableString = SpannableString .valueOf (editText .getText ());
404+ mSpannableString .setSpan (imageSpan , startIndex , endIndex , Spanned .SPAN_EXCLUSIVE_EXCLUSIVE );
405+ editText .setText (mSpannableString );
413406 editText .setSelection (endIndex );
414407 editText .getText ().replace (startIndex , endIndex , richTextBean .content );
415408 }
@@ -422,10 +415,11 @@ private void insertMentions(RichTextBean richTextBean) {
422415 if (editText .getText () != null ) {
423416 editText .getText ().insert (startIndex , richTextBean .tag + richTextBean .name );
424417 }
425- SpannableStringBuilder ss = SpannableStringBuilder .valueOf (editText .getText ());
426- TextSpan textSpan = new TextSpan (mContext , richTextBean );
427- ss .setSpan (textSpan , startIndex , endIndex , Spanned .SPAN_EXCLUSIVE_EXCLUSIVE );
428- editText .setText (ss );
418+ Bitmap bitmap = BitMapUtil .getTextBitmap (richTextBean .tag + richTextBean .name , editText .getTypeface (), editText .getTextSize (), richTextBean .color );
419+ TextSpan textSpan = new TextSpan (mContext , bitmap , richTextBean );
420+ mSpannableString = SpannableString .valueOf (editText .getText ());
421+ mSpannableString .setSpan (textSpan , startIndex , endIndex , Spanned .SPAN_EXCLUSIVE_EXCLUSIVE );
422+ editText .setText (mSpannableString );
429423 editText .setSelection (endIndex );
430424 editText .getText ().replace (startIndex , endIndex , richTextBean .content );
431425 }
0 commit comments