/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2015 Umeng, Inc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.umeng.comm.ui.fragments;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.WindowManager;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import com.umeng.comm.core.beans.CommUser;
import com.umeng.comm.core.beans.Comment;
import com.umeng.comm.core.beans.FeedItem;
import com.umeng.comm.core.constants.Constants;
import com.umeng.comm.core.utils.ResFinder;
import com.umeng.comm.core.utils.ResFinder.ResType;
import com.umeng.comm.core.utils.ToastMsg;
import com.umeng.comm.ui.emoji.EmojiBean;
import com.umeng.comm.ui.emoji.EmojiBorad;
import com.umeng.comm.ui.emoji.EmojiBorad.OnEmojiItemClickListener;
import com.umeng.comm.ui.mvpview.MvpCommentView;
import com.umeng.comm.ui.presenter.BaseFragmentPresenter;
import com.umeng.comm.ui.presenter.impl.CommentPresenter;
import com.umeng.comm.ui.widgets.CommentEditText;
import com.umeng.comm.ui.widgets.CommentEditText.EditTextBackEventListener;
/**
* 含有评论发布页面的Fragment基类
*
* @param <T> 数据类型
* @param <P> Presenter类型
*/
public abstract class CommentEditFragment<T, P extends BaseFragmentPresenter<T>> extends
BaseFragment<T, P> implements MvpCommentView {
/**
* 评论布局的根视图
*/
protected View mCommentLayout;
/**
* 评论内容编辑框
*/
protected CommentEditText mCommentEditText;
/**
* 发送按钮
*/
private View mCommentSendView;
/**
* 输入法
*/
protected InputMethodManager mInputMgr;
/**
* 当前的Feed
*/
protected FeedItem mFeedItem;
/**
* 评论的Presenter
*/
protected CommentPresenter mCommentPresenter;
/**
* emoji表情触发按钮
*/
protected ImageView mEmojiImageView;
/**
* 对某人进行回复。用在评论的时候显示在EditText中
*/
protected CommUser mReplyUser;
/** 对某条评论进行回复 */
protected String mReplyCommentId = "";
/**
* emoji表情面板
*/
private EmojiBorad mEmojiBoard;
private int totalTime = 0;
private boolean isFinish = false;
private int mKeyboardIconRes;
private int mEmojiIconRes;
private BaseInputConnection mInputConnection = null;
@Override
protected void initWidgets() {
mCommentLayout = mViewFinder.findViewById(ResFinder
.getId("umeng_comm_comment_edit_layout"));
mCommentLayout.setClickable(true);
mCommentEditText = mViewFinder.findViewById(ResFinder
.getId("umeng_comm_comment_edittext"));
mCommentEditText.setEditTextBackListener(new EditTextBackEventListener() {
@Override
public boolean onClickBack() {
hideCommentLayout();
mEmojiBoard.setVisibility(View.GONE);
return true;
}
});
// 点击评论编辑框时,此时将弹出软键盘,需要隐藏掉表情面板
mCommentEditText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mEmojiBoard.setVisibility(View.GONE);
}
});
mInputConnection = new BaseInputConnection(mCommentEditText, true);
mCommentSendView = mViewFinder.findViewById(ResFinder
.getId("umeng_comm_comment_send_button"));
mCommentSendView.setClickable(true);
mCommentSendView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final String content = mCommentEditText.getText().toString();
if (!checkCommentData(content)) {
return;
}
hideCommentLayout();
postComment(content);
}
});
mEmojiImageView = mViewFinder.findViewById(ResFinder.getId("umeng_comm_emoji"));
mEmojiBoard = mViewFinder.findViewById(ResFinder.getId("umeng_comm_emojiview"));
mKeyboardIconRes = ResFinder.getResourceId(ResType.DRAWABLE, "umeng_comm_emoji_keyboard");
mEmojiIconRes = ResFinder.getResourceId(ResType.DRAWABLE, "umeng_comm_emoji");
// click emoji ImageView to show emoji board
mEmojiImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mEmojiBoard.getVisibility() == View.VISIBLE) { // 显示输入法,隐藏表情board
mEmojiBoard.setVisibility(View.GONE);
mEmojiImageView.setImageResource(mEmojiIconRes);
getActivity().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
sendInputMethodMessage(Constants.INPUT_METHOD_SHOW, mCommentEditText);
} else { // 隐藏输入法,显示表情board
mEmojiImageView.setImageResource(mKeyboardIconRes);
sendInputMethodMessage(Constants.INPUT_METHOD_DISAPPEAR, mCommentEditText);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mEmojiBoard.setVisibility(View.VISIBLE);
}
}, 80);
}
}
});
// 点击表情的某一项的回调函数
mEmojiBoard.setOnEmojiItemClickListener(new OnEmojiItemClickListener() {
@Override
public void onItemClick(EmojiBean emojiBean) {
// delete event
if (EmojiBorad.DELETE_KEY.equals(emojiBean.getEmoji())) {
// 对于删除事件,此时模拟一个输入法上的删除事件达到删除的效果
//【注意:此处不能调用delete方法,原因是emoji有些是单字符,有的是双字符】
mInputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_DEL));
return;
}
// 预判断,如果插入超过140字符,则不显示最新的表情
int emojiLen = emojiBean.isDouble ? 2: 1;
if ( mCommentEditText.getText().length()+emojiLen > Constants.COMMENT_CHARS ) {
ToastMsg.showShortMsgByResName("umeng_comm_comment_text_max");
return ;
}
int start = mCommentEditText.getSelectionStart();
int end = mCommentEditText.getSelectionEnd();
if (start < 0) {
mCommentEditText.append(emojiBean.getEmoji());
} else {
mCommentEditText.getText().replace(Math.min(start, end), Math.max(start, end),
emojiBean.getEmoji(), 0, emojiBean.getEmoji().length());
}
}
});
// 此时如果点击其它区域,需要隐藏表情面板
mCommentEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
mEmojiBoard.setVisibility(View.GONE);
}
}
});
mInputMgr = (InputMethodManager) getActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
}
/**
* 该Handler主要处理软键盘的弹出跟隐藏
*/
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
View view = (View) msg.obj;
// 显示软键盘
if (msg.what == Constants.INPUT_METHOD_SHOW) {
boolean result = mInputMgr.showSoftInput(view, 0);
if (!result && totalTime < Constants.LIMIT_TIME) {
totalTime += Constants.IDLE;
Message message = Message.obtain(msg);
mHandler.sendMessageDelayed(message, Constants.IDLE);
} else if (!isFinish) {
totalTime = 0;
result = view.requestFocus();
isFinish = true;
}
} else if (msg.what == Constants.INPUT_METHOD_DISAPPEAR) {
// 隐藏软键盘
mInputMgr.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
};
/**
* 发送show or hide输入法消息</br>
*
* @param type
* @param view
*/
protected void sendInputMethodMessage(int type, View view) {
Message message = mHandler.obtainMessage(type);
message.obj = view;
mHandler.sendMessage(message);
}
@Override
protected P createPresenters() {
// 初始化评论相关的Presenter
mCommentPresenter = new CommentPresenter(this, mFeedItem);
mCommentPresenter.attach(getActivity());
return null;
}
protected void postComment(String text) {
if (mCommentPresenter == null) {
mCommentPresenter = new CommentPresenter(this, mFeedItem);
mCommentPresenter.attach(getActivity());
}
mCommentPresenter.postComment(text, mReplyUser, mReplyCommentId);
}
protected void showCommentLayout() {
mCommentLayout.setVisibility(View.VISIBLE);
mCommentLayout.setClickable(true);
mCommentEditText.requestFocus();
mCommentEditText.postDelayed(new Runnable() {
@Override
public void run() {
mInputMgr.showSoftInput(mCommentEditText, 0);
}
}, 30);
}
@Override
public void showCommentLayout(int realPosition, Comment comment) {
showCommentLayout();
}
protected void hideCommentLayout() {
mCommentLayout.setVisibility(View.GONE);
mEmojiBoard.setVisibility(View.GONE);
getActivity().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
mInputMgr.hideSoftInputFromWindow(mCommentEditText.getWindowToken(), 0);
}
/**
* 检查评论是否有效。目前仅仅判空</br>
*
* @param content 评论的内容
* @return
*/
private boolean checkCommentData(String content) {
// 检查评论的内容是否合法
if (TextUtils.isEmpty(content)) {
ToastMsg.showShortMsgByResName("umeng_comm_content_invalid");
return false;
}
if (content.length() > 140) {
ToastMsg.showShortMsgByResName("umeng_comm_comment_text_overflow");
return false;
}
return true;
}
@Override
public void onDestroy() {
if (mCommentPresenter != null) {
mCommentPresenter.detach();
}
super.onDestroy();
}
@Override
public void postCommentSuccess(Comment comment, CommUser replyUser) {
}
@Override
public void loadMoreComment(List<Comment> comments) {
}
@Override
public void onRefreshEnd() {
}
@Override
public void onCommentDeleted(Comment comment) {
}
}