package org.qii.weiciyuan.ui.adapter; import org.qii.weiciyuan.R; import org.qii.weiciyuan.bean.CommentBean; import org.qii.weiciyuan.bean.MessageBean; import org.qii.weiciyuan.bean.UserBean; import org.qii.weiciyuan.support.asyncdrawable.TimeLineBitmapDownloader; import org.qii.weiciyuan.support.lib.LongClickableLinkMovementMethod; import org.qii.weiciyuan.support.lib.MyURLSpan; import org.qii.weiciyuan.support.lib.TimeLineAvatarImageView; import org.qii.weiciyuan.support.lib.TimeTextView; import org.qii.weiciyuan.support.settinghelper.SettingUtility; import org.qii.weiciyuan.support.utils.GlobalContext; import org.qii.weiciyuan.support.utils.ThemeUtility; import org.qii.weiciyuan.support.utils.TimeLineUtility; import org.qii.weiciyuan.support.utils.Utility; import org.qii.weiciyuan.support.utils.ViewUtility; import org.qii.weiciyuan.ui.browser.BrowserWeiboMsgFragment; import org.qii.weiciyuan.ui.send.WriteReplyToCommentActivity; import org.qii.weiciyuan.ui.userinfo.UserInfoActivity; import android.app.Activity; import android.content.Intent; import android.graphics.drawable.Drawable; import android.support.v4.app.Fragment; import android.text.Layout; import android.text.SpannableString; import android.text.Spanned; import android.text.TextPaint; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import java.util.List; import java.util.Map; import java.util.WeakHashMap; /** * User: qii * Date: 13-6-16 */ public class BrowserWeiboMsgCommentAndRepostAdapter extends BaseAdapter { private boolean isCommentList = true; private List<CommentBean> commentListBean; private List<MessageBean> repostListBean; private Fragment fragment; private ListView listView; private int checkedBG; private int defaultBG; private LayoutInflater inflater; private Map<BrowserWeiboMsgCommentAndRepostAdapter.ViewHolder, Drawable> bg = new WeakHashMap<BrowserWeiboMsgCommentAndRepostAdapter.ViewHolder, Drawable>(); public BrowserWeiboMsgCommentAndRepostAdapter(Fragment fragment, ListView listView , List<CommentBean> commentListBean, List<MessageBean> repostListBean) { this.fragment = fragment; this.listView = listView; this.commentListBean = commentListBean; this.repostListBean = repostListBean; this.inflater = fragment.getActivity().getLayoutInflater(); this.defaultBG = fragment.getResources().getColor(R.color.transparent); this.checkedBG = ThemeUtility .getColor(fragment.getActivity(), R.attr.listview_checked_color); } protected Activity getActivity() { return fragment.getActivity(); } public void switchToRepostType() { this.isCommentList = false; notifyDataSetChanged(); } public void switchToCommentType() { this.isCommentList = true; notifyDataSetChanged(); } @Override public int getCount() { if (isCommentList) { return commentListBean.size(); } else { return repostListBean.size(); } } @Override public Object getItem(int position) { if (isCommentList) { return commentListBean.get(position); } else { return repostListBean.get(position); } } @Override public long getItemId(int position) { if (isCommentList) { return commentListBean.get(position).getIdLong(); } else { return repostListBean.get(position).getIdLong(); } } @Override public boolean hasStableIds() { return true; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null || convertView.getTag() == null) { convertView = initSimpleLayout(parent); holder = buildHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } configLayerType(holder); configViewFont(holder); bindViewData(holder, position); bindOnTouchListener(holder); return convertView; } public void bindViewData(ViewHolder holder, int position) { if (isCommentList) { bindCommentData(holder, position); } else { bindRepostData(holder, position); } } private void bindCommentData(ViewHolder holder, int position) { Drawable drawable = bg.get(holder); if (drawable != null) { holder.listview_root.setBackgroundDrawable(drawable); } else { drawable = holder.listview_root.getBackground(); bg.put(holder, drawable); } if (listView.getCheckedItemPosition() == position + listView.getHeaderViewsCount()) { holder.listview_root.setBackgroundColor(checkedBG); } final CommentBean comment = (CommentBean) getItem(position); UserBean user = comment.getUser(); if (user != null) { holder.username.setVisibility(View.VISIBLE); if (!TextUtils.isEmpty(user.getRemark())) { holder.username.setText(new StringBuilder(user.getScreen_name()).append("(") .append(user.getRemark()).append(")").toString()); } else { holder.username.setText(user.getScreen_name()); } if (!SettingUtility.getEnableCommentRepostListAvatar()) { holder.avatar.setLayoutParams(new RelativeLayout.LayoutParams(0, 0)); } else { buildAvatar(holder.avatar, position, user); } } else { holder.username.setVisibility(View.INVISIBLE); holder.avatar.setVisibility(View.INVISIBLE); } holder.avatar.checkVerified(user); holder.content.setText(comment.getListViewSpannableString()); holder.time.setTime(comment.getMills()); holder.reply.setVisibility(View.VISIBLE); holder.reply.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getActivity(), WriteReplyToCommentActivity.class); intent.putExtra("token", GlobalContext.getInstance().getSpecialToken()); intent.putExtra("msg", comment); getActivity().startActivity(intent); } }); } private void bindRepostData(ViewHolder holder, int position) { Drawable drawable = bg.get(holder); if (drawable != null) { holder.listview_root.setBackgroundDrawable(drawable); } else { drawable = holder.listview_root.getBackground(); bg.put(holder, drawable); } if (listView.getCheckedItemPosition() == position + listView.getHeaderViewsCount()) { holder.listview_root.setBackgroundColor(checkedBG); } final MessageBean msg = (MessageBean) getItem(position); UserBean user = msg.getUser(); if (user != null) { holder.username.setVisibility(View.VISIBLE); if (!TextUtils.isEmpty(user.getRemark())) { holder.username.setText(new StringBuilder(user.getScreen_name()).append("(") .append(user.getRemark()).append(")").toString()); } else { holder.username.setText(user.getScreen_name()); } if (!SettingUtility.getEnableCommentRepostListAvatar()) { holder.avatar.setLayoutParams(new RelativeLayout.LayoutParams(0, 0)); } else { buildAvatar(holder.avatar, position, user); } } else { holder.username.setVisibility(View.INVISIBLE); holder.avatar.setVisibility(View.INVISIBLE); } if (!TextUtils.isEmpty(msg.getListViewSpannableString())) { holder.content.setText(msg.getListViewSpannableString()); } else { TimeLineUtility.addJustHighLightLinks(msg); holder.content.setText(msg.getListViewSpannableString()); } holder.avatar.checkVerified(user); holder.time.setTime(msg.getMills()); holder.reply.setVisibility(View.GONE); } private View initSimpleLayout(ViewGroup parent) { View convertView; convertView = inflater .inflate(R.layout.timeline_listview_item_simple_layout, parent, false); return convertView; } private void bindOnTouchListener(ViewHolder holder) { holder.listview_root.setClickable(false); holder.username.setClickable(false); holder.time.setClickable(false); holder.content.setClickable(false); if (holder.content != null) { holder.content.setOnTouchListener(onTouchListener); } } private ViewHolder buildHolder(View convertView) { ViewHolder holder = new ViewHolder(); holder.username = ViewUtility.findViewById(convertView, R.id.username); TextPaint tp = holder.username.getPaint(); tp.setFakeBoldText(true); holder.content = ViewUtility.findViewById(convertView, R.id.content); holder.time = ViewUtility.findViewById(convertView, R.id.time); holder.avatar = (TimeLineAvatarImageView) convertView.findViewById(R.id.avatar); holder.listview_root = ViewUtility.findViewById(convertView, R.id.listview_root); holder.reply = ViewUtility.findViewById(convertView, R.id.replyIV); return holder; } private void configLayerType(ViewHolder holder) { boolean disableHardAccelerated = SettingUtility.disableHardwareAccelerated(); if (!disableHardAccelerated) { return; } int currentWidgetLayerType = holder.username.getLayerType(); if (View.LAYER_TYPE_SOFTWARE != currentWidgetLayerType) { holder.username.setLayerType(View.LAYER_TYPE_SOFTWARE, null); if (holder.content != null) { holder.content.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } if (holder.time != null) { holder.time.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } } } private void configViewFont(ViewHolder holder) { int prefFontSizeSp = SettingUtility.getFontSize(); float currentWidgetTextSizePx; currentWidgetTextSizePx = holder.time.getTextSize(); if (Utility.sp2px(prefFontSizeSp - 3) != currentWidgetTextSizePx) { holder.time.setTextSize(prefFontSizeSp - 3); } currentWidgetTextSizePx = holder.content.getTextSize(); if (Utility.sp2px(prefFontSizeSp) != currentWidgetTextSizePx) { holder.content.setTextSize(prefFontSizeSp); holder.username.setTextSize(prefFontSizeSp); } } //onTouchListener has some strange problem, when user click link, holder.listview_root may also receive a MotionEvent.ACTION_DOWN event //the background then changed private View.OnTouchListener onTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { ViewHolder holder = getViewHolderByView(v); if (holder == null) { return false; } Layout layout = ((TextView) v).getLayout(); int x = (int) event.getX(); int y = (int) event.getY(); int offset = 0; if (layout != null) { int line = layout.getLineForVertical(y); offset = layout.getOffsetForHorizontal(line, x); } TextView tv = (TextView) v; SpannableString value = SpannableString.valueOf(tv.getText()); LongClickableLinkMovementMethod.getInstance().onTouchEvent(tv, value, event); switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: MyURLSpan[] urlSpans = value.getSpans(0, value.length(), MyURLSpan.class); boolean find = false; int findStart = 0; int findEnd = 0; for (MyURLSpan urlSpan : urlSpans) { int start = value.getSpanStart(urlSpan); int end = value.getSpanEnd(urlSpan); if (start <= offset && offset <= end) { find = true; findStart = start; findEnd = end; break; } } boolean hasActionMode = ((BrowserWeiboMsgFragment) fragment).hasActionMode(); boolean result = false; if (find && !hasActionMode) { result = true; } if (find && !result) { BackgroundColorSpan[] backgroundColorSpans = value .getSpans(0, value.length(), BackgroundColorSpan.class); for (BackgroundColorSpan urlSpan : backgroundColorSpans) { value.removeSpan(urlSpan); ((TextView) v).setText(value); } } if (result) { BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan( ThemeUtility.getColor(R.attr.link_pressed_background_color)); value.setSpan(backgroundColorSpan, findStart, findEnd, Spanned.SPAN_INCLUSIVE_INCLUSIVE); ((TextView) v).setText(value); } return result; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: LongClickableLinkMovementMethod.getInstance().removeLongClickCallback(); BackgroundColorSpan[] backgroundColorSpans = value .getSpans(0, value.length(), BackgroundColorSpan.class); for (BackgroundColorSpan urlSpan : backgroundColorSpans) { value.removeSpan(urlSpan); ((TextView) v).setText(value); } break; } return false; } }; //when view is recycled by listview, need to catch exception private ViewHolder getViewHolderByView(View view) { try { final int position = listView.getPositionForView(view); if (position == ListView.INVALID_POSITION) { return null; } return getViewHolderByView(position); } catch (NullPointerException e) { } return null; } private ViewHolder getViewHolderByView(int position) { int wantedPosition = position - listView.getHeaderViewsCount(); int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount(); int wantedChild = wantedPosition - firstPosition; if (wantedChild < 0 || wantedChild >= listView.getChildCount()) { return null; } View wantedView = listView.getChildAt(wantedChild); ViewHolder holder = (ViewHolder) wantedView.getTag(); return holder; } private static class ViewHolder { RelativeLayout listview_root; TextView username; TextView content; TimeTextView time; TimeLineAvatarImageView avatar; ImageView reply; } protected void buildAvatar(TimeLineAvatarImageView view, int position, final UserBean user) { view.setVisibility(View.VISIBLE); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getActivity(), UserInfoActivity.class); intent.putExtra("token", GlobalContext.getInstance().getSpecialToken()); intent.putExtra("user", user); getActivity().startActivity(intent); } }); view.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { UserDialog dialog = new UserDialog(user); dialog.show(fragment.getFragmentManager(), ""); return true; } }); view.checkVerified(user); buildAvatar(view.getImageView(), position, user); } protected void buildAvatar(ImageView view, int position, final UserBean user) { String image_url = user.getProfile_image_url(); if (!TextUtils.isEmpty(image_url)) { view.setVisibility(View.VISIBLE); TimeLineBitmapDownloader.getInstance().downloadAvatar(view, user, false); } else { view.setVisibility(View.GONE); } } public void removeCommentItem(final int postion) { if (postion >= 0 && postion < commentListBean.size()) { Animation anim = AnimationUtils.loadAnimation( fragment.getActivity(), R.anim.account_delete_slide_out_right ); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { commentListBean.remove(postion); BrowserWeiboMsgCommentAndRepostAdapter.this.notifyDataSetChanged(); } @Override public void onAnimationRepeat(Animation animation) { } }); int positonInListView = postion + 1; int start = listView.getFirstVisiblePosition(); int end = listView.getLastVisiblePosition(); if (positonInListView >= start && positonInListView <= end) { int positionInCurrentScreen = postion - start; listView.getChildAt(positionInCurrentScreen + 1).startAnimation(anim); } else { commentListBean.remove(postion); BrowserWeiboMsgCommentAndRepostAdapter.this.notifyDataSetChanged(); } } } }