
什麼是MVP呢,簡單來說就是将view層和邏輯完全獨立出來,讓邏輯和顯示完全獨立。本例中就是采用了這種模式,讓activity作為view層,activity中涉及了擴充卡,是以這裡嘗試讓擴充卡作為P層來進行邏輯處理。以後可能要考慮用多個p來做邏輯處理。總之,我們先來分析下如何用MVP得思路來分析這個工程吧~
一、界面
界面這個環節有很多細節需要扣,之前我寫過一篇文章就是講這個界面實作的,推薦先去看看:http://www.cnblogs.com/tianzhijiexian/p/4295195.html
二、根據界面來思考邏輯
一般情況下我們從設計那裡得到了一張圖後就需要進行分析了,分析這個界面需要什麼邏輯。是以我們再來看看界面是什麼樣的:
我們從上到下進行分析,分析時就需要寫出接口了,等于把自然語言程式化。
1.頂部有退出按鈕——finish()
2.頂部有重新整理按鈕——refresh();重新整理成功後需要有回調——onRefreshSuccess()
3.界面有資訊,需要擴充卡——setAdapter()
4.下方有+号,是發送圖檔的按鈕——sendPhoto();因為是實時聊天界面,即使資訊沒發送成功,也需要添加到擴充卡中,顯示一個沒法送成功的标記就好。是以不需要做回調。隻需要在擴充卡的getView()中根據list得item的标志來判斷是否發送成功了,根據是否發送成功來顯示沒法送成功的感歎号。
5.有發送按鈕,發送文字——addNewReply(String str);因為是實時聊天界面,即使資訊沒發送成功,也需要添加到擴充卡中,顯示一個沒法送成功的标記就好。需要在擴充卡的getView()中進行狀态的回調,回調方式同上。
6.既然需要在getView中進行回調,那麼activity中就要能有這個getView()的方法——onGetViewFromAdapter()
三、Activity需要實作的接口
這樣我們大概的接口就已經寫好了,下面來看看最終的接口文檔:
接口 IUMengFeedbackView(實作友盟回報的activity需要實作這個接口)
四、調用P層進行邏輯操作
我們假設我們的activity已經實作了這個接口,也已經做好了界面,那麼是不是該調用p層來處理邏輯了呢?現在p層在哪裡呢?别着急,p我已經寫好了,而且對外提供了很多的方法讓view可以随意調用。
UMengFeedbackPresenter的源碼:
package com.kale.umenglib;
import com.umeng.fb.FeedbackAgent;
import com.umeng.fb.SyncListener;
import com.umeng.fb.model.Conversation;
import com.umeng.fb.model.Reply;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.List;
import java.util.UUID;
/**
* @author:Jack Tony
* 定義回話界面的adapter
* @date :2015年2月9日
*/
public class UMengFeedbackPresenter extends BaseAdapter {
private final String TAG = getClass().getSimpleName();
/**
* 表示是一對一聊天,有兩個類型的資訊
*/
private static final int VIEW_TYPE_COUNT = 2;
/**
* 使用者的辨別
*/
private static final int VIEW_TYPE_USER = 0;
/**
* 開發者的辨別
*/
private static final int VIEW_TYPE_DEV = 1;
/**
* 一次性加載多少條資料,預設10條
*/
private int mLoadDataNum = 10; // default
/**
* 目前顯示的資料條數
*/
private int mCurrentMsgCount = 10;
private Context mContext;
/**
* 負責顯示umeng回報界面資訊的activity
*/
private IUMengFeedbackView mFeedbackView;
/**
* 回報系統的回話對象
*/
private Conversation mConversation;
private static UMengFeedbackPresenter instance;
private UMengFeedbackPresenter(IUMengFeedbackView view) {
mContext = (Context) view;
mFeedbackView = view;
mConversation = new FeedbackAgent(mContext).getDefaultConversation();
mConversation.setOnChangeListener(new Conversation.OnChangeListener() {
@Override
public void onChange() {
// 發送消息後會自動調用此方法,在這裡更新下發送狀态
notifyDataSetChanged();
}
});
}
public static UMengFeedbackPresenter getInstance(IUMengFeedbackView view) {
if (instance == null) {
instance = new UMengFeedbackPresenter(view);
}
return instance;
}
/**
* 得到目前adapt中的資料條數
*
* @return 目前adapt中的資料條數
*/
@Override
public int getCount() {
// 如果開始時的數目小于一次性顯示的數目,就按照目前的數目顯示,否則會數組越界
int totalCount = mConversation.getReplyList().size();
if (totalCount < mCurrentMsgCount) {
mCurrentMsgCount = totalCount;
}
return mCurrentMsgCount;
}
/**
* @return 目前的position
* 重要方法,計算出目前的position
*/
private int getCurrentPosition(int position) {
int totalCount = mConversation.getReplyList().size();
if (totalCount < mCurrentMsgCount) {
mCurrentMsgCount = totalCount;
}
return totalCount - mCurrentMsgCount + position;
}
@Override
public Object getItem(int position) {
position = getCurrentPosition(position);
return mConversation.getReplyList().get(position);
}
@Override
public long getItemId(int position) {
return getCurrentPosition(position);
}
@Override
public int getViewTypeCount() {
// 這裡是一對一聊天,是以是兩種類型
return VIEW_TYPE_COUNT;
}
@Override
public int getItemViewType(int position) {
position = getCurrentPosition(position);
// 擷取單條回複
Reply reply = mConversation.getReplyList().get(position);
if (reply.type.equals(Reply.TYPE_DEV_REPLY)) {
// 開發者回複Item布局
return VIEW_TYPE_DEV;
} else if (reply.type.equals(Reply.TYPE_USER_REPLY)) {
// 使用者回報、回複Item布局
return VIEW_TYPE_USER;
} else {
return 0;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
position = getCurrentPosition(position);
// 得到目前位置的reply對象
Reply reply = mConversation.getReplyList().get(position);
//Log.d(TAG, "reply type = " + reply.type);
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
// 根據Type的類型來加載不同的Item布局
switch (reply.type) {
case Reply.TYPE_DEV_REPLY:
// 如果是開發者回複的,那麼就加載開發者回複的布局
convertView = inflater.inflate(mFeedbackView.getDevReplyLayoutId(), null);
break;
case Reply.TYPE_NEW_FEEDBACK:
//break;
case Reply.TYPE_USER_REPLY:
convertView = inflater.inflate(mFeedbackView.getUserReplyLayoutId(), null);
break;
default:
}
}
if (reply.type.equals(Reply.TYPE_USER_REPLY) || reply.type.equals(Reply.TYPE_NEW_FEEDBACK)) {
mFeedbackView.setUserReplyView(convertView, reply);
} else if (reply.type.equals(Reply.TYPE_DEV_REPLY)) {
mFeedbackView.setDevReplyView(convertView, reply);
}
Reply nextReply = null;
if ((position + 1) < mConversation.getReplyList().size()) {
nextReply = mConversation.getReplyList().get(position + 1);
}
mFeedbackView.onGetViewFromAdapter(convertView, reply, nextReply);
return convertView;
}
/**
* 加載之前的聊天資訊
*/
public void loadOldData() {
int loadDataNum = mLoadDataNum;
int totalCount = mConversation.getReplyList().size();
if (loadDataNum + mCurrentMsgCount >= totalCount) {
// 如果要加載的資料超過了資料的總量,算出實際加載的資料條數
loadDataNum = totalCount - mCurrentMsgCount;
}
mCurrentMsgCount += loadDataNum;
notifyDataSetChanged();
mFeedbackView.onLoadOldDataSuccess(loadDataNum);
}
/**
* 發送圖檔給開發者
*/
public void sendPhotoToDev() {
Intent intent = new Intent();
intent.putExtra(UMengFeedbackPhotoActivity.KEY_UMENG_GET_PHOTO, UMengFeedbackPhotoActivity.VALUE_UMENG_GET_PHOTO);
intent.setClass(mContext, UMengFeedbackPhotoActivity.class);
mContext.startActivity(intent);
}
/**
* 當使用者發送圖檔資訊時,在Activity的onActivityResult中調用此方法來處理上傳圖檔等後續操作
*/
protected void getPhotoFromAlbum(Intent data) {
//Log.e(TAG, "data.getDataString -- " + data.getDataString());
if (UMengB.a(mContext, data.getData())) {
UMengB.a(mContext, data.getData(), "R" + UUID.randomUUID().toString(), new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
sendMsgToDev((String) msg.obj, Reply.CONTENT_TYPE_IMAGE_REPLY);
}
});
}
}
/**
* 使用者發送了一條新的資訊後調用此方法
*
* @param replyMsg 資訊的内容
* @param type Reply.CONTENT_TYPE_TEXT_REPLY或者Reply.CONTENT_TYPE_IMAGE_REPLY
*/
public void sendMsgToDev(String replyMsg, String type) {
if (type.equals(Reply.CONTENT_TYPE_TEXT_REPLY)) {
mConversation.addUserReply(replyMsg);
} else if (type.equals(Reply.CONTENT_TYPE_IMAGE_REPLY)) {
mConversation.addUserReply("", replyMsg, "image_reply", -1.0F);
} else if (type.equals(Reply.CONTENT_TYPE_AUDIO_REPLY)) {
}
mCurrentMsgCount++;
syncToUmeng();
}
/**
* 将資料和伺服器同步
* TODO:這裡有兩種寫法,可以考慮換個實作方式。
*/
public void syncToUmeng() {
//new FeedbackAgent(mContext).sync();// 第一種寫法
// 第二種寫法↓
mConversation.sync(new SyncListener() {
@Override
public void onSendUserReply(List<Reply> replyList) {
Log.d(TAG, "onSendUserReply");
if (replyList == null || replyList.size() < 1) {
Log.d(TAG, "user 使用者沒有發送新的消息");
} else {
notifyDataSetChanged();
}
}
@Override
public void onReceiveDevReply(List<Reply> replyList) {
Log.d(TAG, "onReceiveDevReply");
if (replyList == null || replyList.size() < 1) {
// 沒有開發者新的回複
Log.d(TAG, "dev 開發者沒有新的回複");
} else {
notifyDataSetChanged();
}
}
});
}
/**
* 設定界面一開始顯示多少條資料,預設顯示最近的十條資訊
*/
public void setReplyMsgCount(int count) {
mCurrentMsgCount = count;
}
/**
* 設定調用loadOldData()時,一次性加載多少條資料,預設10條
*/
public void setLoadDataNum(int number) {
mLoadDataNum = number;
}
/**
* 得到擴充卡對象
*/
public BaseAdapter getAdapter() {
return this;
}
}
shark0017
因為有發送圖檔的功能是以需要從系統相冊中得到圖檔,這就要建立一個activity去擷取圖檔:
package com.kale.umenglib;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.MediaStore;
/**
* @author Jack Tony
* @date 2015/5/11
*/
public class UMengFeedbackPhotoActivity extends Activity{
private static final int REQUEST_CODE = 1;
public static final String KEY_UMENG_GET_PHOTO = "KEY_UMENG_GET_PHOTO";
public static final int VALUE_UMENG_GET_PHOTO = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent() != null && getIntent().getIntExtra(KEY_UMENG_GET_PHOTO, 0) == VALUE_UMENG_GET_PHOTO) {
Intent intent = new Intent("android.intent.action.PICK", MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, REQUEST_CODE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == -1 && requestCode == REQUEST_CODE && data != null) {
UMengFeedbackPresenter.getInstance(null).getPhotoFromAlbum(data);
}
finish();
}
}
五、Demo
下面的demo通過activity來調用了presenter的各個方法,完全自定義的友盟的回報界面,而且隻用關系界面的view,不用考慮任何邏輯處理。這就是mvp的特點,分工明确,而且友善擴充~
UMengFeedbackActivity源碼:
package com.example.jack.umengfeedback;
import com.kale.lib.ViewHolder;
import com.kale.lib.activity.KaleBaseActivity;
import com.kale.lib.utils.EasyToast;
import com.kale.lib.utils.InputUtil;
import com.kale.umenglib.IUMengFeedbackView;
import com.kale.umenglib.UMengFeedbackPresenter;
import com.umeng.fb.model.Reply;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.ViewStub;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
public class UMengFeedbackActivity extends KaleBaseActivity implements IUMengFeedbackView {
/**
* 退出的文字按鈕
*/
private TextView exitTv;
/**
* 重新整理新的資訊的圖檔按鈕
*/
private ImageView refreshIv;
/**
* 會話界面的下拉重新整理控件
*/
private SwipeRefreshLayout swipeRefreshLayout;
/**
* 對話的listView
*/
private ListView conversationLv;
/**
* 輸入資訊的文本框
*/
private EditText inputBoxEt;
/**
* 發送資訊的按鈕
*/
private Button sendMsgBtn;
private ImageView sendPhotoIv;
/**
* 友盟回報界面的聊天資訊擴充卡
*/
private UMengFeedbackPresenter mUMengFeedbackPresenter;
@Override
protected void beforeSetContentView() {
super.beforeSetContentView();
}
@Override
protected int getContentViewId() {
return R.layout.umeng_feedback_main;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* 當這個activity在最上方時不重複啟動activity, 如果調用了startActivity,那麼就更新下視圖
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d(TAG, "on new intent");
}
@Override
protected void findViews() {
refreshIv = getView(R.id.refresh_imageView);
exitTv = getView(R.id.exit_textView);
swipeRefreshLayout = getView(R.id.swipe_container);
conversationLv = getView(R.id.fb_conversation_listView);
inputBoxEt = getView(R.id.inputBox_editText);
sendMsgBtn = getView(R.id.sendMsg_button);
sendPhotoIv = getView(R.id.sendPhoto_imageView);
}
@Override
protected void beforeSetViews() {
mUMengFeedbackPresenter = UMengFeedbackPresenter.getInstance(this);
}
@Override
protected void setViews() {
refreshIv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO:修複bug:隻有少數資訊時,重新整理開發者的回複後listView會跳到頂端
mUMengFeedbackPresenter.syncToUmeng();
EasyToast.makeText(mContext, "重新整理成功~");
}
});
exitTv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
setSwipeLayout();
setConversationListView();
setInputBoxEditText();
/**
* 設定發送按鈕的事件
*/
sendMsgBtn.setEnabled(false);
sendMsgBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sendMessage();
}
});
/**
* 設定添加圖檔按鈕的事件
*/
sendPhotoIv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mUMengFeedbackPresenter.sendPhotoToDev();
conversationLv.setSelection(mUMengFeedbackPresenter.getAdapter().getCount());
}
});
}
/**
* 設定下拉重新整理的控件
*/
private void setSwipeLayout() {
swipeRefreshLayout.setSize(SwipeRefreshLayout.DEFAULT);
// 設定下拉圓圈上的顔色,藍色、綠色、橙色、紅色
swipeRefreshLayout.setColorSchemeResources(
android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
swipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
mUMengFeedbackPresenter.loadOldData();
conversationLv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_NORMAL);
}
});
}
/**
* 當加載舊的資料完成後的回調方法
*
* @param loadDataNum 加載了多少個舊的資料
*/
@Override
public void onLoadOldDataSuccess(int loadDataNum) {
swipeRefreshLayout.setRefreshing(false);
// 加載完畢舊的資料,跳到重新整理出來資料的位置
if (loadDataNum - 1 >= 0) {
conversationLv.setSelection(loadDataNum - 1);
} else {
EasyToast.makeText(mContext, "已經到頭了");
conversationLv.setSelection(0);
}
conversationLv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
}
/**
* 設定listView,list不顯示分割線,設定滾動監聽器,設定擴充卡
*/
private void setConversationListView() {
conversationLv.setDivider(null);
conversationLv.setAdapter(mUMengFeedbackPresenter.getAdapter());
// 不顯示滾動到頂部/底部的陰影(減少繪制)
conversationLv.setOverScrollMode(View.OVER_SCROLL_NEVER);
// 監聽listView的滑動狀态,如果到了頂部就重新整理資料,向上滑動就隐藏輸入法
conversationLv.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
// 滾動停止
if (view.getLastVisiblePosition() == (view.getCount() - 1)) {
// 如果滾動到底部
} else if (view.getFirstVisiblePosition() == 0) {
// 滾動到頂部
}
break;
case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
// 開始滾動
break;
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
// 正在滾動
InputUtil.getInstance((Activity) mContext).hide();
break;
}
}
});
}
/**
* 設定發送消息的按鈕和輸入框 按下Enter鍵,發送消息
*/
private void setInputBoxEditText() {
inputBoxEt.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// 按下回車發送消息
// 這兩個條件必須同時成立,如果僅僅用了enter判斷,就會執行兩次
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
sendMessage();
return true;
}
return false;
}
});
// 給editText添加監聽器
inputBoxEt.addTextChangedListener(new TextWatcher() {
// 輸入過程中,還在記憶體裡,沒到螢幕上
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
// 在輸入之前會觸發的
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
// 輸入完将要顯示到螢幕上時會觸發
boolean isEmpty = s.toString().isEmpty();
sendMsgBtn.setEnabled(!isEmpty);
sendMsgBtn.setTextColor(isEmpty ? 0xffa1a2a5 : 0xffffffff);
}
});
}
/**
* 發送消息
*/
private void sendMessage() {
String replyMsg = inputBoxEt.getText().toString();
inputBoxEt.getText().clear();
if (!TextUtils.isEmpty(replyMsg)) {
mUMengFeedbackPresenter.sendMsgToDev(replyMsg, Reply.CONTENT_TYPE_TEXT_REPLY);
conversationLv.setSelection(mUMengFeedbackPresenter.getAdapter().getCount());
}
}
@Override
public int getUserReplyLayoutId() {
return R.layout.umeng_feedback_user_reply;
}
/**
* 設定使用者的list item view
* 這裡的提示資訊有進度條和感歎号兩種。如果正在發送就顯示進度條,如果發送失敗就顯示感歎号
*/
@Override
public void setUserReplyView(View convertView, Reply reply) {
// 利用viewHolder進行了優化
TextView textMsgTv = ViewHolder.get(convertView, R.id.textMsg_textView);
ImageView photoMsgIv = ViewHolder.get(convertView, R.id.photoMsg_imageView);
ImageView msgErrorIv = ViewHolder.get(convertView, R.id.msg_error_imageView);
ProgressBar msgSendingPb = ViewHolder.get(convertView, R.id.msg_progressBar);
// 放入消息
switch (reply.content_type) {
case Reply.CONTENT_TYPE_TEXT_REPLY:
photoMsgIv.setVisibility(View.GONE);
textMsgTv.setVisibility(View.VISIBLE);
textMsgTv.setText(reply.content);
break;
case Reply.CONTENT_TYPE_IMAGE_REPLY:
textMsgTv.setVisibility(View.GONE);
photoMsgIv.setVisibility(View.VISIBLE);
// 顯示大圖
//photoMsgIv.setImageBitmap(BitmapFactory.decodeFile(com.umeng.fb.util.c.b(mContext, reply.reply_id)));
// 顯示小圖
com.umeng.fb.image.a.a().a(com.umeng.fb.util.c.b(mContext, reply.reply_id), photoMsgIv, getPhotoSize(mContext));
break;
case Reply.CONTENT_TYPE_AUDIO_REPLY:
break;
default:
}
// 根據Reply的狀态來設定replyStateFailed的狀态,如果發送失敗就顯示提示圖示
switch (reply.status) {
case Reply.STATUS_NOT_SENT:
msgSendingPb.setVisibility(View.GONE);
msgErrorIv.setVisibility(View.VISIBLE);
break;
case Reply.STATUS_SENDING:
//break;
case Reply.STATUS_WILL_SENT:
msgSendingPb.setVisibility(View.VISIBLE);
msgErrorIv.setVisibility(View.GONE);
break;
case Reply.STATUS_SENT:
msgSendingPb.setVisibility(View.GONE);
msgErrorIv.setVisibility(View.GONE);
break;
default:
}
}
@Override
public int getDevReplyLayoutId() {
return R.layout.umeng_feedback_dev_reply;
}
/**
* 設定開發者的list item view
*/
@Override
public void setDevReplyView(View convertView, Reply reply) {
// 利用viewHolder進行了優化
TextView textMsgTv = ViewHolder.get(convertView, R.id.dev_textMsg_textView);
textMsgTv.setText(reply.content);
}
/**
* 如果兩條資訊間隔了TIME_RANGE秒,那麼就顯示上一條資訊的發送時間
*/
public static final int TIME_RANGE = 2 * 60;
@Override
public void onGetViewFromAdapter(View convertView, Reply reply, Reply nextReply) {
/* Log.d(TAG, "context_type = " + reply.content_type);
Log.d(TAG, "context = " + reply.content);
Log.d(TAG, "reply_id = " + reply.reply_id);*/
// 顯示消息的時間
if (nextReply != null) {
ViewStub timeView = ViewHolder.get(convertView, R.id.msg_time_viewStub);
// 當兩條回複相差TIME_RANGE秒時顯示時間
if (nextReply.created_at - reply.created_at > TIME_RANGE * 1000) {
timeView.setVisibility(View.VISIBLE);
TextView timeTv = ViewHolder.get(convertView, R.id.msg_Time_TextView);
Date replyTime = new Date(reply.created_at);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
timeTv.setText(sdf.format(replyTime));
} else {
timeView.setVisibility(View.GONE);
}
}
}
private int getPhotoSize(Context context) {
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
return metrics.widthPixels > metrics.heightPixels ? metrics.heightPixels : metrics.widthPixels;
}
@Override
public void finish() {
super.finish();
InputUtil.getInstance((Activity) mContext).hide();
}
}
源碼下載下傳:
http://download.csdn.net/detail/shark0017/8683945
最新源碼(推薦):http://download.csdn.net/detail/shark0017/8686989
BTW:源碼引用了kaleLibrary這個庫:https://github.com/tianzhijiexian/KaleLibrary/