Split Emoji categories fitting the pager
Bug: 10538430 Change-Id: Ic023ac0b9db8a1fe16c73ab5fd12dfcd7cbbe6a3main
parent
0f317a5603
commit
5dfbc8af24
|
@ -75,5 +75,9 @@
|
|||
<dimen name="gesture_floating_preview_vertical_padding">15dp</dimen>
|
||||
|
||||
<!-- Emoji keyboard -->
|
||||
<fraction name="emoji_keyboard_key_width">8.3333%p</fraction>
|
||||
<fraction name="emoji_keyboard_key_width">10%p</fraction>
|
||||
<fraction name="emoji_keyboard_row_height">50%p</fraction>
|
||||
<fraction name="emoji_keyboard_key_letter_size">60%p</fraction>
|
||||
<integer name="emoji_keyboard_max_key_count">20</integer>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -117,6 +117,9 @@
|
|||
|
||||
<!-- Emoji keyboard -->
|
||||
<fraction name="emoji_keyboard_key_width">14.2857%p</fraction>
|
||||
<fraction name="emoji_keyboard_row_height">33%p</fraction>
|
||||
<fraction name="emoji_keyboard_key_letter_size">90%p</fraction>
|
||||
<integer name="emoji_keyboard_max_key_count">21</integer>
|
||||
|
||||
<!-- Inset used in Accessibility mode to avoid accidental key presses when a finger slides off the screen. -->
|
||||
<dimen name="accessibility_edge_slop">8dp</dimen>
|
||||
|
@ -124,4 +127,5 @@
|
|||
<integer name="user_dictionary_max_word_length" translatable="false">48</integer>
|
||||
|
||||
<dimen name="language_on_spacebar_horizontal_margin">1dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
<Keyboard
|
||||
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
||||
latin:keyWidth="@fraction/emoji_keyboard_key_width"
|
||||
latin:keyLetterSize="90%p"
|
||||
latin:keyLetterSize="@fraction/emoji_keyboard_key_letter_size"
|
||||
latin:keyLabelSize="60%p"
|
||||
latin:rowHeight="@fraction/emoji_keyboard_row_height"
|
||||
>
|
||||
<GridRows
|
||||
latin:codesArray="@array/emoji_recents"
|
||||
|
|
|
@ -28,6 +28,7 @@ import android.support.v4.view.PagerAdapter;
|
|||
import android.support.v4.view.ViewPager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.SparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -38,9 +39,7 @@ import android.widget.TabHost;
|
|||
import android.widget.TabHost.OnTabChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.inputmethod.keyboard.internal.CodesArrayParser;
|
||||
import com.android.inputmethod.keyboard.internal.DynamicGridKeyboard;
|
||||
import com.android.inputmethod.keyboard.internal.KeyboardParams;
|
||||
import com.android.inputmethod.keyboard.internal.ScrollKeyboardView;
|
||||
import com.android.inputmethod.keyboard.internal.ScrollViewWithNotifier;
|
||||
import com.android.inputmethod.latin.Constants;
|
||||
|
@ -90,7 +89,17 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
private static final int CATEGORY_SYMBOLS = 5;
|
||||
private static final int CATEGORY_EMOTICONS = 6;
|
||||
|
||||
private static class CategoryProperties {
|
||||
public int mCategory;
|
||||
public int mPageCount;
|
||||
public CategoryProperties(final int category, final int pageCount) {
|
||||
mCategory = category;
|
||||
mPageCount = pageCount;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EmojiCategory {
|
||||
private static final int DEFAULT_PAGE_KEY_COUNT = 21;
|
||||
private static final int DEFAULT_MAX_ROW_SIZE = 3;
|
||||
private static final String[] sCategoryName = {
|
||||
"recents",
|
||||
|
@ -118,10 +127,12 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
KeyboardId.ELEMENT_EMOJI_CATEGORY4,
|
||||
KeyboardId.ELEMENT_EMOJI_CATEGORY5,
|
||||
KeyboardId.ELEMENT_EMOJI_CATEGORY6, };
|
||||
private Resources mRes;
|
||||
private final Resources mRes;
|
||||
private final int mMaxPageKeyCount;
|
||||
private final KeyboardLayoutSet mLayoutSet;
|
||||
private final HashMap<String, Integer> mCategoryNameToIdMap = CollectionUtils.newHashMap();
|
||||
private final ArrayList<Integer> mShownCategories = new ArrayList<Integer>();
|
||||
private final ArrayList<CategoryProperties> mShownCategories =
|
||||
CollectionUtils.newArrayList();
|
||||
private final ConcurrentHashMap<Long, DynamicGridKeyboard>
|
||||
mCategoryKeyboardMap = new ConcurrentHashMap<Long, DynamicGridKeyboard>();
|
||||
|
||||
|
@ -129,32 +140,42 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
|
||||
public EmojiCategory(final Resources res, final KeyboardLayoutSet layoutSet) {
|
||||
mRes = res;
|
||||
mMaxPageKeyCount = res.getInteger(R.integer.emoji_keyboard_max_key_count);
|
||||
mLayoutSet = layoutSet;
|
||||
for (int i = 0; i < sCategoryName.length; ++i) {
|
||||
mCategoryNameToIdMap.put(sCategoryName[i], i);
|
||||
}
|
||||
mShownCategories.add(CATEGORY_RECENTS);
|
||||
addShownCategory(CATEGORY_RECENTS);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
mShownCategories.add(CATEGORY_PEOPLE);
|
||||
mShownCategories.add(CATEGORY_OBJECTS);
|
||||
mShownCategories.add(CATEGORY_NATURE);
|
||||
mShownCategories.add(CATEGORY_PLACES);
|
||||
addShownCategory(CATEGORY_PEOPLE);
|
||||
addShownCategory(CATEGORY_OBJECTS);
|
||||
addShownCategory(CATEGORY_NATURE);
|
||||
addShownCategory(CATEGORY_PLACES);
|
||||
// TODO: Restore last saved category
|
||||
mCurrentCategory = CATEGORY_PEOPLE;
|
||||
} else {
|
||||
// TODO: Restore last saved category
|
||||
mCurrentCategory = CATEGORY_SYMBOLS;
|
||||
}
|
||||
mShownCategories.add(CATEGORY_SYMBOLS);
|
||||
mShownCategories.add(CATEGORY_EMOTICONS);
|
||||
addShownCategory(CATEGORY_SYMBOLS);
|
||||
addShownCategory(CATEGORY_EMOTICONS);
|
||||
}
|
||||
|
||||
public String getCategoryName(int category) {
|
||||
return sCategoryName[category];
|
||||
private void addShownCategory(int category) {
|
||||
// Load a keyboard of category
|
||||
getKeyboard(category, 0);
|
||||
final CategoryProperties properties =
|
||||
new CategoryProperties(category, getCategoryPageCount(category));
|
||||
mShownCategories.add(properties);
|
||||
}
|
||||
|
||||
public String getCategoryName(int category, int categoryPageId) {
|
||||
return sCategoryName[category] + "-" + categoryPageId;
|
||||
}
|
||||
|
||||
public int getCategoryId(String name) {
|
||||
return mCategoryNameToIdMap.get(name);
|
||||
final String[] strings = name.split("-");
|
||||
return mCategoryNameToIdMap.get(strings[0]);
|
||||
}
|
||||
|
||||
public int getCategoryIcon(int category) {
|
||||
|
@ -165,7 +186,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
return sCategoryLabel[category];
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getShownCategories() {
|
||||
public ArrayList<CategoryProperties> getShownCategories() {
|
||||
return mShownCategories;
|
||||
}
|
||||
|
||||
|
@ -184,7 +205,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
|
||||
public int getTabIdFromCategory(int category) {
|
||||
for (int i = 0; i < mShownCategories.size(); ++i) {
|
||||
if (mShownCategories.get(i) == category) {
|
||||
if (mShownCategories.get(i).mCategory == category) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -192,12 +213,53 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Returns the view pager's page position for the category
|
||||
public int getPageIdFromCategory(int category) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < mShownCategories.size(); ++i) {
|
||||
final CategoryProperties props = mShownCategories.get(i);
|
||||
if (props.mCategory == category) {
|
||||
return sum;
|
||||
}
|
||||
sum += props.mPageCount;
|
||||
}
|
||||
Log.w(TAG, "category not found: " + category);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getRecentTabId() {
|
||||
return getTabIdFromCategory(CATEGORY_RECENTS);
|
||||
}
|
||||
|
||||
public int getCategoryFromTabId(int tabId) {
|
||||
return mShownCategories.get(tabId);
|
||||
private int getCategoryPageCount(int category) {
|
||||
final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[category]);
|
||||
return (keyboard.getKeys().length - 1) / mMaxPageKeyCount + 1;
|
||||
}
|
||||
|
||||
// Returns a pair of the category id and the category page id from the view pager's page
|
||||
// position. The category page id is numbered in each category. And the view page position
|
||||
// is the position of the current shown page in the view pager which contains all pages of
|
||||
// all categories.
|
||||
public Pair<Integer, Integer> getCategoryIdAndPageIdFromPagePosition(int position) {
|
||||
int sum = 0;
|
||||
for (CategoryProperties properties : mShownCategories) {
|
||||
final int temp = sum;
|
||||
sum += properties.mPageCount;
|
||||
if (sum > position) {
|
||||
return new Pair<Integer, Integer>(properties.mCategory, position - temp);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns a keyboard from the view pager's page position.
|
||||
public DynamicGridKeyboard getKeyboardFromPagePosition(int position) {
|
||||
final Pair<Integer, Integer> categoryAndId =
|
||||
getCategoryIdAndPageIdFromPagePosition(position);
|
||||
if (categoryAndId != null) {
|
||||
return getKeyboard(categoryAndId.first, categoryAndId.second);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public DynamicGridKeyboard getKeyboard(int category, int id) {
|
||||
|
@ -206,25 +268,29 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
final DynamicGridKeyboard kbd;
|
||||
if (!mCategoryKeyboardMap.containsKey(key)) {
|
||||
if (category != CATEGORY_RECENTS) {
|
||||
kbd = new DynamicGridKeyboard(
|
||||
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
||||
DEFAULT_MAX_ROW_SIZE);
|
||||
final Keyboard keyboard =
|
||||
mLayoutSet.getKeyboard(sCategoryElementId[category]);
|
||||
// TODO: Calculate maxPageCount dynamically
|
||||
final Key[][] sortedKeys = sortKeys(keyboard.getKeys(), 21);
|
||||
for (Key emojiKey : sortedKeys[0]) {
|
||||
if (emojiKey == null) {
|
||||
break;
|
||||
final Key[][] sortedKeys = sortKeys(keyboard.getKeys(), mMaxPageKeyCount);
|
||||
for (int i = 0; i < sortedKeys.length; ++i) {
|
||||
final DynamicGridKeyboard tempKbd = new DynamicGridKeyboard(
|
||||
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
||||
mMaxPageKeyCount);
|
||||
for (Key emojiKey : sortedKeys[i]) {
|
||||
if (emojiKey == null) {
|
||||
break;
|
||||
}
|
||||
tempKbd.addKeyLast(emojiKey);
|
||||
}
|
||||
kbd.addKeyLast(emojiKey);
|
||||
mCategoryKeyboardMap.put((((long) category) << 32) | i, tempKbd);
|
||||
}
|
||||
kbd = mCategoryKeyboardMap.get(key);
|
||||
} else {
|
||||
kbd = new DynamicGridKeyboard(
|
||||
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
||||
DEFAULT_MAX_ROW_SIZE);
|
||||
mMaxPageKeyCount);
|
||||
mCategoryKeyboardMap.put(key, kbd);
|
||||
}
|
||||
mCategoryKeyboardMap.put(key, kbd);
|
||||
} else {
|
||||
kbd = mCategoryKeyboardMap.get(key);
|
||||
}
|
||||
|
@ -232,6 +298,14 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
}
|
||||
}
|
||||
|
||||
public int getTotalPageCountOfAllCategories() {
|
||||
int sum = 0;
|
||||
for (CategoryProperties properties : mShownCategories) {
|
||||
sum += properties.mPageCount;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
private Key[][] sortKeys(Key[] inKeys, int maxPageCount) {
|
||||
Key[] keys = Arrays.copyOf(inKeys, inKeys.length);
|
||||
Arrays.sort(keys, 0, keys.length, new Comparator<Key>() {
|
||||
|
@ -287,10 +361,10 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
|
||||
context, null /* editorInfo */);
|
||||
final Resources res = context.getResources();
|
||||
final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res);
|
||||
builder.setSubtype(SubtypeSwitcher.getInstance().getEmojiSubtype());
|
||||
builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res),
|
||||
(int)ResourceUtils.getDefaultKeyboardHeight(res)
|
||||
+ res.getDimensionPixelSize(R.dimen.suggestions_strip_height));
|
||||
emojiLp.mEmojiKeyboardHeight);
|
||||
builder.setOptions(false, false, false /* lanuageSwitchKeyEnabled */);
|
||||
mLayoutSet = builder.build();
|
||||
mEmojiCategory = new EmojiCategory(context.getResources(), builder.build());
|
||||
|
@ -311,7 +385,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
}
|
||||
|
||||
private void addTab(final TabHost host, final int category) {
|
||||
final String tabId = mEmojiCategory.getCategoryName(category);
|
||||
final String tabId = mEmojiCategory.getCategoryName(category, 0 /* categoryPageId */);
|
||||
final TabHost.TabSpec tspec = host.newTabSpec(tabId);
|
||||
tspec.setContent(R.id.emoji_keyboard_dummy);
|
||||
if (mEmojiCategory.getCategoryIcon(category) != 0) {
|
||||
|
@ -334,8 +408,8 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
protected void onFinishInflate() {
|
||||
mTabHost = (TabHost)findViewById(R.id.emoji_category_tabhost);
|
||||
mTabHost.setup();
|
||||
for (final int i : mEmojiCategory.getShownCategories()) {
|
||||
addTab(mTabHost, i);
|
||||
for (final CategoryProperties properties : mEmojiCategory.getShownCategories()) {
|
||||
addTab(mTabHost, properties.mCategory);
|
||||
}
|
||||
mTabHost.setOnTabChangedListener(this);
|
||||
mTabHost.getTabWidget().setStripEnabled(true);
|
||||
|
@ -384,7 +458,8 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
|
||||
@Override
|
||||
public void onPageSelected(final int position) {
|
||||
setCurrentCategory(mEmojiCategory.getCategoryFromTabId(position), false /* force */);
|
||||
setCurrentCategory(mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position).first,
|
||||
false /* force */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -439,8 +514,10 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
|
||||
mEmojiCategory.setCurrentCategory(category);
|
||||
final int newTabId = mEmojiCategory.getTabIdFromCategory(category);
|
||||
if (force || mEmojiPager.getCurrentItem() != newTabId) {
|
||||
mEmojiPager.setCurrentItem(newTabId, true /* smoothScroll */);
|
||||
final int newCategoryPageId = mEmojiCategory.getPageIdFromCategory(category);
|
||||
if (force || mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(
|
||||
mEmojiPager.getCurrentItem()).first != category) {
|
||||
mEmojiPager.setCurrentItem(newCategoryPageId, true /* smoothScroll */);
|
||||
}
|
||||
if (force || mTabHost.getCurrentTab() != newTabId) {
|
||||
mTabHost.setCurrentTab(newTabId);
|
||||
|
@ -480,7 +557,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mEmojiCategory.getShownCategories().size();
|
||||
return mEmojiCategory.getTotalPageCountOfAllCategories();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -499,7 +576,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
|
|||
@Override
|
||||
public Object instantiateItem(final ViewGroup container, final int position) {
|
||||
final Keyboard keyboard =
|
||||
mEmojiCategory.getKeyboard(mEmojiCategory.getCategoryFromTabId(position), 0);
|
||||
mEmojiCategory.getKeyboardFromPagePosition(position);
|
||||
final LayoutInflater inflater = LayoutInflater.from(container.getContext());
|
||||
final View view = inflater.inflate(
|
||||
R.layout.emoji_keyboard_page, container, false /* attachToRoot */);
|
||||
|
|
|
@ -27,6 +27,8 @@ import android.widget.LinearLayout;
|
|||
public class EmojiLayoutParams {
|
||||
private static final int DEFAULT_KEYBOARD_ROWS = 4;
|
||||
|
||||
public final int mEmojiPagerHeight;
|
||||
private final int mEmojiPagerBottomMargin;
|
||||
public final int mEmojiKeyboardHeight;
|
||||
public final int mEmojiActionBarHeight;
|
||||
public final int mKeyVerticalGap;
|
||||
|
@ -49,13 +51,15 @@ public class EmojiLayoutParams {
|
|||
+ mKeyVerticalGap;
|
||||
mEmojiActionBarHeight = ((int) baseheight) / DEFAULT_KEYBOARD_ROWS
|
||||
- (mKeyVerticalGap - mBottomPadding) / 2;
|
||||
mEmojiKeyboardHeight = defaultKeyboardHeight - mEmojiActionBarHeight;
|
||||
mEmojiPagerHeight = defaultKeyboardHeight - mEmojiActionBarHeight;
|
||||
mEmojiPagerBottomMargin = mKeyVerticalGap / 2;
|
||||
mEmojiKeyboardHeight = mEmojiPagerHeight - mEmojiPagerBottomMargin - 1;
|
||||
}
|
||||
|
||||
public void setPagerProps(ViewPager vp) {
|
||||
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) vp.getLayoutParams();
|
||||
lp.height = mEmojiKeyboardHeight - mKeyVerticalGap / 2;
|
||||
lp.bottomMargin = mKeyVerticalGap / 2;
|
||||
lp.height = mEmojiPagerHeight - mEmojiPagerBottomMargin;
|
||||
lp.bottomMargin = mEmojiPagerBottomMargin;
|
||||
vp.setLayoutParams(lp);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public class DynamicGridKeyboard extends Keyboard {
|
|||
|
||||
private Key[] mCachedGridKeys;
|
||||
|
||||
public DynamicGridKeyboard(final Keyboard templateKeyboard, final int maxRows) {
|
||||
public DynamicGridKeyboard(final Keyboard templateKeyboard, final int maxKeyCount) {
|
||||
super(templateKeyboard);
|
||||
final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0);
|
||||
final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1);
|
||||
|
@ -49,7 +49,7 @@ public class DynamicGridKeyboard extends Keyboard {
|
|||
mHorizontalStep = Math.abs(key1.getX() - key0.getX());
|
||||
mVerticalStep = key0.getHeight() + mVerticalGap;
|
||||
mColumnsNum = mBaseWidth / mHorizontalStep;
|
||||
mMaxKeyCount = mColumnsNum * maxRows;
|
||||
mMaxKeyCount = maxKeyCount;
|
||||
}
|
||||
|
||||
private Key getTemplateKey(final int code) {
|
||||
|
|
Loading…
Reference in New Issue