package com.gh.gamecenter.adapter; import android.app.Activity; import android.content.Intent; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; import android.text.Html; import android.text.TextUtils; 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.CheckLoginUtils; import com.gh.common.util.CommentUtils; import com.gh.common.util.ConcernContentUtils; import com.gh.common.util.DataCollectionUtils; 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.NewsDetailActivity; import com.gh.gamecenter.PersonalHomeActivity; import com.gh.gamecenter.R; import com.gh.gamecenter.ShareCardActivity; 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.entity.ArticleCommentParent; 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 com.lightgame.utils.Utils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; import retrofit2.HttpException; /** * 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; private ConcernEntity mConcernEntity; private OnCommentCallBackListener mOnCommentCallBackListener; private RecyclerView mRecyclerView; private List mHotCommentList; private List mNormalCommentList; private String mEntrance; private boolean isOver; private boolean isLoading; private boolean isNetworkError; private boolean isRefreshPosition; private boolean isGetRvHeight = true; // 防止评论时弹出软键盘 影响RecyclerView高度 private int rvHeight; private int mPage; public MessageDetailAdapter(Activity context, OnCommentCallBackListener listener, RecyclerView messageDetailRv, ConcernEntity concernEntity, String entrance) { super(context); mRecyclerView = messageDetailRv; mEntrance = entrance; mOnCommentCallBackListener = listener; isOver = false; isLoading = false; isNetworkError = false; isRefreshPosition = true; mPage = 1; mHotCommentList = new ArrayList<>(); mNormalCommentList = new ArrayList<>(); mConcernEntity = concernEntity; if (mConcernEntity != null && mConcernEntity.getCommentnum() != 0) { addHotComment(); } else if (mConcernEntity != null) { isOver = true; notifyItemChanged(getItemCount() - 1); if (mOnCommentCallBackListener != null) { mOnCommentCallBackListener.onCommentCallback(null); } } } public void addHotComment() { RetrofitManager.getInstance(mContext).getApi().getHotComment(mConcernEntity.getId(), 10, 1) .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(); // 考虑到断网刷新问题 } @Override public void onFailure(HttpException e) { addNormalComment(); } }); } public void addNormalComment() { if (isLoading) { return; } isLoading = true; RetrofitManager.getInstance(mContext).getApi().getComment(mConcernEntity.getId(), 10, mPage, Utils.getTime(mContext)) .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(); mPage++; 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(R.string.comment_hot); } else { ((CommentHeadViewHolder) holder).commentHeadTitleTv.setText(R.string.comment_new); } } } @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.readNum.setText(String.valueOf(mConcernEntity.getViews())); } if (mConcernEntity.getCommentnum() > 999) { viewHolder.commentnum.setText(R.string.thousand); } else { viewHolder.commentnum.setText(String.valueOf(mConcernEntity.getCommentnum())); } 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, "+(消息详情)"), mContext.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(mContext, 34)); } ImageUtils.display(viewHolder.thumb, mConcernEntity.getGameIcon()); viewHolder.title.setText(mConcernEntity.getGameName()); NewsUtils.setNewsPublishOn(viewHolder.time, mConcernEntity.getTime()); viewHolder.share.setOnClickListener(v -> { if (mConcernEntity.getImg() != null && mConcernEntity.getImg().size() > 0) { ShareCardPicActivity.startShareCardPicActivity(mContext, mConcernEntity, mEntrance); } else { String shareContent; if (mConcernEntity.getBrief() != null) { shareContent = mConcernEntity.getBrief(); } else { shareContent = mConcernEntity.getContent(); } mContext.startActivity(ShareCardActivity.getIntent(mContext, mConcernEntity, shareContent)); } }); viewHolder.itemView.setOnClickListener(v -> { DataCollectionUtils.uploadClick(mContext, "详情", "消息详情", mConcernEntity.getTitle()); // 统计阅读量 statNewsViews(mConcernEntity.getId()); if (mConcernEntity.getLink() != null) { mContext.startActivity(WebActivity.getIntentByNews(mContext, mConcernEntity , StringUtils.buildString(mEntrance, "+(消息详情)"))); } else { Intent intent = new Intent(mContext, NewsDetailActivity.class); intent.putExtra(EntranceUtils.KEY_NEWSID, mConcernEntity.getId()); intent.putExtra(EntranceUtils.KEY_ENTRANCE, StringUtils.buildString(mEntrance, "+(消息详情)")); mContext.startActivity(intent); } }); viewHolder.comment.setOnClickListener(v -> { if (mOnCommentCallBackListener != null) { mOnCommentCallBackListener.onCommentCallback(null); } }); viewHolder.itemView.post(() -> { 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; } holder.commentContentTv.setText(commentEntity.getContent()); ArticleCommentParent parent = commentEntity.getParent(); if (parent != null && !TextUtils.isEmpty(parent.getUser().getName())) { holder.quoteContainer.setVisibility(View.VISIBLE); holder.quoteAuthorTv.setText(String.format("@%s", parent.getUser().getName())); String content; if (parent.getActive()) { content = parent.getComment(); } else { content = mContext.getString(R.string.comment_hide_hint); } holder.quoteContentTv.setText(content); } else { holder.quoteContainer.setVisibility(View.GONE); } CommentUtils.setCommentUserView(mContext, holder, commentEntity); CommentUtils.setCommentTime(holder.commentTimeTv, commentEntity.getTime()); final CommentEntity finalCommentEntity = commentEntity; final boolean finalIsHotComment = isHotComment; final int finalCommentPosition = commentPosition; holder.commentLikeIv.setOnClickListener(v -> CheckLoginUtils.checkLogin(mContext, "资讯文章详情-评论详情-点赞", () -> CommentUtils.postVote(mContext, finalCommentEntity, holder.commentLikeCountTv, holder.commentLikeIv, () -> { int index1 = (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(index1)); } modifyVolleyCache(finalCommentEntity.getId(), cacheUrl); //修改缓存 }) )); holder.itemView.setOnClickListener(v -> CommentUtils.showReportDialog(finalCommentEntity, mContext, true, mOnCommentCallBackListener, null, "资讯文章详情-评论详情")); holder.commentUserNameTv.setOnClickListener(v -> PersonalHomeActivity.startTargetActivity(mContext, finalCommentEntity.getUser().getId(), mEntrance, "文章-评论详情")); holder.commentUserIconDv.setOnClickListener(v -> PersonalHomeActivity.startTargetActivity(mContext, finalCommentEntity.getUser().getId(), mEntrance, "文章-评论详情")); if (commentEntity.getPriority() != 0) { holder.commentBadge.setVisibility(View.VISIBLE); } else { holder.commentBadge.setVisibility(View.GONE); } } 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(R.string.comment_empty); } else { if (mNormalCommentList.size() > 10) { viewHolder.hint.setText(R.string.comment_nomore); } else { viewHolder.hint.setText(""); } viewHolder.loading.setVisibility(View.GONE); } viewHolder.itemView.setOnClickListener(v -> { if (isNetworkError) { isNetworkError = false; viewHolder.loading.setVisibility(View.VISIBLE); viewHolder.hint.setText(R.string.loading); addHotComment(); notifyDataSetChanged(); } }); } private void statNewsViews(final String news_id) { RetrofitManager.getInstance(mContext).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(mContext, 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(mContext, 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(mContext, 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(findTheLastPriorComment(), commentEntity); } public void addCommentCount() { mConcernEntity.setCommentnum(mConcernEntity.getCommentnum()); notifyDataSetChanged(); } public int findTheLastPriorComment() { int lastPriorityPosition = 0; for (int i = 0; i < mNormalCommentList.size(); i++) { if (mNormalCommentList.get(i).getPriority() != 0) { lastPriorityPosition = i + 1; } } return lastPriorityPosition; } 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; } }