package com.gh.gamecenter.adapter; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; import android.text.Html; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import com.gh.common.constant.Config; import com.gh.common.util.CommentUtils; import com.gh.common.util.ConcernContentUtils; import com.gh.common.util.DataCollectionUtils; import com.gh.common.util.DataUtils; import com.gh.common.util.DisplayUtils; import com.gh.common.util.EntranceUtils; import com.gh.common.util.ImageUtils; import com.gh.common.util.NewsUtils; import com.gh.common.util.StringUtils; import com.gh.common.util.TimestampUtils; import com.gh.gamecenter.MessageDetailActivity; import com.gh.gamecenter.NewsDetailActivity; import com.gh.gamecenter.R; import com.gh.gamecenter.ShareCardPicActivity; import com.gh.gamecenter.WebActivity; import com.gh.gamecenter.adapter.viewholder.CommentHeadViewHolder; import com.gh.gamecenter.adapter.viewholder.CommentViewHolder; import com.gh.gamecenter.adapter.viewholder.FooterViewHolder; import com.gh.gamecenter.adapter.viewholder.NewsDigestViewHolder; import com.gh.gamecenter.db.CommentDao; import com.gh.gamecenter.db.VoteDao; import com.gh.gamecenter.entity.CommentEntity; import com.gh.gamecenter.entity.ConcernEntity; import com.gh.gamecenter.manager.VisitManager; import com.gh.gamecenter.retrofit.JSONObjectResponse; import com.gh.gamecenter.retrofit.OkHttpCache; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; import com.lightgame.adapter.BaseRecyclerAdapter; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import retrofit2.HttpException; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; /** * Created by khy on 2016/11/8. * 消息详情-数据适配器 */ public class MessageDetailAdapter extends BaseRecyclerAdapter { private static final int ITEM_TOP = 100; private static final int ITEM_TITLE = 101; private static final int ITEM_COMMENT = 102; private static final int ITEM_FOOTER = 103; boolean isGetRvHeight = true; // 防止评论时弹出软键盘 影响RecyclerView高度 int rvHeight; private ConcernEntity mConcernEntity; private OnCommentCallBackListener mOnCommentCallBackListener; private RecyclerView mRecyclerView; private List mHotCommentList; private List mNormalCommentList; private VoteDao mVoteDao; private CommentDao mCommentDao; private SharedPreferences sp; private String userName; //用户名 private String userIcon; //用户icon private String mEntrance; private boolean isOver; private boolean isLoading; private boolean isNetworkError; private boolean isRefreshPosition; public MessageDetailAdapter(MessageDetailActivity context, OnCommentCallBackListener listener, CommentDao commentDao, RecyclerView messageDetailRv, ConcernEntity concernEntity, String entrance) { super(context); mRecyclerView = messageDetailRv; mEntrance = entrance; mOnCommentCallBackListener = listener; mVoteDao = new VoteDao(context); mCommentDao = commentDao; sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); userName = sp.getString("user_name", null); userIcon = sp.getString("user_icon", null); isOver = false; isLoading = false; isNetworkError = false; isRefreshPosition = true; mHotCommentList = new ArrayList<>(); mNormalCommentList = new ArrayList<>(); mConcernEntity = concernEntity; if (mConcernEntity != null && mConcernEntity.getCommentnum() != 0) { addHotComment(0); } else if (mConcernEntity != null) { isOver = true; notifyItemChanged(getItemCount() - 1); if (mOnCommentCallBackListener != null) { mOnCommentCallBackListener.onCommentCallback(null); } } } public void addHotComment(int offset) { RetrofitManager.getComment().getHotComment(mConcernEntity.getId(), 10, offset) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response>() { @Override public void onResponse(List response) { if (response.size() != 0) { mHotCommentList.clear(); mHotCommentList.addAll(response); notifyDataSetChanged(); } addNormalComment(mNormalCommentList.size()); // 考虑到断网刷新问题 } @Override public void onFailure(HttpException e) { addNormalComment(mNormalCommentList.size()); } }); } public void addNormalComment(int offset) { if (isLoading) { return; } isLoading = true; RetrofitManager.getComment().getComment(mConcernEntity.getId(), 10, offset) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response>() { @Override public void onResponse(List response) { if (response.size() < 10) { isOver = true; } if (response.size() != 0) { mNormalCommentList.addAll(response); } notifyDataSetChanged(); isLoading = false; } @Override public void onFailure(HttpException e) { isLoading = false; isNetworkError = true; notifyDataSetChanged(); } }); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view; switch (viewType) { case ITEM_TOP: view = mLayoutInflater.inflate(R.layout.news_digest_item, parent, false); return new NewsDigestViewHolder(view); case ITEM_TITLE: view = mLayoutInflater.inflate(R.layout.comment_head_item, parent, false); return new CommentHeadViewHolder(view); case ITEM_COMMENT: view = mLayoutInflater.inflate(R.layout.comment_item, parent, false); return new CommentViewHolder(view); case ITEM_FOOTER: view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false); return new FooterViewHolder(view); default: return null; } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof NewsDigestViewHolder) { initNewsDigestViewHolder((NewsDigestViewHolder) holder); } else if (holder instanceof CommentViewHolder) { initCommentViewHolder((CommentViewHolder) holder, position); } else if (holder instanceof FooterViewHolder) { initFooterViewHolder((FooterViewHolder) holder); } else if (holder instanceof CommentHeadViewHolder) { if (mHotCommentList.size() != 0 && position == 1) { ((CommentHeadViewHolder) holder).commentHeadTitleTv.setText("热门评论"); } else { ((CommentHeadViewHolder) holder).commentHeadTitleTv.setText("最新评论"); } } } @Override public int getItemViewType(int position) { int index; if (mHotCommentList.size() == 0) { index = 1; } else { index = 2; } if (position == 0 && mConcernEntity != null) { return ITEM_TOP; } else if (mHotCommentList.size() != 0 && position == 1 || mNormalCommentList.size() != 0 && mHotCommentList.size() + index == position) { return ITEM_TITLE; } else if (getItemCount() == position + 1) { return ITEM_FOOTER; } return ITEM_COMMENT; } @Override public int getItemCount() { int itemCount = 0; if (mHotCommentList.size() != 0) { itemCount = itemCount + mHotCommentList.size() + 1; } if (mNormalCommentList.size() != 0) { itemCount = itemCount + mNormalCommentList.size() + 1; } if (mConcernEntity != null) { itemCount = itemCount + 1; } return itemCount + 1; } private void initNewsDigestViewHolder(final NewsDigestViewHolder viewHolder) { if (mConcernEntity.getViews() != 0) { viewHolder.read.setText(String.format(Locale.getDefault(), "阅读 %d", mConcernEntity.getViews())); } if (mConcernEntity.getCommentnum() != 0) { if (mConcernEntity.getCommentnum() > 999) { viewHolder.commentnum.setText(R.string.thousand); } else { viewHolder.commentnum.setText(String.valueOf(mConcernEntity.getCommentnum())); } } if (mConcernEntity.getLink() != null) { viewHolder.link.setImageResource(R.drawable.ic_link); } else { viewHolder.link.setImageResource(R.drawable.concern_message_icon); } if (mConcernEntity.getBrief() != null) { viewHolder.content.setText(Html.fromHtml(mConcernEntity.getBrief())); viewHolder.content.setMaxLines(100); } else { viewHolder.content.setText(Html.fromHtml(mConcernEntity.getContent())); viewHolder.content.setMaxLines(5); } if (mConcernEntity.getImg().size() == 0) { viewHolder.imgLayout.setVisibility(View.GONE); viewHolder.imgLayout.removeAllViews(); } else { viewHolder.imgLayout.setVisibility(View.VISIBLE); viewHolder.imgLayout.removeAllViews(); ConcernContentUtils.addContentPic(mContext, viewHolder.imgLayout, mConcernEntity.getImg(), StringUtils.buildString(mEntrance, "+(消息详情[", mConcernEntity.getGameName(), "])"), mContext.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(mContext, 34)); } // viewHolder.thumb.setImageURI(mConcernEntity.getGameIcon()); ImageUtils.display(viewHolder.thumb, mConcernEntity.getGameIcon()); viewHolder.title.setText(mConcernEntity.getGameName()); NewsUtils.setNewsPublishOn(viewHolder.time, mConcernEntity.getTime()); viewHolder.share.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ShareCardPicActivity.startShareCardPicActivity(mContext, mConcernEntity, mEntrance); } }); viewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Map kv = new HashMap<>(); kv.put("名字", mConcernEntity.getTitle()); DataUtils.onEvent(mContext, "点击", "消息详情", kv); DataCollectionUtils.uploadClick(mContext, "详情", "消息详情", mConcernEntity.getTitle()); // 统计阅读量 statNewsViews(mConcernEntity.getId()); if (mConcernEntity.getLink() != null) { Intent intent = new Intent(mContext, WebActivity.class); intent.putExtra("url", mConcernEntity.getLink()); intent.putExtra("gameName", mConcernEntity.getGameName()); intent.putExtra("newsId", mConcernEntity.getId()); intent.putExtra(EntranceUtils.KEY_ENTRANCE, StringUtils.buildString(mEntrance, "+(消息详情[", mConcernEntity.getGameName(), "])")); mContext.startActivity(intent); } else { Intent intent = new Intent(mContext, NewsDetailActivity.class); intent.putExtra("newsId", mConcernEntity.getId()); intent.putExtra(EntranceUtils.KEY_ENTRANCE, StringUtils.buildString(mEntrance, "+(消息详情[", mConcernEntity.getGameName(), "])")); mContext.startActivity(intent); } } }); viewHolder.comment.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mOnCommentCallBackListener != null) { mOnCommentCallBackListener.onCommentCallback(null); } } }); viewHolder.itemView.post(new Runnable() { @Override public void run() { if (isRefreshPosition) { Timer timer = new Timer(); // 延迟半秒,防止出现闪屏现象 timer.schedule(new TimerTask() { @Override public void run() { mRecyclerView.smoothScrollBy(0, viewHolder.itemView.getHeight()); //定位到评论顶部 } }, 300); isRefreshPosition = false; } } }); } private void initCommentViewHolder(final CommentViewHolder holder, int position) { int index; if (mHotCommentList.size() == 0) { index = 2; } else { index = 3; } int commentPosition = 0;// boolean isHotComment = false; //区分热门评论和最新评论 - 修改缓存链接 CommentEntity commentEntity = null; // 初始化数据 if (mHotCommentList.size() != 0 && mHotCommentList.size() > position - 2) { commentEntity = mHotCommentList.get(position - 2); isHotComment = true; } else if (mNormalCommentList.size() != 0 && mNormalCommentList.size() > position - mHotCommentList.size() - index) { commentPosition = position - mHotCommentList.size() - index; commentEntity = mNormalCommentList.get(position - mHotCommentList.size() - index); isHotComment = false; } if (commentEntity == null) { return; } if (commentEntity.getParent() != null) { holder.commentContentTv.setText(StringUtils.buildString("回复", commentEntity.getParent().getUser().getName(), ": ", commentEntity.getContent())); } else { holder.commentContentTv.setText(commentEntity.getContent()); } holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.hint)); holder.commentLikeIv.setImageResource(R.drawable.ic_like_unselect); if (commentEntity.getVote() == 0) { holder.commentLikeCountTv.setVisibility(View.GONE); } else { // 检查是否已点赞 if (mVoteDao.isVote(commentEntity.getId()) && commentEntity.getVote() >= 1) { holder.commentLikeCountTv.setTextColor(ContextCompat.getColor(mContext, R.color.theme)); holder.commentLikeIv.setImageResource(R.drawable.ic_like_select); } holder.commentLikeCountTv.setVisibility(View.VISIBLE); holder.commentLikeCountTv.setText(String.valueOf(commentEntity.getVote())); } //检查是否是自身评论 if (userName != null && userIcon != null && !userIcon.isEmpty() && !userIcon.isEmpty() && mCommentDao.isMyComment(commentEntity.getId())) { holder.commentUserNameTv.setText(sp.getString("user_name", null)); // holder.commentUserIconDv.setImageURI(sp.getString("user_icon", null)); ImageUtils.display(holder.commentUserIconDv, sp.getString("user_icon", null)); } else { holder.commentUserNameTv.setText(commentEntity.getUser().getName()); if (commentEntity.getUser().getIcon().isEmpty()) { holder.commentUserIconDv.setImageURI(Uri.parse("res:///" + R.drawable.user_default_icon_comment)); } else { // holder.commentUserIconDv.setImageURI(commentEntity.getUser().getIcon()); ImageUtils.display(holder.commentUserIconDv, commentEntity.getUser().getIcon()); } } CommentUtils.setCommentTime(holder.commentTimeTv, commentEntity.getTime()); final CommentEntity finalCommentEntity = commentEntity; final boolean finalIsHotComment = isHotComment; final int finalCommentPosition = commentPosition; holder.commentLikeIv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { CommentUtils.initVote(mContext, finalCommentEntity, mVoteDao, holder.commentLikeCountTv, holder.commentLikeIv, new CommentUtils.OnVoteListener() { @Override public void onVote() { int index = (finalCommentPosition / 10) * 10; //获取需要修改缓存的链接 String cacheUrl; if (finalIsHotComment) { cacheUrl = StringUtils.buildString(Config.COMMENT_HOST, "article/", mConcernEntity.getId(), "/comment?order=hot&limit=10", "&offset=0"); // 热门评论固定链接 } else { cacheUrl = StringUtils.buildString(Config.COMMENT_HOST, "article/", mConcernEntity.getId(), "/comment?limit=10&offset=", String.valueOf(index)); } modifyVolleyCache(finalCommentEntity.getId(), cacheUrl); //修改缓存 } }); } }); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { CommentUtils.showReportDialog(finalCommentEntity, mContext, mOnCommentCallBackListener, null); } }); } private void initFooterViewHolder(final FooterViewHolder viewHolder) { if (isGetRvHeight) { rvHeight = mRecyclerView.getHeight(); isGetRvHeight = false; } LinearLayout.LayoutParams params; int height = 0; if (mRecyclerView.getChildCount() != 1) { for (int i = 0; i < mRecyclerView.getChildCount(); i++) { if (i != 0 || mRecyclerView.getChildAt(0).getHeight() < 200) { height = height + mRecyclerView.getChildAt(i).getHeight(); } } } if (rvHeight - height < 100 || (mNormalCommentList.size() + mHotCommentList.size()) * 220 > rvHeight) { params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); ((LinearLayout) viewHolder.itemView).setGravity(Gravity.CENTER); } else { params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, rvHeight - height); ((LinearLayout) viewHolder.itemView).setGravity(Gravity.CENTER_HORIZONTAL); } viewHolder.itemView.setLayoutParams(params); if (isNetworkError) { viewHolder.loading.setVisibility(View.GONE); viewHolder.hint.setText(R.string.loading_error_network); } else if (!isOver) { viewHolder.hint.setText(R.string.loading); viewHolder.loading.setVisibility(View.VISIBLE); } else if (mNormalCommentList.size() == 0 && mHotCommentList.size() == 0) { viewHolder.loading.setVisibility(View.GONE); viewHolder.itemView.setLayoutParams(params); viewHolder.itemView.setPadding(0, DisplayUtils.dip2px(mContext, 30), 0, 0); viewHolder.hint.setText("目前还没有评论"); } else { if (mNormalCommentList.size() > 10) { viewHolder.hint.setText("没有更多评论啦"); } else { viewHolder.hint.setText(""); } viewHolder.loading.setVisibility(View.GONE); } viewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isNetworkError) { isNetworkError = false; viewHolder.loading.setVisibility(View.VISIBLE); viewHolder.hint.setText(R.string.loading); addHotComment(0); } } }); } private void statNewsViews(final String news_id) { RetrofitManager.getData().postNewsViews(news_id) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new JSONObjectResponse() { @Override public void onResponse(JSONObject response) { if (response.length() != 0) { try { if ("success".equals(response.getString("status"))) { mConcernEntity.setViews(mConcernEntity.getViews() + 1); notifyItemChanged(0); // 更新okhttp缓存数据 VisitManager.updateOkhttpCache(mConcernEntity.getId()); } } catch (JSONException e) { e.printStackTrace(); } } } }); } private void modifyVolleyCache(String id, String url) { if (url == null) { return; } url = TimestampUtils.addTimestamp(url); byte[] data = OkHttpCache.getCache(url); if (data != null) { try { JSONArray jsonArray = new JSONArray(new String(data)); JSONObject jsonObject; for (int i = 0, size = jsonArray.length(); i < size; i++) { jsonObject = jsonArray.getJSONObject(i); if (jsonObject.getString("_id").equals(id)) { jsonObject.put("vote", jsonObject.getInt("vote") + 1); break; } } OkHttpCache.updateCache(url, jsonArray.toString().getBytes()); } catch (JSONException e) { e.printStackTrace(); } } } public ConcernEntity getConcernEntity() { return mConcernEntity; } public boolean isLoading() { return isLoading; } // 往位置0添加评论 public void addNormalComment(CommentEntity commentEntity) { mNormalCommentList.add(0, commentEntity); } public void addCommentCount() { mConcernEntity.setCommentnum(mConcernEntity.getCommentnum() + 1); notifyItemChanged(0); } public int getHotCommentListSize() { int index = 0; if (mHotCommentList.size() != 0) { index = mHotCommentList.size() + 1; } return index; } public void addConcernEntity(ConcernEntity concernEntity) { this.mConcernEntity = concernEntity; } public boolean isOver() { return isOver; } }