Implementacje widoku Emoji (emotikon) / układów klawiatury

Próbuję dowiedzieć się, w jaki sposób emotikony (emotikony) są zaimplementowane w aplikacji Facebook i Aplikacji Google Hangouts. Zajrzałem do aplikacji SoftKeyboard Demo W Android Api próbki, ale wyświetlanie tych widoków emoji nie wygląda jak SoftKeyboard. Wygląda i zachowuje się bardziej jak niestandardowy widok Dialog. Czy ktoś ma pomysł jak są one realizowane?

Aplikacja Facebook

Facebook

Aplikacja Google Hangouts

Hangouts

Również jest Unicode najlepszy sposób wysyłania Emotikon czy jest jakaś alternatywa? Zauważyłem, że niektóre Unicode sekwencje jak \u1F601 nie renderują odpowiednich emotikon i zamiast tego sekwencja ta pojawia się jako 1:

EditText messageInput = (EditText) findViewById(R.id.message_input);
messageInput.getText().append("\u1F601");
Author: toobsco42, 2013-05-27

6 answers

Znalazłem bardzo przydatną klawiaturę Emotikon . Ta klawiatura nie używa sekwencji Unicode, ale tylko lokalnych zasobów obrazu. Myślę, że ten typ klawiatury może być przydatny tylko w tej aplikacji, a nie w innych aplikacjach lub systemach operacyjnych.

Zamiast tego zamieniam ImageView zawierający zasób na TextView zawierający sekwencję Unicode.

Po odsyłaczu obsługiwane sekwencje Unicode oraz wizualna baza danych Unicode I zdałem sobie sprawę, że \u1F601 jest 32-bitową reprezentacją Unicode, a 16-bitową reprezentację można ustawić następująco:

EditText messageInput = (EditText) findViewById(R.id.message_input);
messageInput.getText().append("\ud83d\ude01");
 44
Author: toobsco42,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-09 22:50:00

Możesz korzystać z tej biblioteki w oparciu o bibliotekę Hieu Rocker: https://github.com/ankushsachdeva/emojicon

Tak to wygląda

Zrzut ekranu

 24
Author: ankush,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-05 01:00:28

Viewgroup be visible or gone również może to zmienić,nie wymaga okna dialogowego. Za każdym razem inicjalizuj emocje, zawsze używam wartości klucza, takiej jak [happy]=R. drawable.szczęśliwy. jest to tekst do emocji, podczas gdy Treść jak [szczęśliwy]

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;

}
 7
Author: user1971705,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 08:39:10

Jeśli nie chcesz wchodzić w szczegóły, jak zaimplementować funkcjonalność klawiatury Emoji, możesz wypróbować następujące biblioteki:

  • Rockerhieu / emojicon : implementuje klawiaturę Emoji za pomocą fragmentów (musisz obsługiwać wyświetlanie jej za pomocą DialogFragment. Nie ma wsparcia dla zmiany układu i domyślnym jest Hole Dark theme;

  • Android Emoji Keyboard : na podstawie pracy Rockerhieu zbudowałem kolejną lib, która zapewnia klawiaturę emoji jako bliższą temu, co widzieliśmy w aplikacjach takich jak WhatsApp lub Telegram. Możesz obsługiwać układ jako LinearLayout, a zatem samodzielnie obsługiwać interakcję z miękką klawiaturą (jak opisano poniżej) lub wybrać panel Telegram lub panel WhatsApp, oba dostarczane przez bibliotekę, która robi to za Ciebie.

PS1: obie biblioteki są licencją Apache

Efekt końcowy powinien wyglądać tak

Część 01: budowanie układu

  • Utwórz GridView dla każdej strony Emoji, którą chcesz na klawiaturze. Na przykład:

  • Zwiąż utworzone widoki we fragmentach:

    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);
    }
    

    }

  • Utwórz nowy układ zawierający widok pagera i komponent do sterowania przejściem widoku pagera (w moim przypadku użyłem biblioteki trzeciej części o nazwie SmartTabLayout, Jak pokazano poniżej:

    <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: przycisk powyżej istnieje w celu zapewnienia backspace funkcjonalność

Część 02: warstwa kontrolera

  • Utwórz adapter do kontrolowania wstawiania emotikon w widoku GridView, na przykład:

    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);
            }
        }
    }
    
  • Utwórz klasy, które będą napompowywać każdą z emoji-stron przekazujących Emoji (zgodnie ze wzorem Unicode) do GridView. tj.:

    @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);
    }
    
  • Utwórz dwie klasy: jedną rozszerzającą się z EditText i drugą rozszerzającą się z TextView. Przechwycić wejście każdego z nich jeśli tak, dodaj spannable, aby wyświetlić ikonę (głównie potrzebujesz, jeśli chcesz nadpisać domyślne emotikony systemowe, aby mieć coś, co wygląda jak whats-app lub telegram, na przykład);

  • Obsługiwać interakcję z miękką klawiaturą. Można to zrobić na dwa sposoby:

    1. narysuj okno dialogowe nad miękką klawiaturą;
    2. wyłącz interakcję miękkiej klawiatury z aktywnością i obsługuj screen draw yourself;

PS3: ciężko mi było sformatować kod i nadal część XML nie jest wyświetlana, gdyby ktoś mógł to naprawić byłbym wdzięczny

 7
Author: Edgar Da Silva Fernandes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-11 21:05:07

Możesz użyć tej biblioteki dla Androida: https://github.com/rockerhieu/emojicon

 4
Author: Hieu Rocker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-19 09:02:19

Przypadek 1: Custom Keypad Uruchomiony Jako Pierwszy Klawiatura jest tworzona na podstawie rozmiaru klawiatury Androida, ponieważ wysokość tej klawiatury jest nieznana Początkowo niestandardowa klawiatura jest tworzona ze stałą wysokością - w tym przypadku należy przesunąć obszar edycji nad niestandardową klawiaturą ze stałą wysokością ( co może być użyte przez ustawienie Padding w układzie nadrzędnym, w którym znajduje się obszar edycji ( parentLayout->setPadding ( 0 , 0 , 0 ,Height) ->Where height to początkowa wysokość klawiatury). Uwaga: nie zapomnij Ustaw padding na 0, gdy niestandardowa klawiatura zostanie zniszczona lub ukryta.

Przypadek 2: Klawiatura tekstowa Androida jest uruchamiana jako pierwsza

Klawiatura jest znana Zapisz do preferencji, gdy zostanie uruchomiona niestandardowa klawiatura użyj tej wysokości. Nie ma potrzeby ustawiania żadnej wyściółki, ponieważ to jest to, co robi dla Ciebie Klawiatura Android.

 3
Author: surya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-21 16:06:11