Skip to content

Commit

Permalink
Refactor the VariantEmojiManager (vanniktech#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
rubengees authored and vanniktech committed Jul 1, 2017
1 parent a56b500 commit e15e896
Show file tree
Hide file tree
Showing 20 changed files with 413 additions and 403 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
import android.view.ViewGroup;
import android.widget.ImageView;
import com.vanniktech.emoji.EmojiEditText;
import com.vanniktech.emoji.EmojiImageView;
import com.vanniktech.emoji.EmojiManager;
import com.vanniktech.emoji.EmojiPopup;
import com.vanniktech.emoji.emoji.Emoji;
import com.vanniktech.emoji.google.GoogleEmojiProvider;
import com.vanniktech.emoji.ios.IosEmojiProvider;
import com.vanniktech.emoji.listeners.OnEmojiBackspaceClickListener;
import com.vanniktech.emoji.listeners.OnEmojiClickedListener;
import com.vanniktech.emoji.listeners.OnEmojiClickListener;
import com.vanniktech.emoji.listeners.OnEmojiPopupDismissListener;
import com.vanniktech.emoji.listeners.OnEmojiPopupShownListener;
import com.vanniktech.emoji.listeners.OnSoftKeyboardCloseListener;
Expand Down Expand Up @@ -128,12 +129,12 @@ public class MainActivity extends AppCompatActivity {
private void setUpEmojiPopup() {
emojiPopup = EmojiPopup.Builder.fromRootView(rootView)
.setOnEmojiBackspaceClickListener(new OnEmojiBackspaceClickListener() {
@Override public void onEmojiBackspaceClicked(final View v) {
@Override public void onEmojiBackspaceClick(final View v) {
Log.d(TAG, "Clicked on Backspace");
}
})
.setOnEmojiClickedListener(new OnEmojiClickedListener() {
@Override public void onEmojiClicked(@NonNull final Emoji emoji) {
.setOnEmojiClickListener(new OnEmojiClickListener() {
@Override public void onEmojiClick(@NonNull final EmojiImageView imageView, @NonNull final Emoji emoji) {
Log.d(TAG, "Clicked on emoji");
}
})
Expand Down
9 changes: 5 additions & 4 deletions app/src/main/java/com/vanniktech/emoji/sample/MainDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
import android.view.ViewGroup;
import android.widget.ImageView;
import com.vanniktech.emoji.EmojiEditText;
import com.vanniktech.emoji.EmojiImageView;
import com.vanniktech.emoji.EmojiPopup;
import com.vanniktech.emoji.emoji.Emoji;
import com.vanniktech.emoji.listeners.OnEmojiBackspaceClickListener;
import com.vanniktech.emoji.listeners.OnEmojiClickedListener;
import com.vanniktech.emoji.listeners.OnEmojiClickListener;
import com.vanniktech.emoji.listeners.OnEmojiPopupDismissListener;
import com.vanniktech.emoji.listeners.OnEmojiPopupShownListener;
import com.vanniktech.emoji.listeners.OnSoftKeyboardCloseListener;
Expand Down Expand Up @@ -102,12 +103,12 @@ private View buildView() {
private void setUpEmojiPopup() {
emojiPopup = EmojiPopup.Builder.fromRootView(rootView)
.setOnEmojiBackspaceClickListener(new OnEmojiBackspaceClickListener() {
@Override public void onEmojiBackspaceClicked(final View v) {
@Override public void onEmojiBackspaceClick(final View v) {
Log.d(TAG, "Clicked on Backspace");
}
})
.setOnEmojiClickedListener(new OnEmojiClickedListener() {
@Override public void onEmojiClicked(@NonNull final Emoji emoji) {
.setOnEmojiClickListener(new OnEmojiClickListener() {
@Override public void onEmojiClick(@NonNull final EmojiImageView imageView, @NonNull final Emoji emoji) {
Log.d(TAG, "Clicked on emoji");
}
})
Expand Down
21 changes: 14 additions & 7 deletions emoji/src/main/java/com/vanniktech/emoji/EmojiArrayAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import com.vanniktech.emoji.emoji.Emoji;
import com.vanniktech.emoji.listeners.OnEmojiClickedListener;
import com.vanniktech.emoji.listeners.OnEmojiClickListener;
import com.vanniktech.emoji.listeners.OnEmojiLongClickListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import static com.vanniktech.emoji.Utils.checkNotNull;

final class EmojiArrayAdapter extends ArrayAdapter<Emoji> {
@Nullable private final OnEmojiClickedListener listener;
@Nullable private final OnEmojiLongClickedListener longListener;
@Nullable private final VariantEmoji variantManager;

EmojiArrayAdapter(@NonNull final Context context, @NonNull final Emoji[] emojis,
@Nullable final OnEmojiClickedListener listener, @Nullable final OnEmojiLongClickedListener longListener) {
@Nullable private final OnEmojiClickListener listener;
@Nullable private final OnEmojiLongClickListener longListener;

EmojiArrayAdapter(@NonNull final Context context, @NonNull final Emoji[] emojis, @Nullable final VariantEmoji variantManager,
@Nullable final OnEmojiClickListener listener, @Nullable final OnEmojiLongClickListener longListener) {
super(context, 0, new ArrayList<>(Arrays.asList(emojis)));

this.variantManager = variantManager;
this.listener = listener;
this.longListener = longListener;
}
Expand All @@ -34,11 +38,14 @@ final class EmojiArrayAdapter extends ArrayAdapter<Emoji> {

if (image == null) {
image = (EmojiImageView) LayoutInflater.from(context).inflate(R.layout.emoji_item, parent, false);

image.setOnEmojiClickListener(listener);
image.setOnEmojiLongClickListener(longListener);
}

final Emoji emoji = checkNotNull(getItem(position), "emoji == null");
final Emoji recentEmoji = RecentEmojiVariantManager.getInstance().getMostRecentVariant(emoji, context);
image.setEmoji(recentEmoji, listener, longListener);
final Emoji variantToUse = variantManager == null ? emoji : variantManager.getVariant(emoji);
image.setEmoji(variantToUse);

return image;
}
Expand Down
13 changes: 8 additions & 5 deletions emoji/src/main/java/com/vanniktech/emoji/EmojiGridView.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import android.support.annotation.Nullable;
import android.widget.GridView;
import com.vanniktech.emoji.emoji.EmojiCategory;
import com.vanniktech.emoji.listeners.OnEmojiClickedListener;
import com.vanniktech.emoji.listeners.OnEmojiClickListener;
import com.vanniktech.emoji.listeners.OnEmojiLongClickListener;

class EmojiGridView extends GridView {
protected EmojiArrayAdapter emojiArrayAdapter;
Expand All @@ -27,10 +28,12 @@ class EmojiGridView extends GridView {
setVerticalScrollBarEnabled(false);
}

public EmojiGridView init(@Nullable final OnEmojiClickedListener onEmojiClickedListener,
@Nullable final OnEmojiLongClickedListener onEmojiLongClickedListener,
@NonNull final EmojiCategory category) {
emojiArrayAdapter = new EmojiArrayAdapter(getContext(), category.getEmojis(), onEmojiClickedListener, onEmojiLongClickedListener);
public EmojiGridView init(@Nullable final OnEmojiClickListener onEmojiClickListener,
@Nullable final OnEmojiLongClickListener onEmojiLongClickListener,
@NonNull final EmojiCategory category, @NonNull final VariantEmoji variantManager) {
emojiArrayAdapter = new EmojiArrayAdapter(getContext(), category.getEmojis(), variantManager,
onEmojiClickListener, onEmojiLongClickListener);

setAdapter(emojiArrayAdapter);

return this;
Expand Down
120 changes: 59 additions & 61 deletions emoji/src/main/java/com/vanniktech/emoji/EmojiImageView.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,38 @@
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.view.View;
import com.vanniktech.emoji.emoji.Emoji;
import com.vanniktech.emoji.listeners.OnEmojiClickedListener;
import com.vanniktech.emoji.listeners.OnEmojiClickListener;
import com.vanniktech.emoji.listeners.OnEmojiLongClickListener;

import static android.support.annotation.RestrictTo.Scope.LIBRARY;

@RestrictTo(LIBRARY) public final class EmojiImageView extends AppCompatImageView {
private static final int VARIANT_INDICATOR_PART_AMOUNT = 6;
private static final int VARIANT_INDICATOR_PART = 5;

Emoji currentEmoji;

OnEmojiClickListener clickListener;
OnEmojiLongClickListener longClickListener;

private final Paint variantIndicatorPaint = new Paint();
private final Path variantIndicatorPath = new Path();

private final Point variantIndicatorTop = new Point();
private final Point variantIndicatorBottomRight = new Point();
private final Point variantIndicatorBottomLeft = new Point();

private boolean hasVariants;
private ImageLoadingTask imageLoadingTask;

private RecentEmojiVariantManager.Disposable disposable;
private boolean hasVariants;

public EmojiImageView(final Context context, final AttributeSet attrs) {
super(context, attrs);
Expand Down Expand Up @@ -72,78 +79,69 @@ public EmojiImageView(final Context context, final AttributeSet attrs) {
}
}

public void setEmoji(final Emoji emoji, @Nullable final OnEmojiClickedListener clickListener, @Nullable final OnEmojiLongClickedListener longClickListener) {
setImageDrawable(null);

setOnClickListener(new EmojiOnClickListener(clickListener, emoji));

final Emoji baseEmoji = emoji.getBase();

hasVariants = baseEmoji.hasVariants();
setOnLongClickListener(hasVariants ? new EmojiOnLongClickListener(longClickListener, emoji) : null);

ImageLoadingTask task = (ImageLoadingTask) getTag();

if (task != null) {
task.cancel(true);
}

task = new ImageLoadingTask(this);
setTag(task);
task.execute(emoji.getResource());

disposable = RecentEmojiVariantManager.getInstance()
.addListener(baseEmoji, new RecentEmojiVariantManager.EmojiVariantListener() {
@Override public void onChanged(final Emoji newEmoji) {
setImageResource(newEmoji.getResource()); // We don't need to load it in an async manner since it's only one Image and we know that for a fact.

setOnClickListener(new EmojiOnClickListener(clickListener, emoji));
}
});
}

@Override protected void onDetachedFromWindow() {
super.onDetachedFromWindow();

if (disposable != null) {
disposable.dispose();
disposable = null; // Force GC.
if (imageLoadingTask != null) {
imageLoadingTask.cancel(true);
imageLoadingTask = null;
}
}

static class EmojiOnClickListener implements OnClickListener {
@Nullable private final OnEmojiClickedListener clickListener;
private final Emoji emoji;
void setEmoji(@NonNull final Emoji emoji) {
if (!emoji.equals(currentEmoji)) {
setImageDrawable(null);

EmojiOnClickListener(@Nullable final OnEmojiClickedListener clickListener, final Emoji emoji) {
this.clickListener = clickListener;
this.emoji = emoji;
}
currentEmoji = emoji;
hasVariants = emoji.getBase().hasVariants();

@Override public void onClick(final View v) {
if (clickListener != null) {
clickListener.onEmojiClicked(emoji);
if (imageLoadingTask != null) {
imageLoadingTask.cancel(true);
}
}
}

static class EmojiOnLongClickListener implements OnLongClickListener {
@Nullable private final OnEmojiLongClickedListener longClickListener;
private final Emoji emoji;
setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View view) {
if (clickListener != null) {
clickListener.onEmojiClick(EmojiImageView.this, currentEmoji);
}
}
});

EmojiOnLongClickListener(final OnEmojiLongClickedListener longClickListener, final Emoji emoji) {
this.longClickListener = longClickListener;
this.emoji = emoji;
}
setOnLongClickListener(hasVariants ? new OnLongClickListener() {
@Override
public boolean onLongClick(final View view) {
longClickListener.onEmojiLongClick(EmojiImageView.this, currentEmoji);

@Override public boolean onLongClick(final View v) {
if (longClickListener != null) {
longClickListener.onEmojiLongClicked(v, emoji);
return true;
}
} : null);

return true;
}
imageLoadingTask = new ImageLoadingTask(this);
imageLoadingTask.execute(emoji.getResource());
}
}

return false;
/**
* Updates the emoji image directly. This should be called only for updating the variant
* displayed (of the same base emoji), since it does not run asynchronously and does not update
* the internal listeners.
*
* @param emoji The new emoji variant to show.
*/
void updateEmoji(@NonNull final Emoji emoji) {
if (!emoji.equals(currentEmoji)) {
currentEmoji = emoji;

setImageResource(emoji.getResource());
}
}

void setOnEmojiClickListener(@Nullable final OnEmojiClickListener listener) {
this.clickListener = listener;
}

void setOnEmojiLongClickListener(@Nullable final OnEmojiLongClickListener listener) {
this.longClickListener = listener;
}
}
18 changes: 11 additions & 7 deletions emoji/src/main/java/com/vanniktech/emoji/EmojiPagerAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,26 @@
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import com.vanniktech.emoji.listeners.OnEmojiClickedListener;
import com.vanniktech.emoji.listeners.OnEmojiClickListener;
import com.vanniktech.emoji.listeners.OnEmojiLongClickListener;

final class EmojiPagerAdapter extends PagerAdapter {
private static final int RECENT_POSITION = 0;

private final OnEmojiClickedListener listener;
private final OnEmojiLongClickedListener longListener;
private final OnEmojiClickListener listener;
private final OnEmojiLongClickListener longListener;
private final RecentEmoji recentEmoji;
private final VariantEmoji variantManager;

private RecentEmojiGridView recentEmojiGridView;

EmojiPagerAdapter(final OnEmojiClickedListener listener,
final OnEmojiLongClickedListener longListener,
final RecentEmoji recentEmoji) {
EmojiPagerAdapter(final OnEmojiClickListener listener,
final OnEmojiLongClickListener longListener,
final RecentEmoji recentEmoji, final VariantEmoji variantManager) {
this.listener = listener;
this.longListener = longListener;
this.recentEmoji = recentEmoji;
this.variantManager = variantManager;
this.recentEmojiGridView = null;
}

Expand All @@ -34,7 +37,8 @@ final class EmojiPagerAdapter extends PagerAdapter {
newView = new RecentEmojiGridView(pager.getContext()).init(listener, longListener, recentEmoji);
recentEmojiGridView = (RecentEmojiGridView) newView;
} else {
newView = new EmojiGridView(pager.getContext()).init(listener, longListener, EmojiManager.getInstance().getCategories()[position - 1]);
newView = new EmojiGridView(pager.getContext()).init(listener, longListener,
EmojiManager.getInstance().getCategories()[position - 1], variantManager);
}

pager.addView(newView);
Expand Down
Loading

0 comments on commit e15e896

Please sign in to comment.