@ -0,0 +1,55 @@ |
|||||
|
package gr.thmmy.mthmmy.editorview; |
||||
|
|
||||
|
import android.content.Context; |
||||
|
import android.content.res.TypedArray; |
||||
|
import android.util.AttributeSet; |
||||
|
import android.widget.GridLayout; |
||||
|
import gr.thmmy.mthmmy.R; |
||||
|
|
||||
|
public class AutoFitGridLayout extends GridLayout { |
||||
|
private int columnWidth; |
||||
|
private int defaultColumnCount; |
||||
|
|
||||
|
public AutoFitGridLayout(Context context) { |
||||
|
super(context); |
||||
|
init(context, null, 0); |
||||
|
} |
||||
|
|
||||
|
public AutoFitGridLayout(Context context, AttributeSet attrs) { |
||||
|
super(context, attrs); |
||||
|
init(context, attrs, 0); |
||||
|
} |
||||
|
|
||||
|
public AutoFitGridLayout(Context context, AttributeSet attrs, int defStyleAttr) { |
||||
|
super(context, attrs, defStyleAttr); |
||||
|
init(context, attrs, defStyleAttr); |
||||
|
} |
||||
|
|
||||
|
public void init(Context context, AttributeSet attrs, int defStyleAttr) { |
||||
|
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoFitGridLayout, 0, defStyleAttr); |
||||
|
try { |
||||
|
columnWidth = a.getDimensionPixelSize(R.styleable.AutoFitGridLayout_columnWidth, 0); |
||||
|
|
||||
|
int[] set = {android.R.attr.columnCount}; |
||||
|
a = context.obtainStyledAttributes(attrs, set, 0, defStyleAttr); |
||||
|
defaultColumnCount = a.getInt(0, 6); |
||||
|
} finally { |
||||
|
a.recycle(); |
||||
|
} |
||||
|
setColumnCount(1); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected void onMeasure(int widthSpec, int heightSpec) { |
||||
|
super.onMeasure(widthSpec, heightSpec); |
||||
|
|
||||
|
int width = MeasureSpec.getSize(widthSpec); |
||||
|
if (columnWidth > 0 && width > 0) { |
||||
|
int totalSpace = width - getPaddingRight() - getPaddingLeft(); |
||||
|
int columnCount = Math.max(1, totalSpace / columnWidth); |
||||
|
setColumnCount(columnCount); |
||||
|
} else { |
||||
|
setColumnCount(defaultColumnCount); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,283 @@ |
|||||
|
package gr.thmmy.mthmmy.editorview; |
||||
|
|
||||
|
import android.app.Activity; |
||||
|
import android.app.AlertDialog; |
||||
|
import android.content.Context; |
||||
|
import android.content.res.TypedArray; |
||||
|
import android.graphics.drawable.Drawable; |
||||
|
import android.support.annotation.Nullable; |
||||
|
import android.support.design.widget.TextInputEditText; |
||||
|
import android.support.design.widget.TextInputLayout; |
||||
|
import android.support.v7.widget.AppCompatImageButton; |
||||
|
import android.text.Editable; |
||||
|
import android.text.TextUtils; |
||||
|
import android.util.AttributeSet; |
||||
|
import android.util.SparseArray; |
||||
|
import android.view.LayoutInflater; |
||||
|
import android.view.inputmethod.EditorInfo; |
||||
|
import android.view.inputmethod.InputConnection; |
||||
|
import android.view.inputmethod.InputMethodManager; |
||||
|
import android.widget.LinearLayout; |
||||
|
import android.widget.PopupWindow; |
||||
|
import android.widget.ScrollView; |
||||
|
|
||||
|
import java.util.Objects; |
||||
|
|
||||
|
import gr.thmmy.mthmmy.R; |
||||
|
|
||||
|
public class EditorView extends LinearLayout { |
||||
|
|
||||
|
private SparseArray<String> colors = new SparseArray<>(); |
||||
|
|
||||
|
private TextInputLayout edittextWrapper; |
||||
|
private TextInputEditText editText; |
||||
|
private AppCompatImageButton emojiButton; |
||||
|
private AppCompatImageButton submitButton; |
||||
|
private EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner; |
||||
|
|
||||
|
public EditorView(Context context) { |
||||
|
super(context); |
||||
|
init(context, null); |
||||
|
} |
||||
|
|
||||
|
public EditorView(Context context, AttributeSet attrs) { |
||||
|
super(context, attrs); |
||||
|
init(context, attrs); |
||||
|
} |
||||
|
|
||||
|
public EditorView(Context context, AttributeSet attrs, int defStyleAttrs) { |
||||
|
super(context, attrs, defStyleAttrs); |
||||
|
init(context, attrs); |
||||
|
} |
||||
|
|
||||
|
private void init(Context context, AttributeSet attrs) { |
||||
|
LayoutInflater.from(context).inflate(R.layout.editor_view, this, true); |
||||
|
setOrientation(VERTICAL); |
||||
|
|
||||
|
edittextWrapper = findViewById(R.id.editor_edittext_wrapper); |
||||
|
editText = findViewById(R.id.editor_edittext); |
||||
|
|
||||
|
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EditorView, 0, 0); |
||||
|
try { |
||||
|
editText.setHint(a.getString(R.styleable.EditorView_hint)); |
||||
|
} finally { |
||||
|
a.recycle(); |
||||
|
} |
||||
|
|
||||
|
// without this, the editor gets default window background
|
||||
|
Drawable background = getBackground(); |
||||
|
for (int i = 0; i < getChildCount(); i++) { |
||||
|
getChildAt(i).setBackground(background); |
||||
|
} |
||||
|
|
||||
|
emojiButton = findViewById(R.id.emoji_keyboard_button); |
||||
|
|
||||
|
editText.setOnTouchListener((v, event) -> { |
||||
|
if (emojiKeyboardOwner.isEmojiKeyboardVisible()) return true; |
||||
|
return false; |
||||
|
}); |
||||
|
|
||||
|
emojiButton.setOnClickListener(view -> { |
||||
|
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE); |
||||
|
assert imm != null; |
||||
|
if (emojiKeyboardOwner.isEmojiKeyboardVisible()) { |
||||
|
editText.requestFocus(); |
||||
|
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); |
||||
|
emojiButton.setImageResource(R.drawable.ic_tag_faces_24dp); |
||||
|
} else { |
||||
|
imm.hideSoftInputFromWindow(getWindowToken(), 0); |
||||
|
view.clearFocus(); |
||||
|
emojiButton.setImageResource(R.drawable.ic_keyboard_24dp); |
||||
|
} |
||||
|
emojiKeyboardOwner.setEmojiKeyboardVisible(!emojiKeyboardOwner.isEmojiKeyboardVisible()); |
||||
|
}); |
||||
|
|
||||
|
submitButton = findViewById(R.id.submit_button); |
||||
|
findViewById(R.id.bold_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[b]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/b]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 4); |
||||
|
}); |
||||
|
findViewById(R.id.italic_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[i]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/i]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 4); |
||||
|
}); |
||||
|
findViewById(R.id.underline_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[u]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/u]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 4); |
||||
|
}); |
||||
|
findViewById(R.id.strikethrough_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[s]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/s]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 4); |
||||
|
}); |
||||
|
|
||||
|
colors.append(R.id.black, "black"); |
||||
|
colors.append(R.id.red, "red"); |
||||
|
colors.append(R.id.yellow, "yellow"); |
||||
|
colors.append(R.id.pink, "pink"); |
||||
|
colors.append(R.id.green, "green"); |
||||
|
colors.append(R.id.orange, "orange"); |
||||
|
colors.append(R.id.purple, "purple"); |
||||
|
colors.append(R.id.blue, "blue"); |
||||
|
colors.append(R.id.beige, "beige"); |
||||
|
colors.append(R.id.brown, "brown"); |
||||
|
colors.append(R.id.teal, "teal"); |
||||
|
colors.append(R.id.navy, "navy"); |
||||
|
colors.append(R.id.maroon, "maroon"); |
||||
|
colors.append(R.id.lime_green, "limegreen"); |
||||
|
|
||||
|
findViewById(R.id.text_color_button).setOnClickListener(view -> { |
||||
|
PopupWindow popupWindow = new PopupWindow(view.getContext()); |
||||
|
popupWindow.setHeight(LayoutParams.WRAP_CONTENT); |
||||
|
popupWindow.setWidth(LayoutParams.WRAP_CONTENT); |
||||
|
popupWindow.setFocusable(true); |
||||
|
ScrollView colorPickerScrollview = (ScrollView) LayoutInflater.from(context).inflate(R.layout.editor_view_color_picker, null); |
||||
|
LinearLayout colorPicker = (LinearLayout) colorPickerScrollview.getChildAt(0); |
||||
|
popupWindow.setContentView(colorPickerScrollview); |
||||
|
for (int i = 0; i < colorPicker.getChildCount(); i++) { |
||||
|
colorPicker.getChildAt(i).setOnClickListener(v -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[color=" + colors.get(v.getId()) + "]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/color]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 8); |
||||
|
popupWindow.dismiss(); |
||||
|
}); |
||||
|
} |
||||
|
popupWindow.showAsDropDown(view); |
||||
|
}); |
||||
|
findViewById(R.id.text_size_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[size=10pt]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/size]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 7); |
||||
|
}); |
||||
|
findViewById(R.id.font_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[font=Verdana]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/font]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 7); |
||||
|
}); |
||||
|
findViewById(R.id.unordered_list_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[list]\n[li]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/li]\n[li][/li]\n[/list]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() - 13 : editText.getSelectionStart() - 23); |
||||
|
}); |
||||
|
findViewById(R.id.align_left_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[left]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/left]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 7); |
||||
|
}); |
||||
|
findViewById(R.id.align_center_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[center]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/center]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 9); |
||||
|
}); |
||||
|
findViewById(R.id.align_right_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[right]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/right]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 8); |
||||
|
}); |
||||
|
findViewById(R.id.link_button).setOnClickListener(view -> { |
||||
|
LinearLayout dialogBody = (LinearLayout) LayoutInflater.from(context) |
||||
|
.inflate(R.layout.dialog_create_link, null); |
||||
|
TextInputLayout linkUrl = dialogBody.findViewById(R.id.link_url_input); |
||||
|
linkUrl.setOnClickListener(view1 -> linkUrl.setError(null)); |
||||
|
TextInputLayout linkText = dialogBody.findViewById(R.id.link_text_input); |
||||
|
linkText.setOnClickListener(view2 -> linkText.setError(null)); |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
int start = editText.getSelectionStart(), end = editText.getSelectionEnd(); |
||||
|
if (editText.hasSelection()) { |
||||
|
linkText.getEditText().setText( |
||||
|
editText.getText().toString().substring(editText.getSelectionStart(), editText.getSelectionEnd())); |
||||
|
} |
||||
|
new AlertDialog.Builder(context, R.style.AppCompatAlertDialogStyleAccent) |
||||
|
.setTitle(R.string.dialog_create_link_title) |
||||
|
.setView(dialogBody) |
||||
|
.setPositiveButton(R.string.ok, (dialog, which) -> { |
||||
|
if (TextUtils.isEmpty(Objects.requireNonNull(linkUrl.getEditText()).getText().toString())) { |
||||
|
linkUrl.setError(context.getString(R.string.input_field_required)); |
||||
|
return; |
||||
|
} |
||||
|
if (TextUtils.isEmpty(Objects.requireNonNull(linkText.getEditText()).getText().toString())) { |
||||
|
linkUrl.setError(context.getString(R.string.input_field_required)); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (hadTextSelection) editText.getText().delete(start, end); |
||||
|
getText().insert(editText.getSelectionStart(), "[url=" + |
||||
|
Objects.requireNonNull(linkUrl.getEditText()).getText().toString() + "]" + |
||||
|
Objects.requireNonNull(linkText.getEditText()).getText().toString() + "[/url]"); |
||||
|
}) |
||||
|
.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()) |
||||
|
.show(); |
||||
|
}); |
||||
|
findViewById(R.id.quote_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[quote]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/quote]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 8); |
||||
|
}); |
||||
|
findViewById(R.id.code_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[code]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/code]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 7); |
||||
|
}); |
||||
|
findViewById(R.id.math_button).setOnClickListener(view -> { |
||||
|
boolean hadTextSelection = editText.hasSelection(); |
||||
|
getText().insert(editText.getSelectionStart(), "[tex]"); |
||||
|
getText().insert(editText.getSelectionEnd(), "[/tex]"); |
||||
|
editText.setSelection(hadTextSelection ? editText.getSelectionEnd() : editText.getSelectionStart() - 6); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public TextInputEditText getEditText() { |
||||
|
return editText; |
||||
|
} |
||||
|
|
||||
|
public Editable getText() { |
||||
|
return editText.getText(); |
||||
|
} |
||||
|
|
||||
|
public void setText(Editable text) { |
||||
|
editText.setText(text); |
||||
|
} |
||||
|
|
||||
|
public void setText(CharSequence text) { |
||||
|
editText.setText(text); |
||||
|
} |
||||
|
|
||||
|
public void setError(@Nullable CharSequence text) { |
||||
|
edittextWrapper.setError(text); |
||||
|
} |
||||
|
|
||||
|
public void setOnSubmitListener(OnClickListener onSubmitListener) { |
||||
|
submitButton.setOnClickListener(onSubmitListener); |
||||
|
} |
||||
|
|
||||
|
public void setEmojiKeyboardOwner(EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner) { |
||||
|
this.emojiKeyboardOwner = emojiKeyboardOwner; |
||||
|
} |
||||
|
|
||||
|
public InputConnection getInputConnection() { |
||||
|
return editText.onCreateInputConnection(new EditorInfo()); |
||||
|
} |
||||
|
|
||||
|
public void updateEmojiKeyboardVisibility() { |
||||
|
if (emojiKeyboardOwner.isEmojiKeyboardVisible()) |
||||
|
emojiButton.setImageResource(R.drawable.ic_keyboard_24dp); |
||||
|
else |
||||
|
emojiButton.setImageResource(R.drawable.ic_tag_faces_24dp); |
||||
|
} |
||||
|
} |
@ -0,0 +1,241 @@ |
|||||
|
package gr.thmmy.mthmmy.editorview; |
||||
|
|
||||
|
import android.content.Context; |
||||
|
import android.os.Handler; |
||||
|
import android.support.v7.widget.AppCompatImageButton; |
||||
|
import android.support.v7.widget.GridLayoutManager; |
||||
|
import android.support.v7.widget.RecyclerView; |
||||
|
import android.text.TextUtils; |
||||
|
import android.util.AttributeSet; |
||||
|
import android.view.LayoutInflater; |
||||
|
import android.view.MotionEvent; |
||||
|
import android.view.inputmethod.InputConnection; |
||||
|
import android.widget.LinearLayout; |
||||
|
|
||||
|
import gr.thmmy.mthmmy.R; |
||||
|
|
||||
|
public class EmojiKeyboard extends LinearLayout { |
||||
|
|
||||
|
// TODO: Sort emojis in a way that makes sense
|
||||
|
private final Emoji[] emojis = {new Emoji(R.drawable.emoji_smiley, ":)"), |
||||
|
new Emoji(R.drawable.emoji_wink, ";)"), |
||||
|
new Emoji(R.drawable.emoji_cheesy, ":D"), |
||||
|
new Emoji(R.drawable.emoji_grin, ";D"), |
||||
|
// removed repeated angry emoji
|
||||
|
new Emoji(R.drawable.emoji_angry, ">:("), |
||||
|
new Emoji(R.drawable.emoji_sad, ":("), |
||||
|
new Emoji(R.drawable.emoji_shocked, ":o"), |
||||
|
new Emoji(R.drawable.emoji_cool, "8))"), |
||||
|
new Emoji(R.drawable.emoji_huh, ":???:"), |
||||
|
new Emoji(R.drawable.emoji_rolleyes, "::)"), |
||||
|
new Emoji(R.drawable.emoji_tongue, ":P"), |
||||
|
new Emoji(R.drawable.emoji_embarrassed, ":-["), |
||||
|
new Emoji(R.drawable.emoji_lipsrsealed, ":-X"), |
||||
|
new Emoji(R.drawable.emoji_undecided, ":-\\\\"), |
||||
|
new Emoji(R.drawable.emoji_kiss, ":-*"), |
||||
|
new Emoji(R.drawable.emoji_cry, ":'("), |
||||
|
new Emoji(R.drawable.emoji_heart, "<3"), |
||||
|
// removed repeated lock emoji
|
||||
|
new Emoji(R.drawable.emoji_locked, "^lock^"), |
||||
|
new Emoji(R.drawable.emoji_roll_over, "^rollover^"), |
||||
|
new Emoji(R.drawable.emoji_redface, "^redface^"), |
||||
|
new Emoji(R.drawable.emoji_confused, "^confused^"), |
||||
|
new Emoji(R.drawable.emoji_innocent, "^innocent^"), |
||||
|
new Emoji(R.drawable.emoji_sleep, "^sleep^"), |
||||
|
new Emoji(R.drawable.emoji_lips_sealed, "^sealed^"), |
||||
|
new Emoji(R.drawable.emoji_cool2, "^cool^"), |
||||
|
new Emoji(R.drawable.emoji_monster, "^monster^"), |
||||
|
new Emoji(R.drawable.emoji_crazy, "^crazy^"), |
||||
|
new Emoji(R.drawable.emoji_mad, "^mad^"), |
||||
|
new Emoji(R.drawable.emoji_wav, "^wav^"), |
||||
|
new Emoji(R.drawable.emoji_binkybaby, "^binkybaby^"), |
||||
|
new Emoji(R.drawable.emoji_police, "^police^"), |
||||
|
new Emoji(R.drawable.emoji_dontknow, "^dontknow^"), |
||||
|
//removed repeated angry hot emoji
|
||||
|
new Emoji(R.drawable.emoji_angry_hot, "^angryhot^"), |
||||
|
new Emoji(R.drawable.emoji_foyska, "^fouska^"), |
||||
|
new Emoji(R.drawable.emoji_e10_7_3e, "^sfinaki^"), |
||||
|
new Emoji(R.drawable.emoji_bang_head, "^banghead^"), |
||||
|
new Emoji(R.drawable.emoji_crybaby, "^crybaby^"), |
||||
|
new Emoji(R.drawable.emoji_hello, "^hello^"), |
||||
|
new Emoji(R.drawable.emoji_jerk, "^jerk^"), |
||||
|
new Emoji(R.drawable.emoji_nono, "^nono^"), |
||||
|
new Emoji(R.drawable.emoji_notworthy, "^notworthy^"), |
||||
|
new Emoji(R.drawable.emoji_off_topic, "^off-topic^"), |
||||
|
new Emoji(R.drawable.emoji_puke, "^puke^"), |
||||
|
new Emoji(R.drawable.emoji_shout, "^shout^"), |
||||
|
new Emoji(R.drawable.emoji_slurp, "^slurp^"), |
||||
|
new Emoji(R.drawable.emoji_superconfused, "^superconfused^"), |
||||
|
new Emoji(R.drawable.emoji_superinnocent, "^superinnocent^"), |
||||
|
new Emoji(R.drawable.emoji_cell_phone, "^cellPhone^"), |
||||
|
new Emoji(R.drawable.emoji_idiot, "^idiot^"), |
||||
|
new Emoji(R.drawable.emoji_knuppel, "^knuppel^"), |
||||
|
new Emoji(R.drawable.emoji_tickedoff, "^tickedOff^"), |
||||
|
new Emoji(R.drawable.emoji_peace, "^peace^"), |
||||
|
new Emoji(R.drawable.emoji_suspicious, "^suspicious^"), |
||||
|
new Emoji(R.drawable.emoji_caffine, "^caffine^"), |
||||
|
new Emoji(R.drawable.emoji_argue, "^argue^"), |
||||
|
new Emoji(R.drawable.emoji_banned2, "^banned2^"), |
||||
|
new Emoji(R.drawable.emoji_banned, "^banned^"), |
||||
|
new Emoji(R.drawable.emoji_bath, "^bath^"), |
||||
|
new Emoji(R.drawable.emoji_beg, "^beg^"), |
||||
|
new Emoji(R.drawable.emoji_bluescreen, "^bluescreen^"), |
||||
|
new Emoji(R.drawable.emoji_boil, "^boil^"), |
||||
|
new Emoji(R.drawable.emoji_bye, "^bye^"), |
||||
|
new Emoji(R.drawable.emoji_callmerip, "^callmerip^"), |
||||
|
new Emoji(R.drawable.emoji_carnaval, "^carnaval^"), |
||||
|
new Emoji(R.drawable.emoji_clap, "^clap^"), |
||||
|
new Emoji(R.drawable.emoji_coffeepot, "^coffepot^"), |
||||
|
new Emoji(R.drawable.emoji_crap, "^crap^"), |
||||
|
new Emoji(R.drawable.emoji_curses, "^curses^"), |
||||
|
new Emoji(R.drawable.emoji_funny, "^funny^"), |
||||
|
new Emoji(R.drawable.emoji_guitar1, "^guitar^"), |
||||
|
new Emoji(R.drawable.emoji_icon_kissy, "^kissy^"), |
||||
|
new Emoji(R.drawable.emoji_band, "^band^"), |
||||
|
new Emoji(R.drawable.emoji_ivres, "^ivres^"), |
||||
|
new Emoji(R.drawable.emoji_kaloe, "^kaloe^"), |
||||
|
new Emoji(R.drawable.emoji_kremala, "^kremala^"), |
||||
|
new Emoji(R.drawable.emoji_moon, "^moon^"), |
||||
|
new Emoji(R.drawable.emoji_mopping, "^mopping^"), |
||||
|
new Emoji(R.drawable.emoji_mountza, "^mountza^"), |
||||
|
new Emoji(R.drawable.emoji_pcsleep, "^pcsleep^"), |
||||
|
new Emoji(R.drawable.emoji_pinokio, "^pinokio^"), |
||||
|
new Emoji(R.drawable.emoji_poke, "^poke^"), |
||||
|
new Emoji(R.drawable.emoji_seestars, "^seestars^"), |
||||
|
new Emoji(R.drawable.emoji_sfyri, "^sfyri^"), |
||||
|
new Emoji(R.drawable.emoji_spam2, "^spam^"), |
||||
|
new Emoji(R.drawable.emoji_esuper, "^super^"), |
||||
|
new Emoji(R.drawable.emoji_tafos, "^tafos^"), |
||||
|
new Emoji(R.drawable.emoji_tomatomourh, "^tomato^"), |
||||
|
new Emoji(R.drawable.emoji_ytold, "^ytold^"), |
||||
|
new Emoji(R.drawable.emoji_beer2, "^beer^"), |
||||
|
new Emoji(R.drawable.emoji_yu, "^yue^"), |
||||
|
new Emoji(R.drawable.emoji_a_eatpaper, "^eatpaper^"), |
||||
|
new Emoji(R.drawable.emoji_fritz, "^fritz^"), |
||||
|
new Emoji(R.drawable.emoji_wade, "^wade^"), |
||||
|
new Emoji(R.drawable.emoji_lypi, "^lypi^"), |
||||
|
new Emoji(R.drawable.emoji_megashok1wq, "^aytoxeir^"), |
||||
|
new Emoji(R.drawable.emoji_victory, "^victory^"), |
||||
|
new Emoji(R.drawable.emoji_filarakia, "^filarakia^"), |
||||
|
new Emoji(R.drawable.emoji_bonjour_97213, "^hat^"), |
||||
|
new Emoji(R.drawable.emoji_curtseyqi9, "^miss^"), |
||||
|
new Emoji(R.drawable.emoji_rofl, "^rolfmao^"), |
||||
|
new Emoji(R.drawable.emoji_question, "^que^"), |
||||
|
new Emoji(R.drawable.emoji_shifty, "^shifty^"), |
||||
|
new Emoji(R.drawable.emoji_shy, "^shy^"), |
||||
|
new Emoji(R.drawable.emoji_music, "^music_listen^"), |
||||
|
new Emoji(R.drawable.emoji_shamed_bag, "^bagface^"), |
||||
|
new Emoji(R.drawable.emoji_rotfl, "^rotate^"), |
||||
|
new Emoji(R.drawable.emoji_love, "^love^"), |
||||
|
new Emoji(R.drawable.emoji_speech, "^speech^"), |
||||
|
new Emoji(R.drawable.emoji_facepalm, "^facepalm^"), |
||||
|
new Emoji(R.drawable.emoji_shocked2, "^shocked^"), |
||||
|
new Emoji(R.drawable.emoji_extremely_shocked, "^ex_shocked^"), |
||||
|
new Emoji(R.drawable.emoji_smurf, "^smurf^") |
||||
|
}; |
||||
|
|
||||
|
InputConnection inputConnection; |
||||
|
|
||||
|
public EmojiKeyboard(Context context) { |
||||
|
this(context, null, 0); |
||||
|
} |
||||
|
|
||||
|
public EmojiKeyboard(Context context, AttributeSet attrs) { |
||||
|
this(context, attrs, 0); |
||||
|
} |
||||
|
|
||||
|
public EmojiKeyboard(Context context, AttributeSet attrs, int defStyleAttrs) { |
||||
|
super(context, attrs, defStyleAttrs); |
||||
|
init(context, attrs); |
||||
|
} |
||||
|
|
||||
|
public void init(Context context, AttributeSet attrs) { |
||||
|
LayoutInflater.from(context).inflate(R.layout.emoji_keyboard, this, true); |
||||
|
setOrientation(VERTICAL); |
||||
|
|
||||
|
RecyclerView emojiRecyclerview = findViewById(R.id.emoji_recyclerview); |
||||
|
emojiRecyclerview.setHasFixedSize(true); |
||||
|
GridLayoutManager emojiLayoutManager = new GridLayoutManager(context, 6); |
||||
|
emojiLayoutManager.setSpanSizeLookup(new EmojiColumnSpanLookup()); |
||||
|
emojiRecyclerview.setLayoutManager(emojiLayoutManager); |
||||
|
|
||||
|
EmojiKeyboardAdapter emojiKeyboardAdapter = new EmojiKeyboardAdapter(emojis); |
||||
|
emojiKeyboardAdapter.setOnEmojiClickListener((view, position) -> { |
||||
|
if (inputConnection == null) return; |
||||
|
String bbcode = emojis[position].getBbcode(); |
||||
|
inputConnection.commitText(" " + bbcode, 1); |
||||
|
}); |
||||
|
emojiRecyclerview.setAdapter(emojiKeyboardAdapter); |
||||
|
AppCompatImageButton backspaceButton = findViewById(R.id.backspace_button); |
||||
|
// backspace behavior
|
||||
|
final Handler handler = new Handler(); |
||||
|
Runnable longPressed = new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
inputConnection.deleteSurroundingText(1, 0); |
||||
|
handler.postDelayed(this, 50); |
||||
|
} |
||||
|
}; |
||||
|
backspaceButton.setOnTouchListener((v, event) -> { |
||||
|
switch (event.getAction()) { |
||||
|
case MotionEvent.ACTION_DOWN: |
||||
|
CharSequence selectedText = inputConnection.getSelectedText(0); |
||||
|
if (TextUtils.isEmpty(selectedText)) |
||||
|
inputConnection.deleteSurroundingText(1, 0); |
||||
|
else |
||||
|
inputConnection.commitText("", 1); |
||||
|
handler.postDelayed(longPressed, 400); |
||||
|
break; |
||||
|
case MotionEvent.ACTION_UP: |
||||
|
handler.removeCallbacks(longPressed); |
||||
|
break; |
||||
|
} |
||||
|
return true; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public void setInputConnection(InputConnection inputConnection) { |
||||
|
this.inputConnection = inputConnection; |
||||
|
} |
||||
|
|
||||
|
public interface EmojiKeyboardOwner { |
||||
|
void setEmojiKeyboardVisible(boolean visible); |
||||
|
boolean isEmojiKeyboardVisible(); |
||||
|
void setEmojiKeyboardInputConnection(InputConnection ic); |
||||
|
} |
||||
|
|
||||
|
class Emoji { |
||||
|
final int src; |
||||
|
final String bbcode; |
||||
|
|
||||
|
public Emoji(int src, String bbcode) { |
||||
|
this.src = src; |
||||
|
this.bbcode = bbcode; |
||||
|
} |
||||
|
|
||||
|
public int getSrc() { |
||||
|
return src; |
||||
|
} |
||||
|
|
||||
|
public String getBbcode() { |
||||
|
return bbcode; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class EmojiColumnSpanLookup extends GridLayoutManager.SpanSizeLookup { |
||||
|
|
||||
|
@Override |
||||
|
public int getSpanSize(int position) { |
||||
|
switch (emojis[position].getSrc()) { |
||||
|
case R.drawable.emoji_wav: |
||||
|
return 4; |
||||
|
case R.drawable.emoji_band: |
||||
|
return 3; |
||||
|
case R.drawable.emoji_pcsleep: |
||||
|
return 2; |
||||
|
default: |
||||
|
return 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,64 @@ |
|||||
|
package gr.thmmy.mthmmy.editorview; |
||||
|
|
||||
|
import android.graphics.drawable.AnimationDrawable; |
||||
|
import android.support.annotation.NonNull; |
||||
|
import android.support.v7.widget.AppCompatImageButton; |
||||
|
import android.support.v7.widget.RecyclerView; |
||||
|
import android.view.LayoutInflater; |
||||
|
import android.view.View; |
||||
|
import android.view.ViewGroup; |
||||
|
|
||||
|
import gr.thmmy.mthmmy.R; |
||||
|
|
||||
|
public class EmojiKeyboardAdapter extends RecyclerView.Adapter<EmojiKeyboardAdapter.EmojiViewHolder> { |
||||
|
private EmojiKeyboard.Emoji[] emojiIds; |
||||
|
private OnEmojiClickListener listener; |
||||
|
|
||||
|
public EmojiKeyboardAdapter(EmojiKeyboard.Emoji[] emojiIds) { |
||||
|
this.emojiIds = emojiIds; |
||||
|
} |
||||
|
|
||||
|
public void setOnEmojiClickListener(OnEmojiClickListener listener) { |
||||
|
this.listener = listener; |
||||
|
} |
||||
|
|
||||
|
@NonNull |
||||
|
@Override |
||||
|
public EmojiViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { |
||||
|
AppCompatImageButton emojiButton = (AppCompatImageButton) LayoutInflater.from(parent.getContext()) |
||||
|
.inflate(R.layout.emoji_keyboard_grid_cell, parent, false); |
||||
|
return new EmojiViewHolder(emojiButton); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onBindViewHolder(@NonNull EmojiViewHolder holder, int position) { |
||||
|
holder.emojiButton.setOnClickListener(view -> listener.onEmojiClick(view, position)); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onViewAttachedToWindow(@NonNull EmojiViewHolder holder) { |
||||
|
holder.emojiButton.setImageResource(emojiIds[holder.getAdapterPosition()].getSrc()); |
||||
|
if (holder.emojiButton.getDrawable() instanceof AnimationDrawable) { |
||||
|
AnimationDrawable emojiAnimation = (AnimationDrawable) holder.emojiButton.getDrawable(); |
||||
|
emojiAnimation.start(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getItemCount() { |
||||
|
return emojiIds.length; |
||||
|
} |
||||
|
|
||||
|
static class EmojiViewHolder extends RecyclerView.ViewHolder { |
||||
|
AppCompatImageButton emojiButton; |
||||
|
|
||||
|
EmojiViewHolder(AppCompatImageButton emojiButton) { |
||||
|
super(emojiButton); |
||||
|
this.emojiButton = emojiButton; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
interface OnEmojiClickListener { |
||||
|
void onEmojiClick(View view, int position); |
||||
|
} |
||||
|
} |
@ -0,0 +1,240 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<animation-list |
||||
|
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
|
android:oneshot="false" > |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f0" |
||||
|
android:duration="500" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f1" |
||||
|
android:duration="500" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f2" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f3" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f4" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f5" |
||||
|
android:duration="500" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f6" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f7" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f8" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f9" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f10" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f11" |
||||
|
android:duration="500" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f12" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f13" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f14" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f15" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f16" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f17" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f18" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f19" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f20" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f21" |
||||
|
android:duration="500" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f22" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f23" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f24" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f25" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f26" |
||||
|
android:duration="400" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f27" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f28" |
||||
|
android:duration="400" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f29" |
||||
|
android:duration="300" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f30" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f31" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f32" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f33" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f34" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f35" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f36" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f37" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f38" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f39" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f40" |
||||
|
android:duration="300" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f41" |
||||
|
android:duration="50" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f42" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f43" |
||||
|
android:duration="10" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f44" |
||||
|
android:duration="10" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f45" |
||||
|
android:duration="300" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f46" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f47" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f48" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f49" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f50" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f51" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f52" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f53" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f54" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f55" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f56" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f57" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f58" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f59" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f60" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f61" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f62" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f63" |
||||
|
android:duration="200" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f64" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f65" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f66" |
||||
|
android:duration="300" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f67" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f68" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f69" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f70" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f71" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f72" |
||||
|
android:duration="150" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f73" |
||||
|
android:duration="700" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f74" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f75" |
||||
|
android:duration="700" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f76" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_a_eatpaper_f77" |
||||
|
android:duration="1000" /> |
||||
|
|
||||
|
</animation-list> |
After Width: | Height: | Size: 636 B |
After Width: | Height: | Size: 603 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 630 B |
After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 630 B |
After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 630 B |
After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 629 B |
After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 629 B |
After Width: | Height: | Size: 617 B |
After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 629 B |
After Width: | Height: | Size: 633 B |
After Width: | Height: | Size: 570 B |
After Width: | Height: | Size: 614 B |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 641 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 603 B |
After Width: | Height: | Size: 631 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 631 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 631 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 631 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 631 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 617 B |
After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 620 B |
After Width: | Height: | Size: 565 B |
After Width: | Height: | Size: 555 B |
After Width: | Height: | Size: 622 B |
After Width: | Height: | Size: 604 B |
After Width: | Height: | Size: 573 B |
After Width: | Height: | Size: 605 B |
After Width: | Height: | Size: 536 B |
After Width: | Height: | Size: 517 B |
After Width: | Height: | Size: 614 B |
After Width: | Height: | Size: 527 B |
After Width: | Height: | Size: 516 B |
After Width: | Height: | Size: 526 B |
After Width: | Height: | Size: 517 B |
After Width: | Height: | Size: 517 B |
After Width: | Height: | Size: 465 B |
After Width: | Height: | Size: 466 B |
After Width: | Height: | Size: 534 B |
After Width: | Height: | Size: 521 B |
After Width: | Height: | Size: 525 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 521 B |
After Width: | Height: | Size: 536 B |
After Width: | Height: | Size: 521 B |
After Width: | Height: | Size: 525 B |
After Width: | Height: | Size: 521 B |
After Width: | Height: | Size: 522 B |
After Width: | Height: | Size: 524 B |
After Width: | Height: | Size: 514 B |
After Width: | Height: | Size: 520 B |
After Width: | Height: | Size: 527 B |
After Width: | Height: | Size: 614 B |
After Width: | Height: | Size: 523 B |
After Width: | Height: | Size: 522 B |
After Width: | Height: | Size: 521 B |
After Width: | Height: | Size: 525 B |
After Width: | Height: | Size: 513 B |
After Width: | Height: | Size: 525 B |
After Width: | Height: | Size: 513 B |
After Width: | Height: | Size: 525 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 614 B |
@ -0,0 +1,18 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<animation-list |
||||
|
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
|
android:oneshot="false" > |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry_f0" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry_f1" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry_f2" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry_f3" |
||||
|
android:duration="100" /> |
||||
|
|
||||
|
</animation-list> |
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<animation-list |
||||
|
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
|
android:oneshot="false" > |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry4_f0" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry4_f1" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry4_f2" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry4_f3" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry4_f4" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry4_f5" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry4_f6" |
||||
|
android:duration="100" /> |
||||
|
<item |
||||
|
android:drawable="@drawable/emoji_angry4_f7" |
||||
|
android:duration="100" /> |
||||
|
|
||||
|
</animation-list> |
After Width: | Height: | Size: 275 B |
After Width: | Height: | Size: 307 B |
After Width: | Height: | Size: 360 B |
After Width: | Height: | Size: 379 B |
After Width: | Height: | Size: 353 B |
After Width: | Height: | Size: 346 B |
After Width: | Height: | Size: 265 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 189 B |