package com.lqr.emoji;
|
|
import android.content.Context;
|
import android.content.res.Resources;
|
import android.graphics.Bitmap;
|
import android.graphics.BitmapFactory;
|
import android.graphics.Rect;
|
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.Drawable;
|
import android.text.TextUtils;
|
import android.util.DisplayMetrics;
|
import android.util.LruCache;
|
import android.util.Xml;
|
|
import org.xml.sax.Attributes;
|
import org.xml.sax.SAXException;
|
import org.xml.sax.helpers.DefaultHandler;
|
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.regex.Pattern;
|
|
/**
|
* CSDN_LQR
|
* emoji表情管理器
|
*/
|
public class EmojiManager {
|
|
private static final String EMOT_DIR = "emoji/";
|
|
private static final int CACHE_MAX_SIZE = 1024;
|
private static Pattern mPattern;
|
|
private static final List<Entry> mDefaultEntries = new ArrayList<>();
|
private static final Map<Integer, Entry> mText2Entry = new HashMap<>();
|
private static LruCache<String, Bitmap> mDrawableCache;
|
|
static {
|
Context context = LQREmotionKit.getContext();
|
|
load(context, EMOT_DIR + "emoji.xml");
|
|
mPattern = makePattern();
|
|
mDrawableCache = new LruCache<String, Bitmap>(CACHE_MAX_SIZE) {
|
@Override
|
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
|
if (oldValue != newValue)
|
oldValue.recycle();
|
}
|
};
|
}
|
|
public static final int getDisplayCount() {
|
return mDefaultEntries.size();
|
}
|
|
public static final Drawable getDisplayDrawable(Context context, int index) {
|
String text = (index >= 0 && index < mDefaultEntries.size() ? mDefaultEntries.get(index).text : null);
|
return TextUtils.isEmpty(text) ? null : getDrawable(context, Integer.decode(text));
|
}
|
|
public static final String getDisplayText(int index) {
|
return index >= 0 && index < mDefaultEntries.size() ? mDefaultEntries.get(index).text : null;
|
}
|
|
public static final Drawable getDrawable(Context context, int code) {
|
Entry entry = mText2Entry.get(code);
|
if (entry == null || TextUtils.isEmpty(entry.text)) {
|
return null;
|
}
|
|
Bitmap cache = mDrawableCache.get(entry.assetPath);
|
if (cache == null) {
|
cache = loadAssetBitmap(context, entry.assetPath);
|
}
|
return new BitmapDrawable(context.getResources(), cache);
|
}
|
|
private static Bitmap loadAssetBitmap(Context context, String assetPath) {
|
InputStream is = null;
|
try {
|
Resources resources = context.getResources();
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
options.inDensity = DisplayMetrics.DENSITY_HIGH;
|
options.inScreenDensity = resources.getDisplayMetrics().densityDpi;
|
options.inTargetDensity = resources.getDisplayMetrics().densityDpi;
|
is = context.getAssets().open(assetPath);
|
Bitmap bitmap = BitmapFactory.decodeStream(is, new Rect(), options);
|
if (bitmap != null) {
|
mDrawableCache.put(assetPath, bitmap);
|
}
|
return bitmap;
|
} catch (IOException e) {
|
e.printStackTrace();
|
} finally {
|
if (is != null) {
|
try {
|
is.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return null;
|
}
|
|
public static final Pattern getPattern() {
|
return mPattern;
|
}
|
|
public static boolean contains(int code) {
|
return mText2Entry.containsKey(code);
|
}
|
|
private static Pattern makePattern() {
|
return Pattern.compile(patternOfDefault());
|
}
|
|
private static String patternOfDefault() {
|
return "\\[[^\\[]{1,10}\\]";
|
}
|
|
private static final void load(Context context, String xmlPath) {
|
new EntryLoader().load(context, xmlPath);
|
|
//补充最后一页少的表情
|
int tmp = mDefaultEntries.size() % EmotionLayout.EMOJI_PER_PAGE;
|
if (tmp != 0) {
|
int tmp2 = EmotionLayout.EMOJI_PER_PAGE - (mDefaultEntries.size() - (mDefaultEntries.size() / EmotionLayout.EMOJI_PER_PAGE) * EmotionLayout.EMOJI_PER_PAGE);
|
for (int i = 0; i < tmp2; i++) {
|
mDefaultEntries.add(new Entry("", ""));
|
}
|
}
|
}
|
|
private static class Entry {
|
String text;
|
String assetPath;
|
|
public Entry(String text, String assetPath) {
|
this.text = text;
|
this.assetPath = assetPath;
|
}
|
}
|
|
private static class EntryLoader extends DefaultHandler {
|
private String catalog = "";
|
|
void load(Context context, String assetPath) {
|
InputStream is = null;
|
try {
|
is = context.getAssets().open(assetPath);
|
Xml.parse(is, Xml.Encoding.UTF_8, this);
|
} catch (IOException e) {
|
e.printStackTrace();
|
} catch (SAXException e) {
|
e.printStackTrace();
|
} finally {
|
if (is != null) {
|
try {
|
is.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|
|
@Override
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
if (localName.equals("Catalog")) {
|
catalog = attributes.getValue(uri, "Title");
|
} else if (localName.equals("Emoticon")) {
|
String tag = attributes.getValue(uri, "Tag");
|
String fileName = attributes.getValue(uri, "File");
|
Entry entry = new Entry(tag, EMOT_DIR + catalog + "/" + fileName);
|
|
mText2Entry.put(Integer.decode(tag), entry);
|
if (catalog.equals("default")) {
|
mDefaultEntries.add(entry);
|
}
|
}
|
}
|
}
|
|
}
|