Objective
When you write again, it's important to accumulate code. As the intention of this blog is actually the purpose of accumulation of code, in fact, it is not difficult, but a very trivial thing really need time to complete and debug, so, get you in writing a function will feel not how difficult, But if you can better organize/accumulate the code.
Demo description
Demo function is actually modeled on the micro-letter Chat Emoje Choice, the adoption of the Viewpager+gridview scheme, but I will fill up the Recyclerview plan, now or first to realize the function. In addition, add Emoje to TextView and EditText, and take a look at this blog: Android uses TextView and edittext to achieve the display and insertion of emoticons, and this blog introduces two ways:
method One: use html.fromhtml parsing, method two: use bitmap to draw out directly, I adopt the second method, use bitmap to draw out.
Read The fucking code
idea: since it is Viewpager + GridView then, start with the big direction, complete the Viewpager, and then complete the GridView. PS: The code uses Rxjava, lambda, Butterknife, Eventbus, Glide.
Here the entire bottom layout is written as a combination of viewgroup–chatbottombar, starting with the layout.
Chatbottombar's Xml–chat_bottom.xml:
<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "
android:layout_width=" match_parent "
android:layout_height=" Wrap_content "
android: Animatelayoutchanges= "true"
android:orientation= "vertical" >
<include layout= "@layout/chat_bottom_ Input "></include>
<include layout=" @layout/chat_bottom_function1 "></include>
</ Linearlayout>
The following are the XML and emoji XML for the input box:
Chat_bottom_input:
<?xml version= "1.0" encoding= "Utf-8"?> <merge xmlns:android= "Http://schemas.android.com/apk/res/android" Android:layout_width= "Match_parent" android:layout_height= "match_parent" android:orientation= "vertical" > < Relativelayout android:id= "@+id/rl_input" android:layout_width= match_parent "android:layout_height=" Wrap_cont Ent "android:background=" #f0f0f0 "> <imageview android:id=" @+id/showmore "android:layout_width=" 42DP "android:layout_height=" 60DP "android:paddingbottom=" 5DP "android:paddingleft=" 9DP "android:p addingtop= "9DP" android:src= "@mipmap/ic_launcher"/> <linearlayout android:layout_width= "Match_par
Ent "android:layout_height=" 35DP "android:layout_centervertical=" true "android:layout_marginright=" 15DP " android:layout_torightof= "@+id/showmore" android:background= "@drawable/shape_white_corner" Android:grav Ity= "Center_vertical" Android:orientation= "Horizontal" > <imageview android:layout_width= "45DP" android:layout_height= "4 0DP "android:paddingbottom=" 10DP "android:paddingleft=" 10DP "android:paddingright=" 5DP "an droid:paddingtop= "10DP" android:src= "@mipmap/ic_launcher"/> <edittext android:id= "@+id/editt Ext "android:layout_width=" match_parent "android:layout_height=" Match_parent "Android:layout_margi
nright= "10DP" android:background= "@null" android:gravity= "center_vertical" android:hint= "Say Something" android:maxlines= "3" android:textcolor= "#999999" android:textcolorhint= "#dddddd" Android:text
Size= "13sp"/> </LinearLayout> </RelativeLayout> </merge>
Chat_bottom_function1:
<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "
android:layout_width=" match_parent "
android:layout_height=" Wrap_content "
android: Background= "#ffffff"
android:orientation= "vertical" >
<android.support.v4.view.viewpager
Android:id= "@+id/emojes"
android:layout_width= "match_parent"
android:layout_height= "110DP" ></ Android.support.v4.view.viewpager>
</LinearLayout>
The first is to Viewpager populate the GridView, looking from pageadapter to see what data is needed:
package Cjh.emojicondemo;
Import Android.content.Context;
Import Android.support.v4.view.PagerAdapter;
Import Android.support.v4.view.ViewPager;
Import Android.view.View;
Import Android.widget.GridView;
Import java.util.ArrayList;
/** * Created by cjh on 16-11-8.
* * public class Emojipageadapter extends Pageradapter {private arraylist<gridview> mlists;
Public Emojipageadapter (context context, arraylist<gridview> array) {this.mlists = array;
@Override public int GetCount () {return mlists.size ();
@Override public boolean isviewfromobject (View arg0, Object arg1) {return arg0 = = Arg1;
@Override public Object Instantiateitem (View arg0, int arg1) {(Viewpager) arg0). AddView (Mlists.get (arg1));
Return Mlists.get (ARG1); @Override public void Destroyitem (view arg0, int arg1, Object arg2) {(Viewpager) arg0). Removeview (view) arg2
); }
}
In fact, basically is pageradapter template code, need only the GridView, look at the code in the Chatbottombar:
@BindView (r.id.emojes)
Android.support.v4.view.ViewPager Emojes;
....
Each page has 24 expressions and then uses the Math ceil function to calculate the minimum number of pages that we need
private void Initemoje () {
int pagecount = (int) Math.ceil ( emojiutils.emojis.length/24.0f);
arraylist<gridview> pagedata = new arraylist<> ();
for (int i = 0; i < PageCount i++) {
GridView GV = Getgridview (i);
Pagedata.add (GV);
}
Emojes.setadapter (New Emojipageadapter (context, pagedata));
}
The big structure is basically the case, followed by small details, such as the creation and presentation of the GridView:
@NonNull
private GridView Getgridview (int i) {
GridView GV = new GridView (context);
Gv.setverticalscrollbarenabled (false);
Gv.setadapter (New Emojigridadapter (context, i));
Gv.setgravity (gravity.center);
Gv.setclickable (true);
Gv.setfocusable (true);
Gv.setnumcolumns (8);
return GV;
}
Adapter
Package Cjh.emojicondemo;
Import Android.content.Context;
Import Android.view.LayoutInflater;
Import Android.view.View;
Import Android.view.ViewGroup;
Import Android.widget.BaseAdapter;
Import Android.widget.ImageView;
Import Org.greenrobot.eventbus.EventBus;
/** * Created by cjh on 16-11-8.
* * public class Emojigridadapter extends Baseadapter {private context;
private int page;
Public Emojigridadapter (context, int page) {this.context = context;
this.page = page;
@Override public int GetCount () {return 24;
@Override public Object getitem (int i) {return null;
@Override public long Getitemid (int i) {return 0;
@Override public View GetView (int i, view view, ViewGroup viewgroup) {Viewholder holder = null;
if (view = = null) {view = Layoutinflater.from (context). Inflate (R.layout.chat_emoji, NULL);
Holder = new Viewholder (); Holder.image = (ImageView) View.findviewbyid (r.id.image);
View.settag (holder);
} holder = (Viewholder) view.gettag ();
int position = page * + i;
if (position < EmojiUtils.emojis.length) Imageloader.load (context, emojiutils.icons[position], holder.image);
else holder.image.setVisibility (View.gone); Holder.image.setOnClickListener (View1-> eventbus.getdefault (). Post (new Emojievent (Emojiutils.emojis[page * + i)
])));
return view;
Static class Viewholder {public ImageView image;
}
}
Here, I use Eventbus to pass the time of click.
The big structure basically already OK, then must look at the comparison core part, the emoji processing, when receives the event incident, called Chatbottombar.appandemoje (EMOJIEVENT.S)
@Subscribe public
void Onemojievent (Emojievent emojievent) {
chatbottombar.appandemoje (EMOJIEVENT.S);
}
So look at the Chatbottombar code:
public void Appandemoje (String s) {
rx. Observable
. Just (s)
. Subscribeon (Schedulers.io ())
. Map (S1-> {spannablestring Emojetext
= Emojiutils.getemojitext (Edittext.gettext (). toString () + S1);
return emojetext;
})
. Unsubscribeon (Schedulers.io ())
. Observeon (Androidschedulers.mainthread ())
. Subscribe (S2-> {
Edittext.settext ("");
Edittext.append (s2);}
The code above uses Rxjava, and you can see that the real core is
Emojiutils.getemojitext (Edittext.gettext (). toString () + S1);
Return Emojetext This line of code inside.
So take a look at Emojiutils's code:
Package Cjh.emojicondemo;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import android.graphics.drawable.Drawable;
Import Android.net.Uri;
Import android.text.Spannable;
Import android.text.SpannableString;
Import Android.text.TextUtils;
Import Android.text.style.ImageSpan;
Import Android.text.style.RelativeSizeSpan;
Import Android.util.SparseArray;
Import Java.io.File;
Import java.util.ArrayList;
Import Java.util.HashMap;
Import Java.util.Map;
Import Java.util.regex.Matcher;
Import Java.util.regex.Pattern;
Import Java.util.zip.Inflater;
/** * Created by cjh on 16-11-7.
* * Public class Emojiutils {private static Hashmap<pattern, integer> Emomap = new hashmap<> ();
public static final String Delete_key = "Em_delete_delete_expression"; public static string[] Emojis = new string[]{"[Smile]", "[twitched]", "[Color]", "[Daze]", "[Proud]", "
[Tears], "[Shy]", "[Shut up]", "[Sleep]", "[Crying]", "[embarrassed]", "[Angry]", "[Naughty]", "[Bared teeth]", "[Surprised]", "[Sad]", "[Cool]", "[Cold Sweat]", "[Crazy]", "[Vomit]",
"[Laughter]", "[Happy]", "[supercilious]", "[Arrogant]", "[Hunger]", "[Sleepy]", "[Panic]", "[Sweating]", "[Shing]",
"[Leisurely]", "[Struggle]", "[Curse]", "[Doubt]", "[Boo]", "[Halo]", "[Crazy]", "[Fade]", "[Skull]", "[Knock]", "[Goodbye]", "[Wipe perspiration]", "[Pick nose]", "[applause]", "[Embarrassing]", "[Bad laugh]", "[left Hem]", "
[Right Hem], "[Yawn]", "[Despise]", "[wronged]", "[Quick to Cry]", "[Sinister]", "[Kiss]", "[Frighten]", "[Pitiful]",
"[Chopper]", "[Watermelon]", "[Beer]", "[Basketball]", "[Ping-Pong]", "[Coffee]", "[Rice]", "[Pig]", "[Rose]", "[Fade]", "[Lips]", "[Love]", "[Heartbreak]", "[Cake]", "[Lightning]", "[Bomb]", "[knife]" [Football ] "," [Ladybug] "," [Poo] "," [Moon] "," [Sun] "," [Gift] "," [Hug] "," [Strong] "," [Weak] "," [
Shake hands] ", [Victory]", "[Shang]", "[Seduce]", "[Fist]", "[Poor]", "[Love You]", "[NO]", "[OK]"}; public static int[] icons = new int[]{r.drawable.ee_1, r.drawable.ee_2, R.drawable.ee_3, r.drawab Le.ee_4, R.drawable.ee_5, R.drawable.ee_6, R.drawable.ee_7, R.drawable.ee_8, R.drawable.ee_9
, R.drawable.ee_10, R.drawable.ee_11, R.drawable.ee_12, r.drawable.ee_13, R.drawable.ee_14,
R.drawable.ee_15, R.drawable.ee_16, R.drawable.ee_17, r.drawable.ee_18, r.drawable.ee_19,
R.drawable.ee_20, r.drawable.ee_21, r.drawable.ee_22, r.drawable.ee_23, r.drawable.ee_24,
R.drawable.ee_25, r.drawable.ee_26, r.drawable.ee_27, r.drawable.ee_28, r.drawable.ee_29, R.drawable.ee_30, r.drawable.ee_31, r.drawable.ee_32, r.drawable.ee_33, r.drawable.ee_34, R.
Drawable.ee_35, r.drawable.ee_36, R.drawable.ee_37, r.drawable.ee_38, r.drawable.ee_39, r.drawable.ee_40, r.drawable.ee_41, R . drawable.ee_42, r.drawable.ee_43, r.drawable.ee_44, r.drawable.ee_45, r.drawable.ee_46, R.D Rawable.ee_47, r.drawable.ee_48, r.drawable.ee_49, R.drawable.ee_50, r.drawable.ee_51, R.dra wable.ee_52, r.drawable.ee_53, r.drawable.ee_54, r.drawable.ee_55, r.drawable.ee_56, R.drawa ble.ee_57, r.drawable.ee_58, r.drawable.ee_59, r.drawable.ee_60, r.drawable.ee_61, r.drawabl e.ee_62, r.drawable.ee_63, r.drawable.ee_64, r.drawable.ee_65, R.drawable.ee_66, r.drawable. ee_67, r.drawable.ee_68, r.drawable.ee_69, r.drawable.ee_70, r.drawable.ee_71, r.drawable.ee _72, r.drawable.ee_73, r.drawable.ee_74, r.drawable.ee_75, r.drawable.ee_76, r.drawable.ee_7 7, R.drawable.ee_78, r.drawable.ee_79, r.drawable.ee_80, r.drawable.ee_81, R.drawable.ee_82, r.drawable.ee_83,
r.drawable.ee_84, r.drawable.ee_85, r.drawable.ee_86, r.drawable.ee_87, r.drawable.ee_88,
R.drawable.ee_89, R.drawable.ee_90,}; static {for (int i = 0; i < emojis.length i++) {emomap.put (Pattern.compile (pattern.quote)), icon
S[i]);
The public static spannablestring Getemojitext (String s) {spannablestring spannable = new Spannablestring (s); For (Map.entry<pattern, integer> entry:emoMap.entrySet ()) {Matcher Matcher = Entry.getkey (). Matcher (span
nable); while (Matcher.find ()) {for (Imagespan Span:spannable.getSpans) (Matcher.start (), Matcher.end (), imag Espan.class)) if (Spannable.getspanstart (span) >= Matcher.start () && Spannable.getspane nd (span) <= matcher.end ()) Spannable.removespan (span);
else break;
drawable drawable = MainActivity.context.getResources (). Getdrawable (Entry.getvalue ());
Drawable.setbounds (0, 0, 60, 60);
Imagespan Imagespan = new Imagespan (drawable);
Spannable.setspan (Imagespan, Matcher.start (), Matcher.end (), spannable.span_exclusive_exclusive);
} return spannable;
}
}
Here to facilitate the insertion of the position of the expression, I will emoji corresponding to the Chinese into the pattern object, in the Getemojitext to do traversal query, which is why I use RX to asynchronous operation.
Basically here, back to look at the content, they are too lazy to spit, but, fortunately, as long as there is a specific demo, can read code, there is no explanation in fact all right, do not be afraid of their own later to understand.
SOURCE Download: Https://github.com/cjhandroid/EmojiInputDemo
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.