package net.oschina.app.ui;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import net.oschina.app.AppConfig;
import net.oschina.app.AppContext;
import net.oschina.app.AppException;
import net.oschina.app.R;
import net.oschina.app.adapter.GridViewFaceAdapter;
import net.oschina.app.adapter.ListViewCommentAdapter;
import net.oschina.app.bean.Comment;
import net.oschina.app.bean.CommentList;
import net.oschina.app.bean.Notice;
import net.oschina.app.bean.Result;
import net.oschina.app.bean.Tweet;
import net.oschina.app.common.StringUtils;
import net.oschina.app.common.UIHelper;
import net.oschina.app.widget.PullToRefreshListView;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ViewSwitcher;
/**
* 动弹详情
* @author liux (http://my.oschina.net/liux)
* @version 1.0
* @created 2012-3-21
*/
public class TweetDetail extends BaseActivity {
private ImageView mBack;
private ImageView mRefresh;
private LinearLayout mLinearlayout;
private ProgressBar mProgressbar;
private PullToRefreshListView mLvComment;
private ListViewCommentAdapter lvCommentAdapter;
private List<Comment> lvCommentData = new ArrayList<Comment>();
private View lvComment_footer;
private TextView lvComment_foot_more;
private ProgressBar lvComment_foot_progress;
private Handler mCommentHandler;
private int lvSumData;
private View lvHeader;
private ImageView userface;
private TextView username;
private TextView date;
private TextView commentCount;
private WebView content;
private ImageView image;
private Handler mHandler;
private Tweet tweetDetail;
private int curId;
private int curCatalog;
private int curLvDataState;
private ViewSwitcher mFootViewSwitcher;
private ImageView mFootEditebox;
private EditText mFootEditer;
private Button mFootPubcomment;
private ProgressDialog mProgress;
private InputMethodManager imm;
private String tempCommentKey = AppConfig.TEMP_COMMENT;
private ImageView mFace;
private GridView mGridView;
private GridViewFaceAdapter mGVFaceAdapter;
private int _catalog;
private int _id;
private int _uid;
private String _content;
private int _isPostToMyZone;
private final static int DATA_LOAD_ING = 0x001;
private final static int DATA_LOAD_COMPLETE = 0x002;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tweet_detail);
//初始化视图控件
this.initView();
//初始化控件数据
this.initData();
//初始化表情视图
this.initGridView();
}
/**
* 头部加载展示
* @param type
* @param action 1-init 2-refresh
*/
private void headButtonSwitch(int type,int action) {
switch (type) {
case DATA_LOAD_ING:
if(action==1)mLinearlayout.setVisibility(View.GONE);
mProgressbar.setVisibility(View.VISIBLE);
mRefresh.setVisibility(View.GONE);
break;
case DATA_LOAD_COMPLETE:
mLinearlayout.setVisibility(View.VISIBLE);
mProgressbar.setVisibility(View.GONE);
mRefresh.setVisibility(View.VISIBLE);
break;
}
}
//初始化视图控件
private void initView()
{
curId = getIntent().getIntExtra("tweet_id", 0);
curCatalog = CommentList.CATALOG_TWEET;
if(curId > 0) tempCommentKey = AppConfig.TEMP_COMMENT + "_" + curCatalog + "_" + curId;
mBack = (ImageView)findViewById(R.id.tweet_detail_back);
mRefresh = (ImageView)findViewById(R.id.tweet_detail_refresh);
mLinearlayout = (LinearLayout)findViewById(R.id.tweet_detail_linearlayout);
mProgressbar = (ProgressBar)findViewById(R.id.tweet_detail_head_progress);
mFace = (ImageView)findViewById(R.id.tweet_detail_foot_face);
mBack.setOnClickListener(UIHelper.finish(this));
mRefresh.setOnClickListener(refreshClickListener);
mFace.setOnClickListener(facesClickListener);
imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
mFootViewSwitcher = (ViewSwitcher)findViewById(R.id.tweet_detail_foot_viewswitcher);
mFootPubcomment = (Button)findViewById(R.id.tweet_detail_foot_pubcomment);
mFootPubcomment.setOnClickListener(commentpubClickListener);
mFootEditebox = (ImageView)findViewById(R.id.tweet_detail_footbar_editebox);
mFootEditebox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mFootViewSwitcher.showNext();
mFootEditer.setVisibility(View.VISIBLE);
mFootEditer.requestFocus();
mFootEditer.requestFocusFromTouch();
imm.showSoftInput(mFootEditer, 0);//显示软键盘
}
});
mFootEditer = (EditText)findViewById(R.id.tweet_detail_foot_editer);
mFootEditer.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//显示软键盘&隐藏表情
showIMM();
}
});
mFootEditer.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if(mFootViewSwitcher.getDisplayedChild()==1){
mFootViewSwitcher.setDisplayedChild(0);
mFootEditer.clearFocus();//隐藏软键盘
mFootEditer.setVisibility(View.GONE);//隐藏编辑框
hideFace();//隐藏表情
}
return true;
}
return false;
}
});
//编辑器添加文本监听
mFootEditer.addTextChangedListener(UIHelper.getTextWatcher(this, tempCommentKey));
//显示临时编辑内容
UIHelper.showTempEditContent(this, mFootEditer, tempCommentKey);
lvHeader = View.inflate(this, R.layout.tweet_detail_content, null);
userface = (ImageView)lvHeader.findViewById(R.id.tweet_listitem_userface);
username = (TextView)lvHeader.findViewById(R.id.tweet_listitem_username);
date = (TextView)lvHeader.findViewById(R.id.tweet_listitem_date);
commentCount = (TextView)lvHeader.findViewById(R.id.tweet_listitem_commentCount);
image = (ImageView)lvHeader.findViewById(R.id.tweet_listitem_image);
content = (WebView)lvHeader.findViewById(R.id.tweet_listitem_content);
content.getSettings().setJavaScriptEnabled(false);
content.getSettings().setSupportZoom(true);
content.getSettings().setBuiltInZoomControls(true);
content.getSettings().setDefaultFontSize(12);
lvComment_footer = getLayoutInflater().inflate(R.layout.listview_footer, null);
lvComment_foot_more = (TextView)lvComment_footer.findViewById(R.id.listview_foot_more);
lvComment_foot_progress = (ProgressBar)lvComment_footer.findViewById(R.id.listview_foot_progress);
lvCommentAdapter = new ListViewCommentAdapter(this, lvCommentData, R.layout.comment_listitem);
mLvComment = (PullToRefreshListView)findViewById(R.id.tweet_detail_commentlist);
mLvComment.addHeaderView(lvHeader);//把动弹详情放进listview头部
mLvComment.addFooterView(lvComment_footer);//添加底部视图 必须在setAdapter前
mLvComment.setAdapter(lvCommentAdapter);
mLvComment.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//点击头部、底部栏无效
if(position == 0 || view == lvComment_footer || position == 1 || view == lvHeader) return;
Comment com = null;
//判断是否是TextView
if(view instanceof TextView){
com = (Comment)view.getTag();
}else{
ImageView img = (ImageView)view.findViewById(R.id.comment_listitem_userface);
com = (Comment)img.getTag();
}
if(com == null) return;
//跳转--回复评论界面
UIHelper.showCommentReply(TweetDetail.this,curId, curCatalog, com.getId(), com.getAuthorId(), com.getAuthor(), com.getContent());
}
});
mLvComment.setOnScrollListener(new AbsListView.OnScrollListener() {
public void onScrollStateChanged(AbsListView view, int scrollState) {
mLvComment.onScrollStateChanged(view, scrollState);
//数据为空--不用继续下面代码了
if(lvCommentData.size() == 0) return;
//判断是否滚动到底部
boolean scrollEnd = false;
try {
if(view.getPositionForView(lvComment_footer) == view.getLastVisiblePosition())
scrollEnd = true;
} catch (Exception e) {
scrollEnd = false;
}
if(scrollEnd && curLvDataState==UIHelper.LISTVIEW_DATA_MORE)
{
mLvComment.setTag(UIHelper.LISTVIEW_DATA_LOADING);
lvComment_foot_more.setText(R.string.load_ing);
lvComment_foot_progress.setVisibility(View.VISIBLE);
//当前pageIndex
int pageIndex = lvSumData/20;
loadLvCommentData(curId, curCatalog, pageIndex, mCommentHandler, UIHelper.LISTVIEW_ACTION_SCROLL);
}
}
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
mLvComment.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
});
mLvComment.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//点击头部、底部栏无效
if(position == 0 || view == lvComment_footer || position == 1 || view == lvHeader) return false;
Comment _com = null;
//判断是否是TextView
if(view instanceof TextView){
_com = (Comment)view.getTag();
}else{
ImageView img = (ImageView)view.findViewById(R.id.comment_listitem_userface);
_com = (Comment)img.getTag();
}
if(_com == null) return false;
final Comment com = _com;
final AppContext ac = (AppContext)getApplication();
//操作--回复 & 删除
int uid = ac.getLoginUid();
//判断该评论是否是当前登录用户发表的:true--有删除操作 false--没有删除操作
if(uid == com.getAuthorId())
{
final Handler handler = new Handler(){
public void handleMessage(Message msg) {
if(msg.what == 1){
Result res = (Result)msg.obj;
if(res.OK()){
lvSumData--;
lvCommentData.remove(com);
lvCommentAdapter.notifyDataSetChanged();
}
UIHelper.ToastMessage(TweetDetail.this, res.getErrorMessage());
}else{
((AppException)msg.obj).makeToast(TweetDetail.this);
}
}
};
final Thread thread = new Thread(){
public void run() {
Message msg = new Message();
try {
Result res = ac.delComment(curId, curCatalog, com.getId(), com.getAuthorId());
msg.what = 1;
msg.obj = res;
} catch (AppException e) {
e.printStackTrace();
msg.what = -1;
msg.obj = e;
}
handler.sendMessage(msg);
}
};
UIHelper.showCommentOptionDialog(TweetDetail.this, curId, curCatalog, com, thread);
}
else
{
UIHelper.showCommentOptionDialog(TweetDetail.this, curId, curCatalog, com, null);
}
return true;
}
});
mLvComment.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener() {
public void onRefresh() {
loadLvCommentData(curId, curCatalog, 0, mCommentHandler, UIHelper.LISTVIEW_ACTION_REFRESH);
}
});
}
//初始化控件数据
private void initData()
{
//加载动弹
mHandler = new Handler(){
public void handleMessage(Message msg) {
headButtonSwitch(DATA_LOAD_COMPLETE,1);
if(msg.what == 1){
username.setText(tweetDetail.getAuthor());
username.setOnClickListener(faceClickListener);
date.setText(StringUtils.friendly_time(tweetDetail.getPubDate()));
commentCount.setText(tweetDetail.getCommentCount()+"");
String body = UIHelper.WEB_STYLE + tweetDetail.getBody();
body = body.replaceAll("(<img[^>]*?)\\s+width\\s*=\\s*\\S+","$1");
body = body.replaceAll("(<img[^>]*?)\\s+height\\s*=\\s*\\S+","$1");
content.loadDataWithBaseURL(null, body, "text/html", "utf-8",null);
content.setWebViewClient(UIHelper.getWebViewClient());
//加载用户头像
String faceURL = tweetDetail.getFace();
if(faceURL.endsWith("portrait.gif") || StringUtils.isEmpty(faceURL)) {
userface.setImageResource(R.drawable.widget_dface);
}else{
UIHelper.showUserFace(userface, faceURL);
}
userface.setOnClickListener(faceClickListener);
//加载图片
String imgSmall = tweetDetail.getImgSmall();
if(!StringUtils.isEmpty(imgSmall)) {
UIHelper.showLoadImage(image, imgSmall, null);
image.setVisibility(View.VISIBLE);
image.setOnClickListener(imageClickListener);
}
//发送通知广播
if(msg.obj != null){
UIHelper.sendBroadCast(TweetDetail.this, (Notice)msg.obj);
}
}else if(msg.what == 0){
UIHelper.ToastMessage(TweetDetail.this, R.string.msg_load_is_null);
}else{
((AppException)msg.obj).makeToast(TweetDetail.this);
}
}
};
this.loadTweetDetail(curId, mHandler, false);
//加载评论
mCommentHandler = new Handler()
{
public void handleMessage(Message msg) {
headButtonSwitch(DATA_LOAD_COMPLETE,2);
if(msg.what >= 0){
CommentList list = (CommentList)msg.obj;
Notice notice = list.getNotice();
//处理listview数据
switch (msg.arg1) {
case UIHelper.LISTVIEW_ACTION_INIT:
case UIHelper.LISTVIEW_ACTION_REFRESH:
lvSumData = msg.what;
lvCommentData.clear();//先清除原有数据
lvCommentData.addAll(list.getCommentlist());
break;
case UIHelper.LISTVIEW_ACTION_SCROLL:
lvSumData += msg.what;
if(lvCommentData.size() > 0){
for(Comment com1 : list.getCommentlist()){
boolean b = false;
for(Comment com2 : lvCommentData){
if(com1.getId() == com2.getId() && com1.getAuthorId() == com2.getAuthorId()){
b = true;
break;
}
}
if(!b) lvCommentData.add(com1);
}
}else{
lvCommentData.addAll(list.getCommentlist());
}
break;
}
if(msg.what < 20){
curLvDataState = UIHelper.LISTVIEW_DATA_FULL;
lvCommentAdapter.notifyDataSetChanged();
lvComment_foot_more.setText(R.string.load_full);
}else if(msg.what == 20){
curLvDataState = UIHelper.LISTVIEW_DATA_MORE;
lvCommentAdapter.notifyDataSetChanged();
lvComment_foot_more.setText(R.string.load_more);
}
//发送通知广播
if(notice != null){
UIHelper.sendBroadCast(TweetDetail.this, notice);
}
}
else if(msg.what == -1){
//有异常--也显示更多 & 弹出错误消息
curLvDataState = UIHelper.LISTVIEW_DATA_MORE;
lvComment_foot_more.setText(R.string.load_more);
((AppException)msg.obj).makeToast(TweetDetail.this);
}
if(lvCommentData.size()==0){
curLvDataState = UIHelper.LISTVIEW_DATA_EMPTY;
lvComment_foot_more.setText(R.string.load_empty);
}
lvComment_foot_progress.setVisibility(View.GONE);
if(msg.arg1 == UIHelper.LISTVIEW_ACTION_REFRESH)
mLvComment.onRefreshComplete(getString(R.string.pull_to_refresh_update) + new Date().toLocaleString());
}
};
this.loadLvCommentData(curId,curCatalog,0,mCommentHandler,UIHelper.LISTVIEW_ACTION_INIT);
}
/**
* 线程加载评论数据
* @param id 当前文章id
* @param catalog 分类
* @param pageIndex 当前页数
* @param handler 处理器
* @param action 动作标识
*/
private void loadLvCommentData(final int id,final int catalog,final int pageIndex,final Handler handler,final int action){
this.headButtonSwitch(DATA_LOAD_ING,2);
new Thread(){
public void run() {
Message msg = new Message();
boolean isRefresh = false;
if(action == UIHelper.LISTVIEW_ACTION_REFRESH || action == UIHelper.LISTVIEW_ACTION_SCROLL)
isRefresh = true;
try {
CommentList commentlist = ((AppContext)getApplication()).getCommentList(catalog, id, pageIndex, isRefresh);
msg.what = commentlist.getPageSize();
msg.obj = commentlist;
} catch (AppException e) {
e.printStackTrace();
msg.what = -1;
msg.obj = e;
}
msg.arg1 = action;//告知handler当前action
handler.sendMessage(msg);
}
}.start();
}
/**
* 线程加载动弹详情
* @param tweetId
* @param handler
*/
private void loadTweetDetail(final int tweetId, final Handler handler, final boolean isRefresh){
this.headButtonSwitch(DATA_LOAD_ING,1);
new Thread(){
public void run() {
Message msg = new Message();
try {
tweetDetail = ((AppContext)getApplication()).getTweet(tweetId, isRefresh);
msg.what = (tweetDetail!=null && tweetDetail.getId()>0) ? 1 : 0;
msg.obj = (tweetDetail!=null) ? tweetDetail.getNotice() : null;
} catch (AppException e) {
e.printStackTrace();
msg.what = -1;
msg.obj = e;
}
handler.sendMessage(msg);
}
}.start();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode != RESULT_OK) return;
if (data == null) return;
if (requestCode == UIHelper.REQUEST_CODE_FOR_RESULT)
{
Comment comm = (Comment)data.getSerializableExtra("COMMENT_SERIALIZABLE");
lvCommentData.add(0, comm);
lvCommentAdapter.notifyDataSetChanged();
mLvComment.setSelection(0);
}
}
//初始化表情控件
private void initGridView() {
mGVFaceAdapter = new GridViewFaceAdapter(this);
mGridView = (GridView)findViewById(R.id.tweet_detail_foot_faces);
mGridView.setAdapter(mGVFaceAdapter);
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//插入的表情
SpannableString ss = new SpannableString(view.getTag().toString());
Drawable d = getResources().getDrawable((int)mGVFaceAdapter.getItemId(position));
d.setBounds(0, 0, 35, 35);//设置表情图片的显示大小
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM);
ss.setSpan(span, 0, view.getTag().toString().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//在光标所在处插入表情
mFootEditer.getText().insert(mFootEditer.getSelectionStart(), ss);
}
});
}
private void showIMM() {
mFace.setTag(1);
showOrHideIMM();
}
private void showFace() {
mFace.setImageResource(R.drawable.widget_bar_keyboard);
mFace.setTag(1);
mGridView.setVisibility(View.VISIBLE);
}
private void hideFace() {
mFace.setImageResource(R.drawable.widget_bar_face);
mFace.setTag(null);
mGridView.setVisibility(View.GONE);
}
private void showOrHideIMM() {
if(mFace.getTag() == null){
//隐藏软键盘
imm.hideSoftInputFromWindow(mFootEditer.getWindowToken(), 0);
//显示表情
showFace();
}else{
//显示软键盘
imm.showSoftInput(mFootEditer, 0);
//隐藏表情
hideFace();
}
}
//表情控件点击事件
private View.OnClickListener facesClickListener = new View.OnClickListener() {
public void onClick(View v) {
showOrHideIMM();
}
};
private View.OnClickListener refreshClickListener = new View.OnClickListener() {
public void onClick(View v) {
loadTweetDetail(curId, mHandler, true);
loadLvCommentData(curId,curCatalog,0,mCommentHandler,UIHelper.LISTVIEW_ACTION_REFRESH);
}
};
private View.OnClickListener faceClickListener = new View.OnClickListener(){
public void onClick(View v) {
if(tweetDetail != null)
UIHelper.showUserCenter(v.getContext(), tweetDetail.getAuthorId(), tweetDetail.getAuthor());
}
};
private View.OnClickListener imageClickListener = new View.OnClickListener(){
public void onClick(View v) {
if(tweetDetail!=null)
UIHelper.showImageZoomDialog(v.getContext(), tweetDetail.getImgBig());
}
};
private View.OnClickListener commentpubClickListener = new View.OnClickListener() {
public void onClick(View v) {
_id = curId;
if(curId == 0){
return;
}
_catalog = curCatalog;
_content = mFootEditer.getText().toString();
if(StringUtils.isEmpty(_content)){
UIHelper.ToastMessage(v.getContext(), "请输入评论内容");
return;
}
final AppContext ac = (AppContext)getApplication();
if(!ac.isLogin()){
UIHelper.showLoginDialog(TweetDetail.this);
return;
}
// if(mZone.isChecked())
// _isPostToMyZone = 1;
_uid = ac.getLoginUid();
mProgress = ProgressDialog.show(v.getContext(), null, "发布中···",true,true);
final Handler handler = new Handler(){
public void handleMessage(Message msg) {
if(mProgress!=null)mProgress.dismiss();
if(msg.what == 1 && msg.obj != null){
Result res = (Result)msg.obj;
UIHelper.ToastMessage(TweetDetail.this, res.getErrorMessage());
if(res.OK()){
//发送通知广播
if(res.getNotice() != null){
UIHelper.sendBroadCast(TweetDetail.this, res.getNotice());
}
//恢复初始底部栏
mFootViewSwitcher.setDisplayedChild(0);
mFootEditer.clearFocus();
mFootEditer.setText("");
mFootEditer.setVisibility(View.GONE);
//隐藏软键盘
imm.hideSoftInputFromWindow(mFootEditer.getWindowToken(), 0);
//隐藏表情
hideFace();
//更新评论列表
lvCommentData.add(0, res.getComment());
lvCommentAdapter.notifyDataSetChanged();
mLvComment.setSelection(0);
//清除之前保存的编辑内容
ac.removeProperty(tempCommentKey);
}
}
else {
((AppException)msg.obj).makeToast(TweetDetail.this);
}
}
};
new Thread(){
public void run() {
Message msg = new Message();
Result res = new Result();
try {
//发表评论
res = ac.pubComment(_catalog, _id, _uid, _content, _isPostToMyZone);
msg.what = 1;
msg.obj = res;
} catch (AppException e) {
e.printStackTrace();
msg.what = -1;
msg.obj = e;
}
handler.sendMessage(msg);
}
}.start();
}
};
}