Implementations of Emoji (Emoticon) View/Keyboard Layouts
Asked Answered
G

6

61

I am trying to figure out how the emoji (emoticon) selections are implemented on the Facebook app and the Google Hangouts app. I looked into the SoftKeyboard Demo app in the Android API Samples but the display of these emoji views does not look like a SoftKeyboard. It looks and behaves more like a custom Dialog view. Does anyone have an idea of how these are implemented?

Facebook App

Facebook

Google Hangouts app

Hangouts

Also, is Unicode the best way to send emoticons or is there an alternative? I noticed that some Unicode sequences like \u1F601 don't render the corresponding emoticon and instead that sequence just shows up as 1 :

EditText messageInput = (EditText) findViewById(R.id.message_input);
messageInput.getText().append("\u1F601");
Gennygeno answered 27/5, 2013 at 8:12 Comment(2)
A keyboard doesn't need to actually look like the soft keyboard- a keyboard can create any custom view it wants, and pretty much only people playing around actually use the KeyboardView class- anyone putting serious time into their keyboard ends up making a custom view.Externality
Related: #3342202Nozzle
G
47

I found a very useful Emoticon Keyboard. This keyboard is not using Unicode sequences but rather just local image assets. I am thinking that this type of keyboard can only be useful within this app and not with other apps or Operating Systems.

So instead I am replacing the ImageView containing an asset with a TextView containing a Unicode sequence.

After cross referencing Supported Unicode Sequences as well as the Visual Unicode Database I realized that \u1F601 was a 32 bit Unicode representation, and the 16bit representation can be set like :

EditText messageInput = (EditText) findViewById(R.id.message_input);
messageInput.getText().append("\ud83d\ude01");
Gennygeno answered 9/6, 2013 at 22:50 Comment(1)
how you converting 32bit representation to 16 bit. is there any pattern to do that.Exserviceman
C
25

You can use this library based on Hieu Rocker's library: https://github.com/ankushsachdeva/emojicon

This is how it looks

Screenshot

Crissum answered 1/9, 2014 at 21:41 Comment(3)
This is the best library for Emoji :DHaematosis
Do you have any same libraries with gradle integrateVictoria
This is really excellent ! Please find here how to implement it in project in Android StudioCruciate
J
9

If you don't want to get into details of how to implement the Emoji-Keyboard functionality, you can try these libraries:

  • Rockerhieu / emojicon: implements the Emoji-Keyboard using fragments (you will need to handle the display of it using a DialogFragment. It doesn't have support for changing the layout and the default one is Hole Dark theme;

  • Android Emoji Keyboard: Based on Rockerhieu work I've built another lib that provides the emoji-keyboard as closer to what we've seen in apps such as WhatsApp or Telegram. You can handle the layout as a LinearLayout and, therefore, handle the interaction with the soft keyboard yourself (as described below) or choose to use Telegram Panel or WhatsApp Panel, both provided by the library, that does it for you.

PS1: Both libraries are Apache License

Final Result should look like that

Part 01: Building the layout

  • Create a GridView for each Emoji-Page you want in your keyboard. For instance:

  • Bind the created views in Fragments:

    public class FragmentEmojiNature extends FragmentEmoji {
    
    public static final String TAG = "FragmentEmojiNature";
    
    private View mRootView;
    private Emoji[] mData;
    private boolean mUseSystemDefault = false;
    
    private static final String USE_SYSTEM_DEFAULT_KEY = "useSystemDefaults";
    private static final String EMOJI_KEY = "emojic";
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        this.mRootView = inflater.inflate(R.layout.frag_emoji_nature, container, false);
        return this.mRootView;
    }
    
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        GridView gridView = (GridView) view.findViewById(R.id.Emoji_GridView);
        Bundle bundle = getArguments();
        if (bundle == null) {
            mData = Nature.DATA;
            mUseSystemDefault = false;
        } else {
            Parcelable[] parcels = bundle.getParcelableArray(EMOJI_KEY);
            mData = new Emoji[parcels.length];
            for (int i = 0; i < parcels.length; i++) {
                mData[i] = (Emoji) parcels[i];
            }
            mUseSystemDefault = bundle.getBoolean(USE_SYSTEM_DEFAULT_KEY);
        }
        gridView.setAdapter(new EmojiAdapter(view.getContext(), mData, mUseSystemDefault));
        gridView.setOnItemClickListener(this);
    }
    

    }

  • Create a new layout containing a view pager and some component to control the view pager transition (in my case I've used a third part library called SmartTabLayout as shown below:

    <com.ogaclejapan.smarttablayout.SmartTabLayout
        android:id="@+id/emoji_tabs"
        android:layout_width="0dip"
        android:layout_height="40dip"
        android:layout_weight="1"
        app:stl_clickable="true"
        app:stl_defaultTabBackground="@color/rsc_emoji_tab_bkg"
        app:stl_defaultTabTextAllCaps="true"
        app:stl_defaultTabTextColor="#000"
        app:stl_defaultTabTextHorizontalPadding="0dip"
        app:stl_defaultTabTextMinWidth="0dp"
        app:stl_defaultTabTextSize="14sp"
        app:stl_distributeEvenly="true"
        app:stl_dividerColor="@color/rsc_emoji_tab_bkg"
        app:stl_drawDecorationAfterTab="true"
        app:stl_indicatorColor="@color/rsc_emoji_tab_indicator"
        app:stl_indicatorGravity="bottom"
        app:stl_indicatorInFront="false"
        app:stl_indicatorInterpolation="smart"
        app:stl_indicatorThickness="2dp"
        app:stl_overlineThickness="0dp"
        app:stl_titleOffset="24dp"
        app:stl_underlineThickness="0dp"/>
    
    <ImageButton
        android:id="@+id/backspace"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="@color/rsc_emoji_tab_bkg"
        android:paddingLeft="10dip"
        android:paddingRight="10dip"
        android:src="@drawable/sym_keyboard_delete_holo_dark"/>
    

PS2: the button above exists in order to provide the backspace functionality

Part 02: Controller layer

  • Create an adapter to control the insertion of the emojis in the GridView, for example:

    public class EmojiAdapter extends ArrayAdapter<Emoji> {
    
        private boolean mUseSystemDefault = Boolean.FALSE;
    
        // CONSTRUCTOR
        public EmojiAdapter(Context context, Emoji[] data) {
            super(context, R.layout.rsc_emoji_item, data);
        }
    
        public EmojiAdapter(Context context, List<Emoji> data) {
            super(context, R.layout.rsc_emoji_item, data);
        }
    
        public EmojiAdapter(Context context, List<Emoji> data, boolean useSystemDefault) {
            super(context, R.layout.rsc_emoji_item, data);
            this.mUseSystemDefault = useSystemDefault;
        }
    
        public EmojiAdapter(Context context, Emoji[] data, boolean useSystemDefault) {
            super(context, R.layout.rsc_emoji_item, data);
            this.mUseSystemDefault = useSystemDefault;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
    
            if (view == null) {
                view = View.inflate(getContext(), R.layout.rsc_emoji_item, null);
                view.setTag(new ViewHolder(view, this.mUseSystemDefault));
            }
    
            Emoji emoji = this.getItem(position);
            ViewHolder holder = (ViewHolder) view.getTag();
            holder.icon.setText(emoji.getEmoji());
    
            return view;
        }
    
        static class ViewHolder {
            EmojiTextView icon;
    
            public ViewHolder(View view, Boolean useSystemDefault) {
                this.icon = (EmojiTextView) view.findViewById(R.id.emoji_icon);
                this.icon.setUseSystemDefault(useSystemDefault);
            }
        }
    }
    
  • Create classes that will inflate each one of the emoji-pages passing the emojis (following the Unicode pattern) to the GridView. i.e.:

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        GridView gridView = (GridView) view.findViewById(R.id.Emoji_GridView);
        Bundle bundle = getArguments();
        if (bundle == null) {
            mData = Nature.DATA;
            mUseSystemDefault = false;
        } else {
            Parcelable[] parcels = bundle.getParcelableArray(EMOJI_KEY);
            mData = new Emoji[parcels.length];
            for (int i = 0; i < parcels.length; i++) {
                mData[i] = (Emoji) parcels[i];
            }
            mUseSystemDefault = bundle.getBoolean(USE_SYSTEM_DEFAULT_KEY);
        }
        gridView.setAdapter(new EmojiAdapter(view.getContext(), mData, mUseSystemDefault));
        gridView.setOnItemClickListener(this);
    }
    
  • Create two classes: one that extends from EditText and another that extends from TextView. Intercept the input of each one of them to identify when the typed element is an Emoji, if so, add a spannable in order to display the icon (mainly need if you want to override the system default emojis to have something that looks like whats-app or telegram, for instance);

  • Handle the interaction with soft-keyboard. It can be done in two ways:

    1. Draw a Dialog over the soft keyboard;
    2. Disable the interaction of the soft keyboard with the activity and handle the screen draw yourself;

PS3: I had a hard time trying to format the code and still some of the XML is not shown, if someone can fix it I would be thankfull

Jennifferjennilee answered 26/2, 2016 at 14:15 Comment(4)
Just linking to your own library (or utility) is not a good answer. Linking to it, explaining why it solves the problem, providing code using it to do so and disclaiming makes for a better answer. See: How can I link to an external resource in a community-friendly way?Engram
How did you create the gif?Ambiversion
To the author of this answer: please add link to the 2nd library (Android Emoji Keyboard).Ambiversion
If you want emoji-library without import and compiling the whole project, just include in you build.gradle the following entry: compile 'br.com.instachat:emoji-library:1.0.6@aar'Lin
R
7

A viewgroup be visible or gone also can relize that,It doesn't neet the dialog. Every time initialize the emotion , I always user a key value like [happy]=R.drawable.happy. this is the text to emotion while content like [happy]

public SpannableString textToImage(String content,Context c){
    SpannableString ss = new SpannableString(content);
    int starts = 0;
    int end = 0;
    if(content.indexOf("[", starts) != -1 && content.indexOf("]", end) != -1){
        starts = content.indexOf("[", starts);
        end = content.indexOf("]", end);
         SharedPreferences shared=c.getSharedPreferences("emotion",0);
         int resource=shared.getInt(content,0);
        try {
            Drawable drawable =c.getResources().getDrawable(resource);  
            if (drawable != null) {
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 
                ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);  
                ss.setSpan(span, starts,end + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
            }
        } catch (Exception ex){

        }
    }
    return ss;

}
Rebut answered 27/5, 2013 at 8:39 Comment(0)
G
4

You can use this library for Android: https://github.com/rockerhieu/emojicon

Gaslight answered 19/1, 2014 at 9:2 Comment(0)
R
3

Case 1 : Custom Keypad Launched First The Keypad is Created Based on the Size of the Android Keypad , as this Keypad is Height is Unknown Initially the Custom keypad is created with a Fixed height - in this case you have to Move the Edit Area above the Custom Keypad with the Fixed Height ( Which can be used by set Padding on the Parent Layout where Edit area is placed ( parentLayout->setPadding ( 0 , 0 , 0 ,Height) ->Where height is your Initial Keypad Height). Note : Donot Forget to set the padding to 0 when the Custom Keypad is Destroyed or hidden.

case 2 : Android Text Keypad is Launched First

The Keypad is Known Write into Preferences when the Custom Keypad is Launched use this Height. No need of setting any padding cause this is what the Android Keypad Does for you.

Recede answered 21/11, 2014 at 16:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.