編輯:關於Android編程
其實就是這個常見的功能
這個功能涉及到很多類, 我一個一個分析
/**
* 底部帶emotion面板的文字和表情的評論功能的Fragment
**/
public class KeyboardFragment extends BaseTabNavFragment {
@Bind(R.id.et_input)
EditText mInput; //輸入框
@Bind(R.id.emotion_layout)
LinearLayout mEmoLayout; //表情的布局
@Bind(R.id.iv_emotion)
ImageView mIvEmotion; //發布評論的圖片
// 回復的對象
private Comment mReplyCmm;
//委托類對象,它管理著鍵盤, emotion按鈕, 輸入框, emotion面板之間的相互操作
private KeyboardActionDelegation mDelegatioin;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//加載底部emotion回復布局
return inflater.inflate(R.layout.fragment_keyboard, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
//這個委托類對象很重要
mDelegatioin = new KeyboardActionDelegation(mContext, mInput, mIvEmotion, mEmoLayout);
//初始化訂閱者
initSubscribers();
//設置ViewPager第一頁選中
mViewPager.setCurrentItem(0);
}
/**
* 注冊事件訂閱者
*/
private void initSubscribers() {
// register a listener to receive a event that mean user selected a emotion
// 注冊一個監聽器接收用戶選擇了一個emotion表情的事件
RxBus.with(this)
.setEvent(Events.EventEnum.DELIVER_SELECT_EMOTION) //設置過濾接收選擇一個emotion表情事件
.setEndEvent(FragmentEvent.DESTROY) //直到Fragment destroy為止
.onNext((events -> {
EmotionRules emotion = events.getMessage();
mDelegatioin.onEmotionItemSelected(emotion); //設置所選的emotion
})).create();
// 接受返回事件,如果顯示表情面板,隱藏!如果顯示軟鍵盤,隱藏!如果顯示回復某某某,隱藏!
RxBus.with(this)
.setEvent(Events.EventEnum.DELIVER_GO_BACK) //接收返回事件
.setEndEvent(FragmentEvent.DESTROY) //直到Fragment destroy為止
.onNext((events -> {
if (mReplyCmm != null) { //如果回復評論不為空,重置回復評論對象
mInput.setHint(getResources().getString(R.string.please_say_something));
mReplyCmm = null;
return;
}
if (!mDelegatioin.onTurnBack())//如果點擊了返回按鈕
return;
RxBus.getInstance().send(Events.EventEnum.WE_HIDE_ALL, null); //發送一個隱藏全部的事件
})).create();
RxBus.with(this)
.setEvent(Events.EventEnum.DELIVER_REPLY_SOMEONE) //接收一個回復某人的事件
.setEndEvent(FragmentEvent.DESTROY) //直到Fragment destroy為止
.onNext((events -> {
mReplyCmm = events.getMessage(); //獲得評論對象
mInput.setHint("回復 @" + mReplyCmm.getAuthor()); //設置hint為@某人
})).create();
RxBus.with(this)
.setEvent(Events.EventEnum.DELIVER_CLEAR_IMPUT) //接收一個清空輸入框事件
.setEndEvent(FragmentEvent.DESTROY)//直到Fragment destroy為止
.onNext((events -> {
mInput.setHint(getResources().getString(R.string.please_say_something)); //重置輸入框
mInput.setText(null);
})).create();
}
/**
* 設置Tab item的View
*/
@Override
public View setupTabItemView(String title) {
//設置emoji笑臉圖標的布局屬性
ImageView view = new ImageView(mContext);
view.setImageResource(R.mipmap.icon_emotion_color);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
0, ViewGroup.LayoutParams.MATCH_PARENT
);
params.weight = 1;
view.setLayoutParams(params);
return view;
}
/**
* 設置tab,調用的是本類中的addTab()方法
*/
@Override
public void onSetupTabs() {
addTab(getResources().getString(R.string.emotion_qq), EmotionPanelFragment.class);
}
/**
* 總在前面添加元素,跟默認的基類做法相悖,所以我們復寫它
*/
@Override
public void addTab(String title, Class fragment) {
mTabs.add(0, new ViewPageInfo(title, Fragment.instantiate(getActivity(), fragment.getName())));
View view = setupTabItemView(title); //創建Tab item的View
mNavLayout.addView(view, 0); //每次都添加到前面
mTabs.get(0).view = view;
}
/**
* 刪除表情或字符
*/
@OnClick(R.id.iv_backspace)
public void removeEmotion() {
InputHelper.backspace(mInput); //退格
}
/**
* 發送信息
*/
@OnClick(R.id.iv_send)
public void sendComment() {
// 如果沒有輸入評論
if (Utilities.isEmpty(mInput.getText().toString())) {
Toast.makeText(mContext, "別鬧,寫點東西再發╭∩╮(︶︿︶)╭∩╮", Toast.LENGTH_SHORT).show();
return;
}
// 判斷是否登錄
if (AppManager.LOCAL_LOGINED_USER == null) {
UIManager.jump2login(mContext); //調到登錄
return;
}
// 封裝實體, 發送消息給相應的presenter
Comment comment = new Comment();
if (mReplyCmm == null) {
comment.setId(-1L);
} else {
comment.setId(mReplyCmm.getId());
comment.setAuthorId(mReplyCmm.getAuthorId());
}
comment.setContent(mInput.getText().toString());
//創建評論的事件
Events events = Events.just(comment);
events.what = Events.EventEnum.DELIVER_SEND_COMMENT; //發送評論
RxBus.getInstance().send(events); //發送評論的事件
}
}
這個類主要是創建了底部評論功能的布局(依靠強大的父類BaseTabNavFragment,只要重寫setupItemView(),onSetupTabs()和addTab()即可), 使用RxBus注冊了一系列的評論相關是事件接受者, 點擊評論按鈕時將評論內容封裝成對象使用RxBus發送出去.
這個類精彩的地方是一連串的RxBus的使用. 從這裡看出來RxJava真心的強大和好用.
代碼中有一個委托類對象, 這個對象很重要, 管理了軟鍵盤, emotion按鈕, 輸入框, emotion面板的關聯操作
//這個委托類對象很重要
mDelegatioin = new KeyboardActionDelegation(mContext, mInput, mIvEmotion, mEmoLayout);
/**
* 鍵盤, emotion按鈕, 輸入框, emotion面板之間的相互關系委派給這個類管理
*/
public class KeyboardActionDelegation {
private ImageView mBtnEmotion; //Emotion按鈕
private EditText mInput; //輸入框
private Context mContext;
private ViewGroup mEmotionPanel; //Emotion面板
private boolean isShowSoftInput; //是否顯示輸入法
public KeyboardActionDelegation(Context context, EditText input, ImageView button, ViewGroup view) {
this.mBtnEmotion = button;
this.mInput = input;
this.mContext = context;
this.mEmotionPanel = view;
init();
}
/**
* 初始化, 綁定事件
*/
private void init() {
//輸入框焦點改變的監聽
mInput.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
hideEmotionPanel(); //隱藏Emotion面板
} else {
hideSoftKeyboard(); //隱藏鍵盤
}
}
});
//輸入框點擊事件的監聽
mInput.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!isEmotionPanelShowing())//如果Emotion面板沒有顯示則直接返回
return;
hideEmotionPanel();//隱藏Emotion面板
}
});
//Emotion表情按鈕被點擊的監聽
mBtnEmotion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isEmotionPanelShowing()) {//如果Emotion面板顯示
hideEmotionPanel(); //隱藏Emotionm面板
} else {
showEmotionPanel();//顯示Emotion面板
}
}
});
}
/**
* 顯示Emotion面板
*/
public void showEmotionPanel() {
mBtnEmotion.setSelected(true);//設置Emotion按鈕被選中, 改變了Emotion按鈕的顯示表情
hideSoftKeyboard();//隱藏輸入法
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mEmotionPanel.setVisibility(View.VISIBLE); //設置可見
}
}, 300);
}
/**
* 判斷Emotion面板是否顯示
*/
private boolean isEmotionPanelShowing() {
return mEmotionPanel.getVisibility() == View.VISIBLE;
}
/**
* 隱藏軟鍵盤
*/
private void hideSoftKeyboard() {
DeviceManager.getSoftInputManager(mContext).hideSoftInputFromWindow(mInput.getWindowToken(), 0);
isShowSoftInput = false;
}
/**
* 隱藏表情面板
*/
private void hideEmotionPanel() {
mEmotionPanel.setVisibility(View.GONE);//設置不占位
mBtnEmotion.setSelected(false);
}
/**
* 是否顯示輸入法
*/
public boolean isShowSoftInput() {
return isShowSoftInput;
}
/**
* Emotion面板中item被選中
*/
public void onEmotionItemSelected(EmotionRules emotion) {
if (mInput == null || emotion == null) {
return;
}
int start = mInput.getSelectionStart();//獲取選中文本的起始位置
int end = mInput.getSelectionEnd(); //獲取選中文本的結束位置
if (start == end) { //如果未選中文本
mInput.append(InputHelper.insertEtn(mContext, emotion)); //將Emotion表情直接追加到光標後
} else { //如果有選中文本
Spannable str = InputHelper.insertEtn(mContext, emotion);//獲得需要插入的內容
mInput.getText().replace(Math.min(start, end), Math.max(start, end), str, 0, str.length());//用Emotion表情替換掉選中的文本
}
}
/**
* 當使用回退鍵時, 讓Emotion面板和輸入法都隱藏
*/
public boolean onTurnBack() {
if (isEmotionPanelShowing()) {
hideEmotionPanel();
return false;
}
if (isShowSoftInput()) {
hideEmotionPanel();
return false;
}
return true;
}
}
這個類其實就是管理了不同的狀態變化, 判斷是否要顯示隱藏輸入法, Emotion面板等.
這裡面比較重要的一個方法是onEmotionItemSelected(), 也就是Emotion面板中表情被選中後的操作.
/**
* Emotion面板中item被選中
*/
public void onEmotionItemSelected(EmotionRules emotion) {
if (mInput == null || emotion == null) {
return;
}
int start = mInput.getSelectionStart();//獲取選中文本的起始位置
int end = mInput.getSelectionEnd(); //獲取選中文本的結束位置
if (start == end) { //如果未選中文本
mInput.append(InputHelper.insertEtn(mContext, emotion)); //將Emotion表情直接追加到光標後
} else { //如果有選中文本
Spannable str = InputHelper.insertEtn(mContext, emotion);//獲得需要插入的內容
mInput.getText().replace(Math.min(start, end), Math.max(start, end), str, 0, str.length());//用Emotion表情替換掉選中的文本
}
}
如果編輯框中有選中的文本,則用表情直接替換文本, 如果沒有, 則直接添加到光標後面. 這個方法在上面的KeyboardFragment中被調用.
// 注冊一個監聽器接收用戶選擇了一個emotion表情的事件
RxBus.with(this)
.setEvent(Events.EventEnum.DELIVER_SELECT_EMOTION) //設置過濾接收選擇一個emotion表情事件
.setEndEvent(FragmentEvent.DESTROY) //直到Fragment destroy為止
.onNext((events -> {
EmotionRules emotion = events.getMessage();
mDelegatioin.onEmotionItemSelected(emotion); //設置所選的emotion
})).create();
KeyboardActionDelegation#onEmotionItemSelected()中使用了InputHelper#insertEtn()實現了在文字中插入Emotion表情. 這裡涉及到了圖文混排.
/**
* 輸入幫助類
*/
public class InputHelper {
/**
* 退格
*/
public static void backspace(EditText input) {
if (input == null) {
return;
}
KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
input.dispatchKeyEvent(event);
}
/**
* 插入表情到文字中, 這裡使用到了SpannableString和ImageSpan實現圖文混排
*/
@SuppressWarnings("all")
public static Spannable insertEtn(Context context, EmotionRules emotion) {
String remote = emotion.getRemote(); //獲得表情的序號
Spannable spannable = new SpannableString(remote); //創建文本樣式
Drawable d = context.getResources().getDrawable(emotion.getMResId()); //獲得emotion的drawable
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); //設置邊界為drawable的真實寬高
ImageSpan iSpan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);//獲得圖片樣式
//Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 前後輸入的字符都不應用這種Spannable
spannable.setSpan(iSpan, 0, remote.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
}
public static void encode(TextView view, String content) {
view.setText("");
StringBuilder mNormalBuilder = new StringBuilder();
StringBuilder mEtnBuilder = new StringBuilder();
boolean isCut = false; //是否截斷
for (int i = 0; i < content.length(); i++) {
char unit = content.charAt(i);
// 截斷,保存在etnBuilder容器
if (isCut) {
// 截斷期間發現新的[,將之前的緩存存入view,刷新容器
if (unit == '[') {
mNormalBuilder.append(mEtnBuilder.toString());
mEtnBuilder.delete(0, mEtnBuilder.length());
mEtnBuilder.append(unit);
continue;
}
if (unit == ']') {
mEtnBuilder.append(unit);
EmotionRules rule = EmotionRules.containOf(mEtnBuilder.toString());
view.append(mNormalBuilder.toString());
if (rule != null) {
view.append(insertEtn(view.getContext(), rule));
} else {
view.append(mEtnBuilder.toString());
}
mNormalBuilder.delete(0, mNormalBuilder.length());
mEtnBuilder.delete(0, mEtnBuilder.length());
isCut = false;
continue;
}
mEtnBuilder.append(unit);
} else { // --> 非截斷
if (unit == '[') {
mEtnBuilder.append(unit);
isCut = true;
continue;
}
mNormalBuilder.append(unit);
}
}
view.append(mNormalBuilder.toString()); //追加到TextView的顯示緩沖區
view.append(mEtnBuilder.toString());
}
}
//TODO: encode()還沒看的太懂, 留個TODO占坑吧.
這個類最重要的方法是InputHelper#insertEtn(). 實現了圖文混排效果.
/**
* 插入表情到文字中, 這裡使用到了SpannableString和ImageSpan實現圖文混排
*/
@SuppressWarnings("all")
public static Spannable insertEtn(Context context, EmotionRules emotion) {
String remote = emotion.getRemote(); //獲得表情的序號
Spannable spannable = new SpannableString(remote); //創建文本樣式
Drawable d = context.getResources().getDrawable(emotion.getMResId()); //獲得emotion的drawable
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); //設置邊界為drawable的真實寬高
ImageSpan iSpan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);//獲得圖片樣式
//Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 前後輸入的字符都不應用這種Spannable
spannable.setSpan(iSpan, 0, remote.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
}
這裡講解下setSpan()方法. ImageSpan 可以使用圖片替換文字達到圖文混排的效果,例如在一般聊天工具當中在文字和表情一起發的狀態。
public void setSpan(Object what, int start, int end, int flags);
what傳入各種Span類型的實例,start和end標記要替代的文字內容的范圍,flags是用來標識在 Span 范圍內的文本前後輸入新的字符時是否把它們也應用這個效果,可以傳入Spanned.SPAN_EXCLUSIVE_EXCLUSIVE、Spanned.SPAN_INCLUSIVE_EXCLUSIVE、Spanned.SPAN_EXCLUSIVE_INCLUSIVE、Spanned.SPAN_INCLUSIVE_INCLUSIVE幾個參數,INCLUSIVE表示應用該效果,EXCLUSIVE表示不應用該效果,如Spanned.SPAN_INCLUSIVE_EXCLUSIVE表示對前面的文字應用該效果,而對後面的文字不應用該效果。
下面這個也可以算是一個模板代碼了.
Drawabledrawable=mContext.getResources().getDrawable(R.drawable.new_topic_drawable);
drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
spanString.setSpan(imageSpan,spanString.length()-1,spanString.length(),Spannable.SPAN_INCLUSIVE_INCLUSIVE);
這個類從名字上就可以看出是Emotion面板的Fragment.
/**
* Emotion面板的Fragment
**/
public class EmotionPanelFragment extends BaseTabNavFragment {
public static final int COLUMN = 7; //7列
public static final int ROW = 3; //3行
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setCurrentItem(0); //設置當前選中的item
}
/**
* 設置Emotion面板中的每個View, 也就是每個Emotion表情
*/
@Override
public View setupTabItemView(String title) {
//每個Emotion表情就是一個帶圓形背景的TextView
TextView view = new TextView(mContext);
int m4 = UIHelper.dip2px(mContext, 4);
LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(m4, m4);
int m5 = UIHelper.dip2px(mContext, 5);
layout.setMargins(m5, m5, m5, m5); //外邊距
view.setLayoutParams(layout);
view.setBackgroundResource(R.drawable.selector_dot_nav); //設置圓形背景
return view;
}
/**
* 填充tab中的表情, 這裡使用了分頁填充
*/
@Override
public void onSetupTabs() {
EmotionRules[] rules = EmotionRules.values(); //獲得EmotionRules預定義的枚舉項
//一頁顯示幾條
int page_size = COLUMN * ROW;
//總共多少頁
int page_count = (rules.length + page_size - 1) / page_size;
int i;
//分頁
for (i = 0; i < page_count - 1; i++) { //如果是前page-1頁,直接添加滿即可
addTab("", initView(i * page_size, (i + 1) * page_size - 1));
}
//最後一頁添加到表情結束
addTab("", initView(i * page_size, rules.length - 1));
}
/**
* 用持有GridView的ViewFragment,填充到tab中去
*/
public void addTab(String title, View view) {
addTab(title, new ViewFragment(view));
}
/**
* 初始化Emotion表情展示的GridView
*/
private View initView(int start, int end) {
final EmotionRules[] rules = Arrays.copyOfRange(EmotionRules.values(), start, end + 1);//得到一份EmotionRules的拷貝
GridView view = new GridView(mContext); //創建一個GridView展示Emotion表情
GridView.LayoutParams params = new GridView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
);
view.setLayoutParams(params);
view.setNumColumns(COLUMN); //設置列數
view.setAdapter(new EmotionAdapter(rules)); //設置適配器,實現在下面
view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
Events events = Events.just(rules[position]); //封裝事件實體,發送Emotion表情被選中的事件
events.what = Events.EventEnum.DELIVER_SELECT_EMOTION;
RxBus.getInstance().send(events); //又見RxBus,真是神器啊
}
});
return view;
}
@Override
public FragmentManager getGenuineFragmentManager() {
return getChildFragmentManager();
}
/**
* 一個典型的適配器
*/
public static class EmotionAdapter extends BaseAdapter {
private EmotionRules[] rules;
public EmotionAdapter(EmotionRules[] rules) {
this.rules = rules;
}
@Override
public int getCount() {
return rules.length;
}
@Override
public Object getItem(int position) {
return rules[position];
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHandler handler;
if (convertView == null) {
convertView = new ImageView(parent.getContext());
int m3 = UIHelper.dip2px(parent.getContext(), 3f);
convertView.setPadding(m3, m3, m3, m3);
handler = new ViewHandler();
handler.iView = (ImageView) convertView;
convertView.setTag(handler);
} else {
handler = (ViewHandler) convertView.getTag();
}
handler.iView.setImageResource(rules[position].getMResId()); //將Emotion表情設置到ImageView
return convertView;
}
class ViewHandler {
public ImageView iView;
}
}
}
這段代碼比較簡單, 就是將Emotion表情填充到面板中,每個頁面都是一個ViewFragment.
/**
* 一個簡單的Fragment,專門顯示一個View,特別服務於輪番、ViewPager
*/
@SuppressLint("ValidFragment")
public class ViewFragment extends BaseFragment {
private View view;
public ViewFragment(View view) {
this.view = view;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return view;
}
}
ViewFragment內部持有了一個View對象. 可以簡單的理解為將View轉化為一個Fragment.
在Emotion面板中, Emotion表情是使用一個EmotionRules管理的. EmotionRules枚舉類制定了Emotion表情的規則. 這個命名真不錯.
/**
* 定義了emotion規則: 類型,圖表,文字含義,序號
*/
public enum EmotionRules {
EMOTION0(0, R.mipmap.smiley_0, "[微笑]", "[0]"),
EMOTION1(0, R.mipmap.smiley_1, "[撇嘴]", "[1]"),
EMOTION2(0, R.mipmap.smiley_2, "[色]", "[2]"),
EMOTION3(0, R.mipmap.smiley_3, "[發呆]", "[3]"),
EMOTION4(0, R.mipmap.smiley_4, "[得意]", "[4]"),
EMOTION5(0, R.mipmap.smiley_5, "[流淚]", "[5]"),
EMOTION6(0, R.mipmap.smiley_6, "[害羞]", "[6]"),
EMOTION7(0, R.mipmap.smiley_7, "[閉嘴]", "[7]"),
EMOTION8(0, R.mipmap.smiley_8, "[睡]", "[8]"),
EMOTION9(0, R.mipmap.smiley_9, "[大哭]", "[9]"),
EMOTION10(0, R.mipmap.smiley_10, "[尴尬]", "[10]"),
EMOTION11(0, R.mipmap.smiley_11, "[發怒]", "[11]"),
EMOTION12(0, R.mipmap.smiley_12, "[調皮]", "[12]"),
EMOTION13(0, R.mipmap.smiley_13, "[呲牙]", "[13]"),
EMOTION14(0, R.mipmap.smiley_14, "[驚訝]", "[14]"),
EMOTION15(0, R.mipmap.smiley_15, "[難過]", "[15]"),
EMOTION16(0, R.mipmap.smiley_16, "[酷]", "[16]"),
EMOTION17(0, R.mipmap.smiley_17, "[冷汗]", "[17]"),
EMOTION18(0, R.mipmap.smiley_18, "[抓狂]", "[18]"),
EMOTION19(0, R.mipmap.smiley_19, "[吐]", "[19]"),
EMOTION20(0, R.mipmap.smiley_20, "[偷笑]", "[20]"),
EMOTION21(0, R.mipmap.smiley_21, "[可愛]", "[21]"),
EMOTION22(0, R.mipmap.smiley_22, "[白眼]", "[22]"),
EMOTION23(0, R.mipmap.smiley_23, "[傲慢]", "[23]"),
EMOTION24(0, R.mipmap.smiley_24, "[饑餓]", "[24]"),
EMOTION25(0, R.mipmap.smiley_25, "[困]", "[25]"),
EMOTION26(0, R.mipmap.smiley_26, "[驚恐]", "[26]"),
EMOTION27(0, R.mipmap.smiley_27, "[流汗]", "[27]"),
EMOTION28(0, R.mipmap.smiley_28, "[憨笑]", "[28]"),
EMOTION29(0, R.mipmap.smiley_29, "[大兵]", "[29]"),
EMOTION30(0, R.mipmap.smiley_30, "[奮斗]", "[30]"),
EMOTION31(0, R.mipmap.smiley_31, "[咒罵]", "[31]"),
EMOTION32(0, R.mipmap.smiley_32, "[疑問]", "[32]"),
EMOTION33(0, R.mipmap.smiley_33, "[噓]", "[33]"),
EMOTION34(0, R.mipmap.smiley_34, "[暈]", "[34]"),
EMOTION35(0, R.mipmap.smiley_35, "[折磨]", "[35]"),
EMOTION36(0, R.mipmap.smiley_36, "[衰]", "[36]"),
EMOTION37(0, R.mipmap.smiley_37, "[骷髅]", "[37]"),
EMOTION38(0, R.mipmap.smiley_38, "[敲打]", "[38]"),
EMOTION39(0, R.mipmap.smiley_39, "[再見]", "[39]"),
EMOTION40(0, R.mipmap.smiley_40, "[擦汗]", "[40]"),
EMOTION41(0, R.mipmap.smiley_41, "[摳鼻]", "[41]"),
EMOTION42(0, R.mipmap.smiley_42, "[鼓掌]", "[42]"),
EMOTION43(0, R.mipmap.smiley_43, "[糗大了]", "[43]"),
EMOTION44(0, R.mipmap.smiley_44, "[壞笑]", "[44]"),
EMOTION45(0, R.mipmap.smiley_45, "[左哼哼]", "[45]"),
EMOTION46(0, R.mipmap.smiley_46, "[右哼哼]", "[46]"),
EMOTION47(0, R.mipmap.smiley_47, "[哈欠]", "[47]"),
EMOTION48(0, R.mipmap.smiley_48, "[鄙視]", "[48]"),
EMOTION49(0, R.mipmap.smiley_49, "[委屈]", "[49]"),
EMOTION50(0, R.mipmap.smiley_50, "[快哭了]", "[50]"),
EMOTION51(0, R.mipmap.smiley_51, "[陰險]", "[51]"),
EMOTION52(0, R.mipmap.smiley_52, "[親親]", "[52]"),
EMOTION53(0, R.mipmap.smiley_53, "[嚇]", "[53]"),
EMOTION54(0, R.mipmap.smiley_54, "[可憐]", "[54]");
private int type;
private int mResId;
private String name;
private String remote;
EmotionRules(int type, int mResId, String name, String remote) {
this.type = type;
this.mResId = mResId;
this.name = name;
this.remote = remote;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getMResId() {
return mResId;
}
public void setMResId(int mResId) {
this.mResId = mResId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemote() {
return remote;
}
public void setRemote(String remote) {
this.remote = remote;
}
/**
* 判斷emotion的中文含義和序號中是否包含指定的字符串
*/
public static EmotionRules containOf(String s) {
EmotionRules[] rules = EmotionRules.values();
for (EmotionRules item : rules) {
if (item.getName().equals(s) || item.getRemote().equals(s))
return item;
}
return null;
}
}
這個類中, 將圖片表情和文字都一一對應起來. 至於裡面的remote字段是什麼意思, 我也只能猜測是序號相關的東西了.
至此, 這個可以發送Emotion表情的評論面板功能已經分析完畢. to be continue …
1、修改hosts文件,這個方法操作簡單,但經常失靈,或許運氣不好吧。 首先更新host文件,如圖,打開目錄 C:WindowsSystem32driverse
近幾個月傳出了谷歌正在加速整合Android和Chrome OS的消息,新操作系統定名Andromeda(仙女座)。外媒給出的最新進展是,目前已經有兩家型硬
社會化分享社會化分享,指的是用戶通過互聯網這個媒介,把文本/圖片/多媒體信息分享到該用戶的交際圈,從而加快信息傳播的行為。對於app來說,網絡社區雖多,但用戶量足夠大的就
Android中監聽觸摸事件是onTouchEvent方法,它的參數為MotionEvent,下面列舉MotionEvent的一些常用的方法: getPointerC