From 06eda3814056ee4c6eec7f773220509a835254e2 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 10 Apr 2020 02:11:31 +0300 Subject: [PATCH] emoji_keyboard: first keyboard, supports only unicode emojis --- .../tusky/adapter/UnicodeEmojiAdapter.java | 94 +++++++++++++++++++ .../tusky/view/EmojiKeyboard.java | 89 ++++++++++++++++++ .../main/res/layout/dialog_emoji_keyboard.xml | 8 ++ .../res/layout/item_emoji_keyboard_emoji.xml | 20 ++++ .../res/layout/item_emoji_keyboard_page.xml | 8 ++ app/src/main/res/layout/item_emoji_picker.xml | 24 +++++ 6 files changed, 243 insertions(+) create mode 100644 app/src/main/java/com/keylesspalace/tusky/adapter/UnicodeEmojiAdapter.java create mode 100644 app/src/main/java/com/keylesspalace/tusky/view/EmojiKeyboard.java create mode 100644 app/src/main/res/layout/dialog_emoji_keyboard.xml create mode 100644 app/src/main/res/layout/item_emoji_keyboard_emoji.xml create mode 100644 app/src/main/res/layout/item_emoji_keyboard_page.xml create mode 100644 app/src/main/res/layout/item_emoji_picker.xml diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/UnicodeEmojiAdapter.java b/app/src/main/java/com/keylesspalace/tusky/adapter/UnicodeEmojiAdapter.java new file mode 100644 index 00000000..47adfad3 --- /dev/null +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/UnicodeEmojiAdapter.java @@ -0,0 +1,94 @@ +package com.keylesspalace.tusky.adapter; + +import android.view.*; +import android.util.*; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import com.google.android.flexbox.FlexboxLayoutManager; +import androidx.viewpager2.widget.ViewPager2; +import androidx.recyclerview.widget.*; +import androidx.emoji.widget.EmojiAppCompatButton; +import androidx.emoji.text.EmojiCompat; +import com.keylesspalace.tusky.R; +import com.keylesspalace.tusky.view.EmojiKeyboard; +import com.keylesspalace.tusky.util.Emojis; + +public class UnicodeEmojiAdapter + extends RecyclerView.Adapter + implements TabLayoutMediator.TabConfigurationStrategy { + + private String id; + private EmojiKeyboard.OnEmojiSelectedListener listener; + + private final static float BUTTON_WIDTH_DP = 65.0f; // empirically found value :( + + public UnicodeEmojiAdapter(String id, EmojiKeyboard.OnEmojiSelectedListener listener) { + super(); + this.id = id; + this.listener = listener; + } + + @Override + public void onConfigureTab(TabLayout.Tab tab, int position) { + tab.setText(Emojis.EMOJIS[position][0]); + } + + @Override + public int getItemCount() { + return Emojis.EMOJIS.length; + } + + @Override + public void onBindViewHolder(SingleViewHolder holder, int position) { + ((RecyclerView)holder.itemView).setAdapter(new UnicodeEmojiPageAdapter(Emojis.EMOJIS[position], id, listener)); + } + + @Override + public SingleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_emoji_keyboard_page, parent, false); + SingleViewHolder holder = new SingleViewHolder(view); + + DisplayMetrics dm = parent.getContext().getResources().getDisplayMetrics(); + float wdp = dm.widthPixels / dm.density; + int rows = (int) (wdp / BUTTON_WIDTH_DP + 0.5); + + ((RecyclerView)view).setLayoutManager(new GridLayoutManager(view.getContext(), rows)); + return holder; + } + + private class UnicodeEmojiPageAdapter extends RecyclerView.Adapter { + private final String[] emojis; + private final String id; + private final EmojiKeyboard.OnEmojiSelectedListener listener; + + public UnicodeEmojiPageAdapter(String[] emojis, String id, EmojiKeyboard.OnEmojiSelectedListener listener) { + this.emojis = emojis; + this.id = id; + this.listener = listener; + } + + @Override + public int getItemCount() { + return emojis.length; + } + + @Override + public void onBindViewHolder(SingleViewHolder holder, int position) { + String emoji = emojis[position]; + EmojiAppCompatButton btn = (EmojiAppCompatButton)holder.itemView; + + btn.setText(emoji); + btn.setOnClickListener(v -> listener.onEmojiSelected(id, emoji)); + } + + @Override + public SingleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_emoji_keyboard_emoji, parent, false); + return new SingleViewHolder(view); + } + } + +} + diff --git a/app/src/main/java/com/keylesspalace/tusky/view/EmojiKeyboard.java b/app/src/main/java/com/keylesspalace/tusky/view/EmojiKeyboard.java new file mode 100644 index 00000000..45a1209d --- /dev/null +++ b/app/src/main/java/com/keylesspalace/tusky/view/EmojiKeyboard.java @@ -0,0 +1,89 @@ +package com.keylesspalace.tusky.view; + +import android.view.*; +import android.content.*; +import android.util.*; +import android.widget.*; +import android.app.*; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import androidx.viewpager2.widget.ViewPager2; +import androidx.recyclerview.widget.RecyclerView; +import com.keylesspalace.tusky.R; +import com.keylesspalace.tusky.adapter.UnicodeEmojiAdapter; + +public class EmojiKeyboard extends LinearLayout { + private TabLayout tabs; + private ViewPager2 pager; + private TabLayoutMediator currentMediator; + + public EmojiKeyboard(Context context) { + super(context); + init(context); + } + + public EmojiKeyboard(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public EmojiKeyboard(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + void init(Context context) { + inflate(context, R.layout.item_emoji_picker, this); + + tabs = findViewById(R.id.picker_tabs); + pager = findViewById(R.id.picker_pager); + } + + public static final int UNICODE_MODE = 0; + public static final int CUSTOM_MODE = 1; + public static final int STICKER_MODE = 2; + + void setupKeyboard(String id, int mode, OnEmojiSelectedListener listener) { + RecyclerView.Adapter adapter; + + switch(mode) { + case CUSTOM_MODE: + // UNDONE + //break; + case STICKER_MODE: + // UNDONE + //break; + default: + case UNICODE_MODE: + adapter = new UnicodeEmojiAdapter(id, listener); + break; + } + + pager.setAdapter(adapter); + + if(currentMediator != null) + currentMediator.detach(); + + currentMediator = new TabLayoutMediator(tabs, pager, (TabLayoutMediator.TabConfigurationStrategy)adapter); + currentMediator.attach(); + } + + public interface OnEmojiSelectedListener { + void onEmojiSelected(String id, String emoji); + } + + public static void show(Context ctx, String id, int mode, OnEmojiSelectedListener listener) { + final Dialog dialog = new Dialog(ctx); + + dialog.setTitle(null); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + dialog.setContentView(R.layout.dialog_emoji_keyboard); + EmojiKeyboard kbd = (EmojiKeyboard)dialog.findViewById(R.id.dialog_emoji_keyboard); + kbd.setupKeyboard(id, mode, (_id, _emoji) -> { + listener.onEmojiSelected(_id, _emoji); + dialog.dismiss(); + }); + + dialog.show(); + } +} diff --git a/app/src/main/res/layout/dialog_emoji_keyboard.xml b/app/src/main/res/layout/dialog_emoji_keyboard.xml new file mode 100644 index 00000000..7c76d7d3 --- /dev/null +++ b/app/src/main/res/layout/dialog_emoji_keyboard.xml @@ -0,0 +1,8 @@ + + diff --git a/app/src/main/res/layout/item_emoji_keyboard_emoji.xml b/app/src/main/res/layout/item_emoji_keyboard_emoji.xml new file mode 100644 index 00000000..de740c12 --- /dev/null +++ b/app/src/main/res/layout/item_emoji_keyboard_emoji.xml @@ -0,0 +1,20 @@ + + + diff --git a/app/src/main/res/layout/item_emoji_keyboard_page.xml b/app/src/main/res/layout/item_emoji_keyboard_page.xml new file mode 100644 index 00000000..50202979 --- /dev/null +++ b/app/src/main/res/layout/item_emoji_keyboard_page.xml @@ -0,0 +1,8 @@ + + diff --git a/app/src/main/res/layout/item_emoji_picker.xml b/app/src/main/res/layout/item_emoji_picker.xml new file mode 100644 index 00000000..99a0dd35 --- /dev/null +++ b/app/src/main/res/layout/item_emoji_picker.xml @@ -0,0 +1,24 @@ + + + + + + +