feat : app/src/module_community
@@ -0,0 +1,10 @@
|
||||
package com.chwl.app.community;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/12
|
||||
*/
|
||||
public class ConstantValue {
|
||||
|
||||
public static final int CODE_CHOOSE_PHOTO = 12;
|
||||
|
||||
}
|
@@ -0,0 +1,166 @@
|
||||
package com.chwl.app.community.dynamic.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.UIHelper;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtils;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
|
||||
import com.chwl.app.utils.RegexUtil;
|
||||
import com.chwl.app.utils.TimeUiUtils;
|
||||
import com.chwl.app.vip.util.VipHelper;
|
||||
import com.chwl.core.community.bean.Comment;
|
||||
import com.chwl.library.utils.ListUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/26
|
||||
*/
|
||||
public class CommentAdapter extends BaseQuickAdapter<Comment, BaseViewHolder> {
|
||||
|
||||
|
||||
public CommentAdapter() {
|
||||
super(R.layout.item_dy_comment);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, Comment item) {
|
||||
ImageLoadUtils.loadAvatar( item.getAvatar(),helper.getView(R.id.iv_avatar));
|
||||
TextView tvNick = helper.getView(R.id.tv_nick);
|
||||
tvNick.setText(RegexUtil.getPrintableString(item.getNick()));
|
||||
VipHelper.loadVipIcon(helper.getView(R.id.iv_vip_icon), item.getUserVipInfoVO());
|
||||
int endIcon = 0;
|
||||
if (item.isLandLordFlag()) {
|
||||
endIcon = R.drawable.icon_dy_dynamic_publisher;
|
||||
}
|
||||
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, endIcon, 0);
|
||||
helper.setText(R.id.tv_content, item.getContent());
|
||||
|
||||
helper.getView(R.id.iv_avatar).setOnClickListener(v ->
|
||||
UIHelper.showUserInfoAct(mContext, item.getUid()));
|
||||
|
||||
helper.setText(R.id.tv_time, TimeUiUtils.getDynamicUi(item.getPublishTime()));
|
||||
|
||||
helper.addOnLongClickListener(R.id.tv_content);
|
||||
helper.addOnClickListener(R.id.tv_content);
|
||||
|
||||
|
||||
//===========================回复=========================
|
||||
RecyclerView rvReply = helper.getView(R.id.rv_reply);
|
||||
|
||||
View lineReplyBottom = helper.getView(R.id.line_reply_bottom);
|
||||
if (item.isEmptyReply()) {
|
||||
lineReplyBottom.setVisibility(View.GONE);
|
||||
} else {
|
||||
lineReplyBottom.setVisibility(View.VISIBLE);
|
||||
}
|
||||
CommentReplyAdapter commentReplyAdapter = new CommentReplyAdapter(item.getReplyInfo().getLeftCount() > 0);
|
||||
rvReply.setLayoutManager(new LinearLayoutManager(mContext));
|
||||
rvReply.setAdapter(commentReplyAdapter);
|
||||
|
||||
commentReplyAdapter.setNewData(item.getReplyList());
|
||||
|
||||
commentReplyAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
|
||||
@Override
|
||||
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
if (onCommentReplyItemChildClickListener != null) {
|
||||
onCommentReplyItemChildClickListener.onCommentReplyItemChildClick(view,
|
||||
helper.getAdapterPosition() - 1, position);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
commentReplyAdapter.setOnItemChildLongClickListener(new OnItemChildLongClickListener() {
|
||||
@Override
|
||||
public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
if (onCommentReplyItemChildClickListener != null) {
|
||||
onCommentReplyItemChildClickListener.onCommentReplyItemChildLongClick(view,
|
||||
helper.getAdapterPosition() - 1, position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
View mFooterView = LayoutInflater.from(mContext).inflate(R.layout.item_reply_footer_view, null);
|
||||
|
||||
if (item.getReplyInfo().getLeftCount() > 0) { //剩余回复大于0
|
||||
((TextView) mFooterView).setText(String.format(mContext.getResources().getString(R.string.dy_open_other_number),
|
||||
String.valueOf(item.getReplyInfo().getLeftCount())));
|
||||
commentReplyAdapter.addFooterView(mFooterView);
|
||||
} else {
|
||||
commentReplyAdapter.removeAllFooterView();
|
||||
}
|
||||
|
||||
mFooterView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
onCommentReplyItemChildClickListener.onLoadMoreClick(
|
||||
item.getCommentId(),
|
||||
item.getReplyInfo().getNextTimestamp(),
|
||||
helper.getLayoutPosition() - 1);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
private OnCommentReplyItemChildClickListener onCommentReplyItemChildClickListener;
|
||||
|
||||
public interface OnCommentReplyItemChildClickListener {
|
||||
|
||||
void onCommentReplyItemChildClick(View view, int groupPosition, int childPosition);
|
||||
|
||||
void onCommentReplyItemChildLongClick(View view, int groupPosition, int childPosition);
|
||||
|
||||
void onLoadMoreClick(long commentId, long nextReplyId, int groupPosition);
|
||||
|
||||
}
|
||||
|
||||
public void setOnCommentReplyItemChildClickListener(OnCommentReplyItemChildClickListener onCommentReplyItemChildClickListener) {
|
||||
this.onCommentReplyItemChildClickListener = onCommentReplyItemChildClickListener;
|
||||
}
|
||||
|
||||
public long getItemCommentId(int pos) {
|
||||
List<Comment> list = getData();
|
||||
if (ListUtils.isListEmpty(list)) {
|
||||
return 0;
|
||||
}
|
||||
if (pos >= 0 && pos < list.size()) {
|
||||
Comment comment = list.get(pos);
|
||||
if (comment != null) {
|
||||
return comment.getCommentId();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Comment getDataItem(int pos) {
|
||||
List<Comment> list = getData();
|
||||
if (ListUtils.isListEmpty(list)) {
|
||||
return null;
|
||||
}
|
||||
if (pos >= 0 && pos < list.size()) {
|
||||
return list.get(pos);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void safeDelete(int pos) {
|
||||
List<Comment> list = getData();
|
||||
if (pos >= 0 && pos < list.size()) {
|
||||
list.remove(pos);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
package com.chwl.app.community.dynamic.adapter;
|
||||
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.UIHelper;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtils;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
|
||||
import com.chwl.app.utils.RegexUtil;
|
||||
import com.chwl.app.utils.SpannableBuilder;
|
||||
import com.chwl.app.utils.TimeUiUtils;
|
||||
import com.chwl.app.vip.util.VipHelper;
|
||||
import com.chwl.core.community.bean.comment.Reply;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/27
|
||||
*/
|
||||
public class CommentReplyAdapter extends BaseQuickAdapter<Reply, BaseViewHolder> {
|
||||
|
||||
private boolean hasExpandFooter;
|
||||
|
||||
public CommentReplyAdapter(boolean hasExpandFooter) {
|
||||
super(R.layout.item_dy_reply);
|
||||
this.hasExpandFooter = hasExpandFooter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, Reply item) {
|
||||
|
||||
ImageLoadUtils.loadAvatar(item.getAvatar(),helper.getView(R.id.iv_avatar));
|
||||
TextView tvNick = helper.getView(R.id.tv_nick);
|
||||
tvNick.setText(RegexUtil.getPrintableString(item.getNick()));
|
||||
VipHelper.loadVipIcon(helper.getView(R.id.iv_vip_icon), item.getUserVipInfoVO());
|
||||
int endIcon = 0;
|
||||
if (item.isLandLordFlag()) {
|
||||
endIcon = R.drawable.icon_dy_dynamic_publisher;
|
||||
}
|
||||
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, endIcon, 0);
|
||||
|
||||
SpannableBuilder builder = new SpannableBuilder();
|
||||
builder.append("@" + item.getToNick(),
|
||||
new ForegroundColorSpan(mContext.getResources().getColor(R.color.color_7154EE)))
|
||||
.append(" " + item.getContent(),
|
||||
new ForegroundColorSpan(mContext.getResources().getColor(R.color.text_normal_c6c6e9)));
|
||||
|
||||
helper.setText(R.id.tv_content, builder.build());
|
||||
|
||||
helper.getView(R.id.iv_avatar).setOnClickListener(v ->
|
||||
UIHelper.showUserInfoAct(mContext, item.getUid()));
|
||||
|
||||
helper.setText(R.id.tv_time, TimeUiUtils.getDynamicUi(item.getPublishTime()));
|
||||
|
||||
helper.addOnClickListener(R.id.item_reply_constraintlayout)
|
||||
.addOnClickListener(R.id.tv_content);
|
||||
helper.addOnLongClickListener(R.id.tv_content);
|
||||
|
||||
View line = helper.getView(R.id.view_line_reply);
|
||||
if (hasExpandFooter) {
|
||||
line.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
//没有回复项的时候,最后一项的线隐藏
|
||||
if (helper.getAdapterPosition() == getData().size() - 1) {
|
||||
line.setVisibility(View.GONE);
|
||||
} else {
|
||||
line.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package com.chwl.app.community.helper;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2020/1/3
|
||||
*/
|
||||
@Keep
|
||||
public class CalcSize {
|
||||
|
||||
public CalcSize(int size) {
|
||||
width = size;
|
||||
height = size;
|
||||
}
|
||||
|
||||
public CalcSize() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
public int width;
|
||||
|
||||
public int height;
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package com.chwl.app.community.helper;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.chwl.app.avroom.widget.MessageView;
|
||||
import com.chwl.app.ui.widget.TextSpannableBuilder;
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/12/4
|
||||
*/
|
||||
public class DynamicUiHelper {
|
||||
|
||||
public static CharSequence formatFirstDynamicContent(WorldDynamicBean item, TextView textView,
|
||||
int iconWidth, int iconHeight) {
|
||||
TextSpannableBuilder builder = new TextSpannableBuilder(textView);
|
||||
// if (item.isFirstDynamic()) {
|
||||
// builder.append(textView.getResources().getDrawable(R.drawable.icon_dy_first_dynamic), iconWidth,
|
||||
// iconHeight);
|
||||
// }
|
||||
if (!TextUtils.isEmpty(item.getContent())) {
|
||||
builder.append(item.getContent());
|
||||
} else {
|
||||
builder.append(" ");
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
package com.chwl.app.community.helper;
|
||||
|
||||
import com.chwl.core.community.bean.DynamicMedia;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2020/1/3
|
||||
*/
|
||||
public class ImageUiHelper {
|
||||
/**
|
||||
* 图片最大宽度和父布局比例
|
||||
* 0.68
|
||||
*/
|
||||
public final static int BORDER_MIN = 68;
|
||||
/**
|
||||
* 图片最大宽度和父布局比例
|
||||
* 0.68
|
||||
*/
|
||||
public final static int BORDER_MAX = 100;
|
||||
|
||||
/**
|
||||
* 比例最大2.5,我们用分子分母来表示
|
||||
*/
|
||||
public final static int OFFSET_MIN = 2;
|
||||
|
||||
/**
|
||||
* 比例最大2.5,我们用分子分母来表示
|
||||
*/
|
||||
public final static int OFFSET_MAX = 5;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param width -
|
||||
* @param height -
|
||||
* @param border 图片展示的最大边界
|
||||
* @return -
|
||||
*/
|
||||
public static CalcSize calcImage(int width, int height, int border) {
|
||||
CalcSize calcSize = new CalcSize();
|
||||
int singleImageWidth = border; //单图宽
|
||||
int singleImageHeight = border; //单图高
|
||||
if (width >= height) {
|
||||
//横图的情况
|
||||
if (height * OFFSET_MAX <= width * OFFSET_MIN) {
|
||||
singleImageHeight = border * OFFSET_MIN / OFFSET_MAX;
|
||||
} else {
|
||||
if (width > 0) {
|
||||
singleImageHeight = border * height / width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//竖图的情况
|
||||
//判断比例是否超过2.5
|
||||
if (width * OFFSET_MAX <= height * OFFSET_MIN) {
|
||||
singleImageWidth = border * OFFSET_MIN / OFFSET_MAX;
|
||||
} else {
|
||||
if (height > 0) {
|
||||
singleImageWidth = border * width / height;
|
||||
}
|
||||
}
|
||||
}
|
||||
calcSize.width = singleImageWidth;
|
||||
calcSize.height = singleImageHeight;
|
||||
return calcSize;
|
||||
}
|
||||
|
||||
public static CalcSize calcImage(DynamicMedia media, int border) {
|
||||
if (media == null) {
|
||||
return new CalcSize();
|
||||
}
|
||||
return calcImage(media.getWidth(), media.getHeight(), border);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package com.chwl.app.community.helper;
|
||||
|
||||
import android.app.Activity;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
import com.chwl.library.utils.SingleToastUtil;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/28
|
||||
*/
|
||||
public class ShareDynamicHelper {
|
||||
|
||||
private Activity activity;
|
||||
|
||||
public ShareDynamicHelper(Activity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
public void share(WorldDynamicBean bean) {
|
||||
share(bean, bean.getWorldId());
|
||||
}
|
||||
|
||||
public void share(WorldDynamicBean bean, long worldId) {
|
||||
if (bean.isChecking()) {
|
||||
SingleToastUtil.showToast(ResUtil.getString(R.string.community_helper_sharedynamichelper_01));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,134 @@
|
||||
package com.chwl.app.community.holder;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.AbsoluteSizeSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.MetricAffectingSpan;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.chwl.core.msg.sys.bean.ErbanSysMsgComponent;
|
||||
import com.chwl.core.msg.sys.bean.ErbanSysMsgInfo;
|
||||
import com.chwl.library.utils.json.JsonUtils;
|
||||
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderBase;
|
||||
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.ui.im.RouterHandler;
|
||||
import com.chwl.core.community.attachment.DynamicSysAttachment;
|
||||
import com.chwl.core.msg.sys.ErbanSysMsgLayout;
|
||||
import com.chwl.library.utils.SizeUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Keep
|
||||
public class DynamicSysHolder extends MsgViewHolderBase {
|
||||
private TextView tvTime;
|
||||
private TextView tvContent;
|
||||
private TextView tvTitle;
|
||||
|
||||
public DynamicSysHolder(BaseMultiItemFetchLoadAdapter adapter) {
|
||||
super(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentResId() {
|
||||
return R.layout.item_dynamic_sys;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void inflateContentView() {
|
||||
tvTitle = findViewById(R.id.tv_notice_label);
|
||||
tvTime = findViewById(R.id.tv_time_dynamic_is_pass);
|
||||
tvContent = findViewById(R.id.tv_content_dynamic_is_pass);
|
||||
}
|
||||
|
||||
private ErbanSysMsgInfo erbanSysMsgInfo;
|
||||
@Override
|
||||
protected void bindContentView() {
|
||||
DynamicSysAttachment dynamicSysAttachment = (DynamicSysAttachment) message.getAttachment();
|
||||
if (dynamicSysAttachment == null) {
|
||||
return;
|
||||
}
|
||||
erbanSysMsgInfo = dynamicSysAttachment.getErbanSysMsgInfo();
|
||||
if (erbanSysMsgInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String layout = erbanSysMsgInfo.getLayout();
|
||||
ErbanSysMsgLayout erbanSysMsgLayout;
|
||||
try {
|
||||
erbanSysMsgLayout = JSON.parseObject(layout, ErbanSysMsgLayout.class);
|
||||
|
||||
} catch (Exception ex) { // json解析出错
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
// title
|
||||
setupView(tvTitle, erbanSysMsgLayout.getTitle());
|
||||
// timestamp
|
||||
setupView(tvTime, erbanSysMsgLayout.getTime());
|
||||
// content
|
||||
List<ErbanSysMsgComponent> erbanSysMsgLayoutContent = erbanSysMsgLayout.getContents();
|
||||
if (erbanSysMsgLayoutContent != null) {
|
||||
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
|
||||
for (ErbanSysMsgComponent erbanSysMsgComponent : erbanSysMsgLayoutContent) {
|
||||
int start = spannableStringBuilder.length();
|
||||
String msgBody = erbanSysMsgComponent.getContent();
|
||||
if (Objects.equals(msgBody, "/r/n")) {
|
||||
msgBody = "\r\n";
|
||||
spannableStringBuilder.append(msgBody);
|
||||
continue;
|
||||
}
|
||||
spannableStringBuilder.append(msgBody);
|
||||
if (erbanSysMsgComponent.getFontColor() != null) {
|
||||
spannableStringBuilder.setSpan(new ForegroundColorSpan(Color.parseColor(erbanSysMsgComponent.getFontColor())),
|
||||
start, spannableStringBuilder.length(),
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
if (erbanSysMsgComponent.getFontSize() > 0) {
|
||||
spannableStringBuilder.setSpan(new AbsoluteSizeSpan(SizeUtils.sp2px(tvContent.getContext(), erbanSysMsgComponent.getFontSize() + 0.5F)),
|
||||
start, spannableStringBuilder.length(),
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
spannableStringBuilder.setSpan(
|
||||
new MetricAffectingSpan() {
|
||||
@Override
|
||||
public void updateMeasureState(TextPaint p) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(TextPaint tp) {
|
||||
tp.setFakeBoldText(erbanSysMsgComponent.isFontBold());
|
||||
}
|
||||
},
|
||||
start, spannableStringBuilder.length(),
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
tvContent.setText(spannableStringBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setupView(TextView view, ErbanSysMsgComponent erbanSysMsgComponent) {
|
||||
if (erbanSysMsgComponent != null) {
|
||||
setupComponent(view, erbanSysMsgComponent.getContent(), erbanSysMsgComponent.getFontColor(), erbanSysMsgComponent.getFontSize(),
|
||||
erbanSysMsgComponent.getRouterType(), erbanSysMsgComponent.getRouterValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void setupComponent(TextView view, String text, String textColor, float fontSize, int routerType, int routerValue) {
|
||||
view.setText(text);
|
||||
view.setTextColor(Color.parseColor(textColor));
|
||||
view.setTextSize(fontSize);
|
||||
if (routerType > 0) {
|
||||
view.setOnClickListener(v -> RouterHandler.handle(context, routerType, String.valueOf(routerValue)));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
package com.chwl.app.community.im;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import com.chwl.app.ui.utils.ImageLoadUtils;
|
||||
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderBase;
|
||||
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.community.dynamic.view.DynamicDetailActivity;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
|
||||
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
|
||||
import com.chwl.core.community.im.DynamicImMsg;
|
||||
import com.chwl.core.community.im.WorldDynamicAttachment;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/25
|
||||
*/
|
||||
@Keep
|
||||
public class WorldDynamicShareViewHolder extends MsgViewHolderBase {
|
||||
|
||||
private ImageView rivCover;
|
||||
|
||||
private TextView tvTitle;
|
||||
|
||||
private TextView tvContent;
|
||||
|
||||
private TextView tvShareText;
|
||||
|
||||
private ViewGroup container;
|
||||
|
||||
public WorldDynamicShareViewHolder(BaseMultiItemFetchLoadAdapter adapter) {
|
||||
super(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentResId() {
|
||||
return R.layout.view_holder_world_dynamic_share;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void inflateContentView() {
|
||||
rivCover = findViewById(R.id.riv_cover);
|
||||
tvTitle = findViewById(R.id.tv_title);
|
||||
tvContent = findViewById(R.id.tv_content);
|
||||
tvShareText = findViewById(R.id.tv_share_text);
|
||||
container = findViewById(R.id.cl_container_dynamic);
|
||||
int layoutWidth = UIUtil.getScreenWidth(context) - UIUtil.dip2px(context, 150);
|
||||
ViewGroup.LayoutParams params = container.getLayoutParams();
|
||||
params.width = layoutWidth;
|
||||
container.setLayoutParams(params);
|
||||
if (isReceivedMessage()) {
|
||||
tvTitle.setTextColor(context.getResources().getColor(R.color.color_333333));
|
||||
tvShareText.setTextColor(context.getResources().getColor(R.color.color_333333));
|
||||
tvContent.setTextColor(context.getResources().getColor(R.color.color_9E9E9E));
|
||||
} else {
|
||||
tvTitle.setTextColor(context.getResources().getColor(R.color.white));
|
||||
tvShareText.setTextColor(context.getResources().getColor(R.color.white));
|
||||
tvContent.setTextColor(context.getResources().getColor(R.color.white_transparent_80));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindContentView() {
|
||||
try {
|
||||
if (!(message.getAttachment() instanceof WorldDynamicAttachment)) {
|
||||
return;
|
||||
}
|
||||
WorldDynamicAttachment worldDynamicAttachment = (WorldDynamicAttachment) message.getAttachment();
|
||||
if (worldDynamicAttachment == null) {
|
||||
return;
|
||||
}
|
||||
DynamicImMsg dynamicImMsg = worldDynamicAttachment.getDynamicImMsg();
|
||||
ImageLoadUtils.loadAvatar(dynamicImMsg.getImageUrl(),rivCover);
|
||||
|
||||
String nick = dynamicImMsg.getNick();
|
||||
if (TextUtils.isEmpty(nick)) {
|
||||
nick = "";
|
||||
} else if (nick.length() >= 4) {
|
||||
try {
|
||||
nick = nick.substring(0, 2) + "...";
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
tvTitle.setText(nick);
|
||||
String content = dynamicImMsg.getContent();
|
||||
if (TextUtils.isEmpty(dynamicImMsg.getContent())) {
|
||||
content = ResUtil.getString(R.string.community_im_worlddynamicshareviewholder_01);
|
||||
}
|
||||
tvContent.setText(content);
|
||||
container.setOnClickListener(v ->
|
||||
DynamicDetailActivity.start(context, dynamicImMsg.getDynamicId(), dynamicImMsg.getWorldId(), 3));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package com.chwl.app.community.publish;
|
||||
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.netease.nim.uikit.support.glide.GlideApp;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
|
||||
import com.chwl.core.community.bean.PublishItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ImageAdapter extends BaseQuickAdapter<PublishItem, BaseViewHolder> {
|
||||
|
||||
|
||||
public ImageAdapter(int layoutResId, @Nullable List<PublishItem> data) {
|
||||
super(layoutResId, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, PublishItem item) {
|
||||
helper.addOnClickListener(R.id.iv_delete);
|
||||
helper.setVisible(R.id.iv_delete, !item.isAddItem());
|
||||
ImageView ivPhoto = helper.getView(R.id.iv_photo);
|
||||
if (item.getButtonType() == PublishItem.BUTTON_TYPE_ADD_ITEM) {
|
||||
ivPhoto.setImageResource(R.drawable.icon_dy_add_image);
|
||||
} else {
|
||||
GlideApp.with(ivPhoto.getContext())
|
||||
.asBitmap()
|
||||
.load(item.getPath())
|
||||
.transform(new CenterCrop(),
|
||||
new RoundedCorners(UIUtil.dip2px(ivPhoto.getContext(), 8)))
|
||||
.placeholder(R.drawable.default_cover)
|
||||
.error(R.drawable.default_cover)
|
||||
.into(ivPhoto);
|
||||
}
|
||||
|
||||
helper.setGone(R.id.iv_gif_tag, item.getFileTag() == 1);
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,222 @@
|
||||
package com.chwl.app.community.publish.presenter;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.base.BaseMvpPresenter;
|
||||
import com.chwl.app.community.publish.view.IPublishView;
|
||||
import com.chwl.core.Constants;
|
||||
import com.chwl.core.auth.AuthModel;
|
||||
import com.chwl.core.community.ImageUploadConfig;
|
||||
import com.chwl.core.community.PublishModel;
|
||||
import com.chwl.core.community.bean.DynamicMedia;
|
||||
import com.chwl.core.community.bean.MiniWorldChooseInfo;
|
||||
import com.chwl.core.community.bean.PublishBody;
|
||||
import com.chwl.core.file.FileModel;
|
||||
import com.chwl.core.utils.DirectoryHelper;
|
||||
import com.chwl.core.utils.net.DontWarnObserver;
|
||||
import com.chwl.core.utils.net.RxHelper;
|
||||
import com.chwl.library.base.PresenterEvent;
|
||||
import com.chwl.library.utils.ListUtils;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
import com.chwl.library.utils.file.JXFileUtils;
|
||||
import com.chwl.library.utils.image.JXImageUtils;
|
||||
import com.example.matisse.internal.entity.CustomItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.SingleObserver;
|
||||
import io.reactivex.SingleOnSubscribe;
|
||||
import io.reactivex.SingleSource;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.functions.Function;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/12
|
||||
*/
|
||||
public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
|
||||
|
||||
private PublishBody publishBody;
|
||||
private Disposable mImageUploadSubscribe;
|
||||
|
||||
private boolean isOriginalImage;
|
||||
|
||||
private MiniWorldChooseInfo miniWorldChooseInfo = new MiniWorldChooseInfo();
|
||||
|
||||
public void publishDy(List<DynamicMedia> list, long worldId, String content, boolean isOriginalImage) {
|
||||
publishBody = new PublishBody();
|
||||
List<DynamicMedia> uploadList = new ArrayList<>(list);
|
||||
int type = ListUtils.isListEmpty(uploadList) ? 0 : 2;
|
||||
publishBody.setType(type);
|
||||
publishBody.setUid(AuthModel.get().getCurrentUid());
|
||||
publishBody.setContent(content);
|
||||
if (worldId > 0) {
|
||||
publishBody.setWorldId(worldId);
|
||||
}
|
||||
this.isOriginalImage = isOriginalImage;
|
||||
uploadImage(uploadList)
|
||||
.flatMap((Function<String, SingleSource<String>>) s ->
|
||||
PublishModel.get().publish(publishBody))
|
||||
.subscribe(new DontWarnObserver<String>() {
|
||||
@Override
|
||||
public void acceptThrowable(String s, Throwable throwable) {
|
||||
super.acceptThrowable(s, throwable);
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace();
|
||||
dealUploadFileError(throwable);
|
||||
} else {
|
||||
if (getMvpView() != null) {
|
||||
getMvpView().onPublishSuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Single<String> uploadImage(List<DynamicMedia> imagePaths) {
|
||||
upload(imagePaths);
|
||||
return Single.create(emitter ->
|
||||
mImageUploadSubscribe = Observable.interval(500, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.filter(aLong -> imagePaths != null && imagePaths.size() == 0)
|
||||
.subscribe(aLong -> {
|
||||
emitter.onSuccess("");
|
||||
if (mImageUploadSubscribe != null) {
|
||||
mImageUploadSubscribe.dispose();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void upload(List<DynamicMedia> imagePaths) {
|
||||
if (imagePaths == null || imagePaths.size() == 0) {
|
||||
return;
|
||||
}
|
||||
DynamicMedia item = imagePaths.get(0);
|
||||
String file = item.getLocalFilePath();
|
||||
Single.create((SingleOnSubscribe<String>) e -> {
|
||||
long fileLength = JXFileUtils.getFileLength(file);
|
||||
LogUtil.print(ResUtil.getString(R.string.publish_presenter_publishpresenter_01) + fileLength);
|
||||
String compressFile = null;
|
||||
if (!isOriginalImage && fileLength > ImageUploadConfig.MAX_FILE_SIZE) {
|
||||
JXImageUtils.CompressResult result = JXImageUtils.compressImagePxAndQuality(
|
||||
file, DirectoryHelper.get().getDynamicDir(),
|
||||
"dynamic_" + System.currentTimeMillis() + ".jpg",
|
||||
ImageUploadConfig.EXPECT_MIN_WIDTH,
|
||||
ImageUploadConfig.EXPECT_COMPRESS_SIZE);
|
||||
if (result != null) {
|
||||
compressFile = result.getPath();
|
||||
if (result.getWidth() > 0 && item.getWidth() != result.getWidth()) {
|
||||
item.setWidth(result.getWidth());
|
||||
}
|
||||
if (result.getHeight() > 0 && item.getHeight() != result.getHeight()) {
|
||||
item.setHeight(result.getHeight());
|
||||
}
|
||||
if (result.getFormat() != null) {
|
||||
item.setFormat(result.getFormat());
|
||||
}
|
||||
}
|
||||
LogUtil.print(ResUtil.getString(R.string.publish_presenter_publishpresenter_02) + compressFile);
|
||||
}
|
||||
if (!TextUtils.isEmpty(compressFile)) {
|
||||
e.onSuccess(compressFile);
|
||||
} else if (!TextUtils.isEmpty(file)) {
|
||||
e.onSuccess(file);
|
||||
} else {
|
||||
e.onError(new Throwable(ResUtil.getString(R.string.publish_presenter_publishpresenter_03)));
|
||||
}
|
||||
})
|
||||
.compose(RxHelper.handleSchedulers())
|
||||
.flatMap((Function<String, SingleSource<String>>)
|
||||
path -> FileModel.get().uploadFile(path))
|
||||
.compose(bindUntilEvent(PresenterEvent.DESTROY))
|
||||
.subscribe(new DontWarnObserver<String>() {
|
||||
@Override
|
||||
public void acceptThrowable(String url, Throwable throwable) {
|
||||
super.acceptThrowable(url, throwable);
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace();
|
||||
if (mImageUploadSubscribe != null) {
|
||||
mImageUploadSubscribe.dispose();
|
||||
}
|
||||
dealUploadFileError(throwable);
|
||||
} else {
|
||||
item.setResUrl(url);
|
||||
LogUtil.print(ResUtil.getString(R.string.publish_presenter_publishpresenter_04), item);
|
||||
publishBody.addDynamicMedia(item);
|
||||
imagePaths.remove(0);
|
||||
upload(imagePaths);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void recommendWorlds() {
|
||||
PublishModel.get().squareWorld(Constants.TYPE_RECOMMEND, 1, 5)
|
||||
.compose(bindToLifecycle()).subscribe(new SingleObserver<List<MiniWorldChooseInfo>>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(List<MiniWorldChooseInfo> miniWorldChooseInfos) {
|
||||
if (miniWorldChooseInfos != null) {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.recommendWorldsSuccess(miniWorldChooseInfos);
|
||||
}
|
||||
} else {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.recommendWorldsFails(ResUtil.getString(R.string.publish_presenter_publishpresenter_05));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.recommendWorldsFails(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void dealUploadFileError(Throwable e) {
|
||||
if (getMvpView() != null) {
|
||||
getMvpView().onPublishFailed(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setWorldId(long worldId) {
|
||||
if (miniWorldChooseInfo != null) {
|
||||
miniWorldChooseInfo.setWorldId(worldId);
|
||||
}
|
||||
}
|
||||
|
||||
public void setIsInWorld(boolean isInWorld) {
|
||||
if (miniWorldChooseInfo != null) {
|
||||
miniWorldChooseInfo.setInWorld(isInWorld);
|
||||
}
|
||||
}
|
||||
|
||||
public void setMiniWorldChooseInfo(MiniWorldChooseInfo miniWorldChooseInfo) {
|
||||
this.miniWorldChooseInfo = miniWorldChooseInfo;
|
||||
}
|
||||
|
||||
public long getWorldId() {
|
||||
return miniWorldChooseInfo != null ? miniWorldChooseInfo.getWorldId() : 0;
|
||||
}
|
||||
|
||||
public boolean isInWorld() {
|
||||
return miniWorldChooseInfo != null && miniWorldChooseInfo.isInWorld();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
package com.chwl.app.community.publish.presenter;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.base.BaseMvpPresenter;
|
||||
import com.chwl.app.community.publish.view.IWorldsChooseView;
|
||||
import com.chwl.core.Constants;
|
||||
import com.chwl.core.community.PublishModel;
|
||||
import com.chwl.core.community.bean.MiniWorldChooseInfo;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.SingleObserver;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
@Keep
|
||||
public class WorldChoosePresenter extends BaseMvpPresenter<IWorldsChooseView> {
|
||||
|
||||
private int page = 0;
|
||||
|
||||
public void loadData(boolean isRefresh, byte type) {
|
||||
if (isRefresh) {
|
||||
page = 1;
|
||||
} else {
|
||||
page++;
|
||||
}
|
||||
|
||||
PublishModel.get().squareWorld(type, page, Constants.PAGE_SIZE)
|
||||
.compose(bindToLifecycle()).subscribe(new SingleObserver<List<MiniWorldChooseInfo>>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(List<MiniWorldChooseInfo> miniWorldChooseInfos) {
|
||||
if (miniWorldChooseInfos != null) {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.squareWorldsSuccess(miniWorldChooseInfos);
|
||||
}
|
||||
} else {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.squareWorldsFails(ResUtil.getString(R.string.publish_presenter_worldchoosepresenter_01));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.squareWorldsFails(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.chwl.app.community.publish.view;
|
||||
|
||||
import com.chwl.core.community.bean.MiniWorldChooseInfo;
|
||||
import com.chwl.library.base.IMvpBaseView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/12
|
||||
*/
|
||||
public interface IPublishView extends IMvpBaseView {
|
||||
|
||||
void onPublishSuccess();
|
||||
|
||||
void onPublishFailed(Throwable throwable);
|
||||
|
||||
void recommendWorldsSuccess(List<MiniWorldChooseInfo> list);
|
||||
void recommendWorldsFails(String error);
|
||||
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package com.chwl.app.community.publish.view;
|
||||
|
||||
import com.chwl.core.community.bean.MiniWorldChooseInfo;
|
||||
import com.chwl.library.base.IMvpBaseView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IWorldsChooseView extends IMvpBaseView {
|
||||
void squareWorldsSuccess(List<MiniWorldChooseInfo> list);
|
||||
void squareWorldsFails(String error);
|
||||
}
|
@@ -0,0 +1,568 @@
|
||||
package com.chwl.app.community.publish.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.base.BaseMvpActivity;
|
||||
import com.chwl.app.base.PhotoPickActivity;
|
||||
import com.chwl.app.common.widget.dialog.DialogManager;
|
||||
import com.chwl.app.community.publish.ImageAdapter;
|
||||
import com.chwl.app.community.publish.presenter.PublishPresenter;
|
||||
import com.chwl.app.community.utils.ObjectTypeHelper;
|
||||
import com.chwl.app.photo.BigPhotoActivity;
|
||||
import com.chwl.app.photo.PagerOption;
|
||||
import com.chwl.app.ui.widget.recyclerview.decoration.GridSpacingItemDecoration;
|
||||
import com.chwl.core.Constants;
|
||||
import com.chwl.core.auth.AuthModel;
|
||||
import com.chwl.core.community.bean.MiniWorldChooseInfo;
|
||||
import com.chwl.core.community.bean.PublishItem;
|
||||
import com.chwl.core.miniworld.model.MiniWorldModel;
|
||||
import com.chwl.core.user.UserModel;
|
||||
import com.chwl.core.user.bean.UserInfo;
|
||||
import com.chwl.core.utils.CoreTextUtils;
|
||||
import com.chwl.core.utils.myutil.MyUriUtils;
|
||||
import com.chwl.core.utils.SharedPreferenceUtils;
|
||||
import com.chwl.core.utils.net.DontWarnObserver;
|
||||
import com.chwl.library.base.factory.CreatePresenter;
|
||||
import com.chwl.library.common.util.PhotoCompressUtil;
|
||||
import com.chwl.library.common.util.PhotosCompressCallback;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
import com.chwl.library.utils.SingleToastUtil;
|
||||
import com.example.matisse.internal.entity.CustomItem;
|
||||
import com.google.android.flexbox.FlexboxLayout;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import com.netease.nim.uikit.StatusBarUtil;
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
import com.trello.rxlifecycle3.android.ActivityEvent;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import kotlinx.coroutines.Job;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/11
|
||||
*/
|
||||
@CreatePresenter(PublishPresenter.class)
|
||||
public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresenter>
|
||||
implements IPublishView, WorldsChooseFrg.ChooseWorldCallback,
|
||||
View.OnClickListener {
|
||||
|
||||
private final static String KEY_SP_ORIGINAL_IMAGE = "key_sp_original_image";
|
||||
private final static int PERMISSION_CODE_STORAGE = 12;
|
||||
private final static int REQUEST_CODE_STORAGE = 42;
|
||||
private final static int REQUEST_CODE_OPEN_PHOTO_PROVIDER = 111; // 从相册中选择
|
||||
private final static int maxSelect = 9;
|
||||
|
||||
private RecyclerView rvImages;
|
||||
private TextView tvPublish;
|
||||
private EditText etContent;
|
||||
private TextView tvMiniWorldName;
|
||||
private TextView tvInputLimit;
|
||||
|
||||
private TextView tvChoose;
|
||||
private LinearLayout llGroupChoose;
|
||||
private TextView tvLabelReChoose;
|
||||
private LinearLayout llMiniWorld;
|
||||
private FlexboxLayout flGroup;
|
||||
private RelativeLayout rlChooseGroup;
|
||||
private ImageView ivClose;
|
||||
|
||||
private ImageAdapter imageAdapter;
|
||||
|
||||
private List<PublishItem> imageShowList = new ArrayList<>();
|
||||
|
||||
private List<CustomItem> uploadList = new ArrayList<>();
|
||||
|
||||
private boolean isOriginalImage;
|
||||
|
||||
// 话题客态页进入(话题进入不让修改话题标签)
|
||||
private boolean fromWorld;
|
||||
|
||||
private Job mJob = null;
|
||||
|
||||
|
||||
public static void start(DialogManager manager, long worldId) {
|
||||
if (beforeStart(manager)) {
|
||||
return;
|
||||
}
|
||||
Context context = manager.getContext();
|
||||
Intent intent = new Intent(context, PublishActivity.class);
|
||||
intent.putExtra("worldId", worldId);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 非话题页面进入
|
||||
*/
|
||||
public static void start(DialogManager manager) {
|
||||
if (beforeStart(manager)) {
|
||||
return;
|
||||
}
|
||||
Context context = manager.getContext();
|
||||
Intent intent = new Intent(context, PublishActivity.class);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
private static boolean beforeStart(DialogManager manager) {
|
||||
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
|
||||
if (userInfo == null) {
|
||||
SingleToastUtil.showToast(ResUtil.getString(R.string.yizhuan_xchat_android_constants_xchatconstants_016));
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_publish);
|
||||
|
||||
findView();
|
||||
initListener();
|
||||
|
||||
long worldId = getIntent().getLongExtra("worldId", 0L);
|
||||
if (worldId > 0) {
|
||||
fromWorld = true;
|
||||
getMvpPresenter().setWorldId(worldId);
|
||||
getMvpPresenter().setIsInWorld(true);
|
||||
}
|
||||
|
||||
isOriginalImage = (boolean) SharedPreferenceUtils.get(KEY_SP_ORIGINAL_IMAGE, false);
|
||||
initWhiteTitleBar(getString(R.string.pic_text_publish));
|
||||
initGridImages();
|
||||
updateImagesData();
|
||||
initEditContent();
|
||||
initOtherView();
|
||||
|
||||
// if (!fromWorld) {
|
||||
// getMvpPresenter().recommendWorlds();
|
||||
// } else { // 话题进入,关闭多余的控件
|
||||
// llGroupChoose.setVisibility(View.GONE);
|
||||
// tvChoose.setVisibility(View.GONE);
|
||||
// ivClose.setVisibility(View.GONE);
|
||||
//
|
||||
// flGroup.setVisibility(View.GONE);
|
||||
// }
|
||||
rlChooseGroup.setVisibility(View.GONE);
|
||||
flGroup.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void findView() {
|
||||
rvImages = findViewById(R.id.rv_images);
|
||||
tvPublish = findViewById(R.id.tv_publish);
|
||||
etContent = findViewById(R.id.et_content);
|
||||
tvMiniWorldName = findViewById(R.id.tv_mini_world_name);
|
||||
tvInputLimit = findViewById(R.id.tv_input_limit);
|
||||
tvChoose = findViewById(R.id.tv_choose);
|
||||
llGroupChoose = findViewById(R.id.ll_group_choose);
|
||||
tvLabelReChoose = findViewById(R.id.tv_label_re_choose);
|
||||
llMiniWorld = findViewById(R.id.ll_miniworld);
|
||||
flGroup = findViewById(R.id.fl_group);
|
||||
rlChooseGroup = findViewById(R.id.rl_choose_group);
|
||||
ivClose = findViewById(R.id.iv_close);
|
||||
}
|
||||
|
||||
private void initListener() {
|
||||
tvPublish.setOnClickListener(this);
|
||||
ivClose.setOnClickListener(this);
|
||||
llGroupChoose.setOnClickListener(this);
|
||||
rlChooseGroup.setOnClickListener(this);
|
||||
}
|
||||
|
||||
private void initGridImages() {
|
||||
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 3);
|
||||
rvImages.setLayoutManager(gridLayoutManager);
|
||||
rvImages.addItemDecoration(new GridSpacingItemDecoration(context, 3, 10));
|
||||
imageAdapter = new ImageAdapter(R.layout.item_publish_image, imageShowList);
|
||||
imageAdapter.setOnItemClickListener((adapter, view, position) -> {
|
||||
PublishItem item = imageShowList.get(position);
|
||||
if (item.isAddItem()) {
|
||||
checkStoragePermission();
|
||||
} else {
|
||||
BigPhotoActivity.startCanDelete(PublishActivity.this, (ArrayList<CustomItem>) uploadList,
|
||||
position, new PagerOption().setDelete(true));
|
||||
}
|
||||
});
|
||||
imageAdapter.setOnItemChildClickListener((adapter, view, position) -> {
|
||||
if (position < uploadList.size()) {
|
||||
getDialogManager().showOkCancelDialog(ResUtil.getString(R.string.publish_view_publishactivity_02), () -> {
|
||||
uploadList.remove(position);
|
||||
updateImagesData();
|
||||
imageAdapter.notifyDataSetChanged();
|
||||
toast(ResUtil.getString(R.string.publish_view_publishactivity_03));
|
||||
});
|
||||
}
|
||||
});
|
||||
rvImages.setAdapter(imageAdapter);
|
||||
updateImagesData();
|
||||
}
|
||||
|
||||
private void updateImagesData() {
|
||||
List<PublishItem> tmp = new ArrayList<>();
|
||||
for (int i = 0; i < uploadList.size(); i++) {
|
||||
CustomItem item = uploadList.get(i);
|
||||
if (item.getFileType() == 0 || item.getFileType() == 1) {
|
||||
PublishItem publishItem = new PublishItem(i, PublishItem.BUTTON_TYPE_SHOW_PIC,
|
||||
item.getPath(), item.isGif() ? 1 : 0);
|
||||
tmp.add(publishItem);
|
||||
}
|
||||
}
|
||||
imageShowList.clear();
|
||||
imageShowList.addAll(tmp);
|
||||
if (uploadList.size() < 9) {
|
||||
imageShowList.add(new PublishItem(-1, PublishItem.BUTTON_TYPE_ADD_ITEM, null, 0));
|
||||
}
|
||||
imageAdapter.notifyDataSetChanged();
|
||||
updatePublishStatus();
|
||||
}
|
||||
|
||||
private void initEditContent() {
|
||||
etContent.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
tvInputLimit.setText(s.length() + "/500");
|
||||
updatePublishStatus();
|
||||
String inputText = s.toString().trim();
|
||||
tvPublish.setTextColor(!TextUtils.isEmpty(inputText) ? getResources().getColor(R.color.color_7154EE) : getResources().getColor(R.color.color_999999));
|
||||
tvPublish.setEnabled(!TextUtils.isEmpty(inputText));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.tv_publish:
|
||||
publish();
|
||||
break;
|
||||
|
||||
case R.id.iv_close:
|
||||
showChooseView();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void publish() {
|
||||
tvPublish.setEnabled(false);
|
||||
getDialogManager().showProgressDialog(context);
|
||||
getMvpPresenter().publishDy(
|
||||
ObjectTypeHelper.customToMediaList(uploadList),
|
||||
getMvpPresenter().getWorldId(), etContent.getText().toString(), isOriginalImage);
|
||||
}
|
||||
|
||||
private void updatePublishStatus() {
|
||||
tvPublish.setEnabled(!(uploadList.size() == 0 &&
|
||||
CoreTextUtils.isEmptyText(etContent.getText().toString())));
|
||||
}
|
||||
|
||||
private void initOtherView() {
|
||||
//话题名称
|
||||
long worldId = getMvpPresenter().getWorldId();
|
||||
if (worldId > 0) {
|
||||
MiniWorldModel.getInstance().getWorldDetailInfo(String.valueOf(worldId),
|
||||
String.valueOf(AuthModel.get().getCurrentUid()))
|
||||
.compose(bindUntilEvent(ActivityEvent.DESTROY))
|
||||
.doOnSuccess(info -> {
|
||||
if (info != null && !TextUtils.isEmpty(info.getName())) {
|
||||
showReChooseView(info.getName());
|
||||
}
|
||||
})
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPublishSuccess() {
|
||||
hideIME(etContent);
|
||||
getDialogManager().dismissDialog();
|
||||
tvPublish.setEnabled(true);
|
||||
getDialogManager().showCustomViewDialog(R.layout.dialog_dy_publish_success);
|
||||
getDialogManager().getDialog().setCanceledOnTouchOutside(true);
|
||||
getDialogManager().getDialog().setOnDismissListener(dialog -> finish());
|
||||
getDialogManager().getDialog().setOnKeyListener((dialog, keyCode, event) -> {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0
|
||||
&& event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
hideDialogAndFinish();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
Single.timer(3, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
|
||||
.compose(bindUntilEvent(ActivityEvent.DESTROY))
|
||||
.subscribe(new DontWarnObserver<Long>() {
|
||||
@Override
|
||||
public void accept(Long aLong, String error) {
|
||||
super.accept(aLong, error);
|
||||
if (error == null) {
|
||||
hideDialogAndFinish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void hideDialogAndFinish() {
|
||||
getDialogManager().dismissDialog();
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPublishFailed(Throwable throwable) {
|
||||
tvPublish.setEnabled(true);
|
||||
getDialogManager().dismissDialog();
|
||||
toast(throwable.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recommendWorldsSuccess(List<MiniWorldChooseInfo> list) {
|
||||
addMiniWorldList(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recommendWorldsFails(String error) {
|
||||
flGroup.setVisibility(View.GONE);
|
||||
|
||||
toast(error);
|
||||
}
|
||||
|
||||
private void handleFinish() {
|
||||
if (!tvPublish.isEnabled()) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
getDialogManager().showOkCancelWithTitleDialog(ResUtil.getString(R.string.publish_view_publishactivity_06), ResUtil.getString(R.string.publish_view_publishactivity_07),
|
||||
ResUtil.getString(R.string.publish_view_publishactivity_08), ResUtil.getString(R.string.publish_view_publishactivity_09), new DialogManager.OkCancelDialogListener() {
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOk() {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLeftClickListener() {
|
||||
handleFinish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
handleFinish();
|
||||
}
|
||||
|
||||
private void showChooseView() {
|
||||
rlChooseGroup.setEnabled(true);
|
||||
llGroupChoose.setEnabled(false);
|
||||
|
||||
tvChoose.setVisibility(View.VISIBLE);
|
||||
tvLabelReChoose.setVisibility(View.GONE);
|
||||
|
||||
llMiniWorld.setVisibility(View.GONE);
|
||||
tvMiniWorldName.setText("");
|
||||
|
||||
getMvpPresenter().setMiniWorldChooseInfo(new MiniWorldChooseInfo());
|
||||
}
|
||||
|
||||
private void showReChooseView(String worldName) {
|
||||
rlChooseGroup.setEnabled(false);
|
||||
llGroupChoose.setEnabled(true);
|
||||
|
||||
tvChoose.setVisibility(View.GONE);
|
||||
tvLabelReChoose.setVisibility(View.VISIBLE);
|
||||
tvMiniWorldName.setText("#" + worldName);
|
||||
|
||||
llMiniWorld.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private List<MiniWorldChooseInfo> miniWorldChooseInfoList;
|
||||
|
||||
private void addMiniWorldList(List<MiniWorldChooseInfo> list) {
|
||||
miniWorldChooseInfoList = list;
|
||||
flGroup.removeAllViews();
|
||||
|
||||
if (miniWorldChooseInfoList != null && miniWorldChooseInfoList.size() > 0) {
|
||||
for (MiniWorldChooseInfo item : miniWorldChooseInfoList) {
|
||||
TextView textView = (TextView) LayoutInflater.from(this).inflate(R.layout.item_label_mini_world, flGroup, false);
|
||||
textView.setText(item.getWorldName());
|
||||
textView.setTag(item.getWorldId());
|
||||
textView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
TextView tv = (TextView) v;
|
||||
|
||||
if (miniWorldChooseInfoList != null && tv != null) {
|
||||
for (MiniWorldChooseInfo sub : miniWorldChooseInfoList) {
|
||||
Long tag = (Long) tv.getTag();
|
||||
long worldid = sub.getWorldId();
|
||||
if (worldid == tag) {
|
||||
getMvpPresenter().setMiniWorldChooseInfo(sub);
|
||||
showReChooseView(sub.getWorldName());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
flGroup.addView(textView);
|
||||
}
|
||||
|
||||
} else {
|
||||
flGroup.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callback(MiniWorldChooseInfo miniWorldChooseInfo) {
|
||||
getMvpPresenter().setMiniWorldChooseInfo(miniWorldChooseInfo);
|
||||
if (miniWorldChooseInfo == null) {
|
||||
showChooseView();
|
||||
} else {
|
||||
showReChooseView(miniWorldChooseInfo.getWorldName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needSteepStateBar() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setStatusBar() {
|
||||
StatusBarUtil.transparencyBar(this);
|
||||
StatusBarUtil.StatusBarLightMode(this);
|
||||
}
|
||||
|
||||
|
||||
private void checkStoragePermission() {
|
||||
PhotoPickActivity.start(this, PhotoPickActivity.IMG);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == RESULT_OK) {
|
||||
switch (requestCode) {
|
||||
case PhotoPickActivity.PICK_ACT_RESULT:
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
Uri uri = data.getData();
|
||||
if (uri != null && uri.getPath() != null) {
|
||||
|
||||
if (MyUriUtils.INSTANCE.isGif(context, uri)) {
|
||||
ToastUtils.show(R.string.error_file_type);
|
||||
return;
|
||||
}
|
||||
|
||||
File file = MyUriUtils.INSTANCE.copyFile(PublishActivity.this, uri);
|
||||
if (file != null) {
|
||||
LogUtil.e("选择 file = " + file.getName());
|
||||
LogUtil.e("选择 file = " + file.getPath());
|
||||
|
||||
if (mJob != null) {
|
||||
mJob.cancel(null);
|
||||
}
|
||||
ArrayList<String> pathList = new ArrayList<>();
|
||||
pathList.add(file.getPath());
|
||||
|
||||
mJob = PhotoCompressUtil.compress(PublishActivity.this, pathList,
|
||||
PhotoCompressUtil.getCompressCachePath("publish")
|
||||
, new PhotosCompressCallback() {
|
||||
@Override
|
||||
public void onSuccess(@NonNull ArrayList<String> compressedImgList) {
|
||||
List<CustomItem> pathResult = new ArrayList<>();
|
||||
for (int i = 0; i < compressedImgList.size(); i++) {
|
||||
if (i < pathList.size()) {
|
||||
List<String> fileInfo = MyUriUtils.INSTANCE.getFileInfo(file);
|
||||
if (fileInfo != null) {
|
||||
pathResult.add(new CustomItem(compressedImgList.get(i), CustomItem.IMAGE_NORMAL, fileInfo.get(2), Integer.parseInt(fileInfo.get(0)), Integer.parseInt(fileInfo.get(1))));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pathResult.size() == 0) {
|
||||
return;
|
||||
}
|
||||
LogUtil.print(pathResult);
|
||||
|
||||
uploadList.addAll(pathResult);
|
||||
updateImagesData();
|
||||
|
||||
isOriginalImage = false;
|
||||
LogUtil.print("isOriginalImage:" + isOriginalImage);
|
||||
SharedPreferenceUtils.put(KEY_SP_ORIGINAL_IMAGE, isOriginalImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(@NonNull Throwable e) {
|
||||
toast(getString(R.string.picker_image_error));
|
||||
}
|
||||
}, 200, false, Constants.UPLOAD_IMAGE_MAX_SIZE, Constants.UPLOAD_IMAGE_MAX_FILE_LENGTH);
|
||||
|
||||
} else {
|
||||
ToastUtils.show(R.string.exception_try_again);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mJob != null) {
|
||||
mJob.cancel(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package com.chwl.app.community.publish.view;
|
||||
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
|
||||
import com.chwl.core.community.bean.MiniWorldChooseInfo;
|
||||
|
||||
public class WorldChooseAdapter extends BaseQuickAdapter<MiniWorldChooseInfo, BaseViewHolder> {
|
||||
|
||||
public WorldChooseAdapter() {
|
||||
super(R.layout.item_worlds_choose, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, MiniWorldChooseInfo item) {
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
helper.setText(R.id.tv_world_name, item.getWorldName() + "")
|
||||
.setText(R.id.tv_world_desc, item.getDescription() + "");
|
||||
|
||||
ImageView imageView = helper.getView(R.id.rriv_world);
|
||||
ImageLoadUtilsV2.loadImage(imageView, item.getIcon());
|
||||
helper.addOnClickListener(R.id.cl_container);
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,147 @@
|
||||
package com.chwl.app.community.publish.view;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.base.BaseMvpFragment;
|
||||
import com.chwl.app.community.publish.presenter.WorldChoosePresenter;
|
||||
import com.chwl.app.ui.widget.recyclerview.decoration.HorizontalDecoration;
|
||||
import com.chwl.core.Constants;
|
||||
import com.chwl.core.community.bean.MiniWorldChooseInfo;
|
||||
import com.chwl.library.base.factory.CreatePresenter;
|
||||
import com.chwl.library.utils.SizeUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@CreatePresenter(WorldChoosePresenter.class)
|
||||
public class WorldsChooseFrg extends BaseMvpFragment<IWorldsChooseView, WorldChoosePresenter> implements IWorldsChooseView {
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private RecyclerView recyclerView;
|
||||
private WorldChooseAdapter mAdapter;
|
||||
|
||||
private byte mType;
|
||||
|
||||
public static WorldsChooseFrg newInstance(byte type) {
|
||||
WorldsChooseFrg fragment = new WorldsChooseFrg();
|
||||
Bundle args = new Bundle();
|
||||
args.putByte("type", type);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRootLayoutId() {
|
||||
return R.layout.frg_worlds_choose;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFindViews() {
|
||||
swipeRefreshLayout = mView.findViewById(R.id.swipe_refresh);
|
||||
recyclerView = mView.findViewById(R.id.recycler_view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetListener() {
|
||||
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
mAdapter.setEnableLoadMore(true);
|
||||
loadData(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiate() {
|
||||
Bundle bundle = getArguments();
|
||||
if (bundle != null) {
|
||||
mType = bundle.getByte("type", Constants.TYPE_ALL);
|
||||
} else {
|
||||
mType = Constants.TYPE_ALL;
|
||||
}
|
||||
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
|
||||
mAdapter = new WorldChooseAdapter();
|
||||
mAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
|
||||
@Override
|
||||
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
List<MiniWorldChooseInfo> list = adapter.getData();
|
||||
|
||||
if (list.size() > 0 && position < list.size()) {
|
||||
MiniWorldChooseInfo miniWorldChooseInfo = list.get(position);
|
||||
if (mChooseWorldCallback != null) {
|
||||
mChooseWorldCallback.callback(miniWorldChooseInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(mAdapter);
|
||||
recyclerView.addItemDecoration(new HorizontalDecoration(SizeUtils.dp2px(mContext, 25), false, true));
|
||||
|
||||
loadData(true);
|
||||
}
|
||||
|
||||
private void loadData(boolean isRefresh) {
|
||||
getMvpPresenter().loadData(isRefresh, mType);
|
||||
}
|
||||
|
||||
private ChooseWorldCallback mChooseWorldCallback;
|
||||
|
||||
public WorldsChooseFrg setmChooseWorldCallback(ChooseWorldCallback chooseWorldCallback) {
|
||||
this.mChooseWorldCallback = chooseWorldCallback;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void squareWorldsSuccess(List<MiniWorldChooseInfo> list) {
|
||||
hideStatus();
|
||||
|
||||
if (mAdapter != null) {
|
||||
int page = getMvpPresenter().getPage();
|
||||
if (page <= 1) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
|
||||
if (list == null || list.size() == 0) {
|
||||
showNoData();
|
||||
} else {
|
||||
mAdapter.setNewData(list);
|
||||
}
|
||||
|
||||
} else {
|
||||
mAdapter.addData(list);
|
||||
|
||||
if (list.size() == 0) {
|
||||
mAdapter.loadMoreComplete();
|
||||
mAdapter.loadMoreEnd();
|
||||
mAdapter.setEnableLoadMore(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReloadData() {
|
||||
super.onReloadData();
|
||||
loadData(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void squareWorldsFails(String error) {
|
||||
hideStatus();
|
||||
|
||||
int page = getMvpPresenter().getPage();
|
||||
if (page <= 1) {
|
||||
showNoData();
|
||||
}
|
||||
}
|
||||
|
||||
public interface ChooseWorldCallback {
|
||||
void callback(MiniWorldChooseInfo miniWorldChooseInfo);
|
||||
}
|
||||
}
|
@@ -0,0 +1,318 @@
|
||||
package com.chwl.app.community.square;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.chwl.app.base.BaseFragment;
|
||||
import com.chwl.library.widget.SVGAView;
|
||||
import com.chwl.core.XConstants;
|
||||
import com.trello.rxlifecycle3.android.FragmentEvent;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.UIHelper;
|
||||
import com.chwl.app.avroom.ButtonItemFactory;
|
||||
import com.chwl.app.avroom.activity.AVRoomActivity;
|
||||
import com.chwl.app.common.EmptyViewHelper;
|
||||
import com.chwl.app.common.widget.dialog.DialogManager;
|
||||
import com.chwl.app.community.helper.ShareDynamicHelper;
|
||||
import com.chwl.app.community.square.adapter.SquareDynamicAdapter;
|
||||
import com.chwl.app.ui.widget.ButtonItem;
|
||||
import com.chwl.core.auth.AuthModel;
|
||||
import com.chwl.core.community.CommunityConstant;
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
import com.chwl.core.community.bean.WorldDynamicListResult;
|
||||
import com.chwl.core.community.dynamic.DynamicModel;
|
||||
import com.chwl.core.community.event.DynamicPublishEvent;
|
||||
import com.chwl.core.community.event.DynamicRefreshEvent;
|
||||
import com.chwl.core.community.square.SquareModel;
|
||||
import com.chwl.core.user.UserModel;
|
||||
import com.chwl.core.user.event.LoadLoginUserInfoEvent;
|
||||
import com.chwl.core.utils.net.BeanObserver;
|
||||
import com.chwl.core.utils.net.DontWarnObserver;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import io.reactivex.Single;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2020/1/7
|
||||
*/
|
||||
public class SquareDynamicFragment extends BaseFragment {
|
||||
|
||||
public static final String EXTRA_SQUARE_TYPE = "square_type";
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
private SwipeRefreshLayout refreshLayout;
|
||||
/**
|
||||
* 话题类型ID
|
||||
* 全部 0
|
||||
* 推荐 1
|
||||
*/
|
||||
private static final String TOPIC_CATEGORY_ID = "1";
|
||||
|
||||
private String nextDynamicId;
|
||||
|
||||
private int page = 1;
|
||||
|
||||
private SquareDynamicAdapter adapter;
|
||||
|
||||
private int squareType;
|
||||
|
||||
private SVGAView.SVGACache svgaCache;
|
||||
|
||||
public static SquareDynamicFragment newInstance(int type) {
|
||||
SquareDynamicFragment fragment = new SquareDynamicFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(EXTRA_SQUARE_TYPE, type);
|
||||
fragment.setArguments(bundle);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
mView = inflater.inflate(R.layout.fragment_square_dynamic, container, false);
|
||||
EventBus.getDefault().register(this);
|
||||
return mView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFindViews() {
|
||||
recyclerView = mView.findViewById(R.id.recycler_view);
|
||||
refreshLayout = mView.findViewById(R.id.refresh_layout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetListener() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiate() {
|
||||
Bundle bundle = getArguments();
|
||||
if (bundle != null) {
|
||||
squareType = bundle.getInt(EXTRA_SQUARE_TYPE, SquareFragment.TAB_TYPE_RECOMMEND);
|
||||
}
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
|
||||
adapter = new SquareDynamicAdapter(getActivity(), svgaCache);
|
||||
recyclerView.setAdapter(adapter);
|
||||
adapter.setPreLoadNumber(2);
|
||||
adapter.setHeaderAndEmpty(true);
|
||||
adapter.setOnLoadMoreListener(() -> loadData(false), recyclerView);
|
||||
adapter.setOnItemChildClickListener((baseQuickAdapter, view, pos) -> {
|
||||
WorldDynamicBean bean = adapter.getItem(pos);
|
||||
if (bean == null) {
|
||||
return;
|
||||
}
|
||||
if (view.getId() == R.id.iv_more) {
|
||||
List<ButtonItem> list = new ArrayList<>();
|
||||
if (!UserModel.get().isMyseft(bean.getUid())) {
|
||||
ButtonItem item = new ButtonItem(getString(R.string.me_shield_dynamic), () -> {
|
||||
UserModel.get().addReport(bean.getDynamicId(), 0)
|
||||
.subscribe(new BeanObserver<String>() {
|
||||
@Override
|
||||
public void onErrorMsg(String error) {
|
||||
getDialogManager().dismissDialog();
|
||||
toast(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(String s) {
|
||||
getDialogManager().dismissDialog();
|
||||
toast(ResUtil.getString(R.string.me_shield_success));
|
||||
adapter.remove(pos);
|
||||
}
|
||||
});
|
||||
});
|
||||
list.add(item);
|
||||
}
|
||||
if (!UserModel.get().isMyseft(bean.getUid())) {
|
||||
ButtonItem blackListItem = ButtonItemFactory.createAddToBlackListItem(
|
||||
getDialogManager(), String.valueOf(bean.getUid()));
|
||||
list.add(blackListItem);
|
||||
}
|
||||
if (!UserModel.get().isMyseft(bean.getUid())) {
|
||||
ButtonItem item = new ButtonItem(getString(R.string.me_report_dynamic), () -> {
|
||||
UIHelper.showReportPage(getActivity(), bean.getUid(),
|
||||
XConstants.REPORT_TYPE_DYNAMIC_SQUARE);
|
||||
});
|
||||
list.add(item);
|
||||
}
|
||||
if (UserModel.get().isMyseft(bean.getUid()) ||
|
||||
isThisWorldOwner(bean)) {
|
||||
ButtonItem item = new ButtonItem(getString(R.string.me_delete), () -> deleteDynamic(pos));
|
||||
list.add(item);
|
||||
}
|
||||
getDialogManager().showCommonPopupDialog(list, getString(R.string.cancel));
|
||||
} else if (view.getId() == R.id.ll_share) {
|
||||
new ShareDynamicHelper(getActivity()).share(bean);
|
||||
} else if (view.getId() == R.id.iv_in_room) {
|
||||
if (bean.getInRoomUid() == null) {
|
||||
return;
|
||||
}
|
||||
AVRoomActivity.start(mContext, bean.getInRoomUid());
|
||||
}
|
||||
});
|
||||
|
||||
refreshLayout = mView.findViewById(R.id.refresh_layout);
|
||||
refreshLayout.setOnRefreshListener(() -> {
|
||||
loadData(true);
|
||||
});
|
||||
|
||||
loadData(true);
|
||||
}
|
||||
|
||||
public void setSvgaCache(SVGAView.SVGACache svgaCache) {
|
||||
this.svgaCache = svgaCache;
|
||||
}
|
||||
|
||||
private void loadData(boolean isRefresh) {
|
||||
if (isRefresh) {
|
||||
nextDynamicId = null;
|
||||
page = 1;
|
||||
} else {
|
||||
page++;
|
||||
}
|
||||
|
||||
Single<WorldDynamicListResult> single = null;
|
||||
//推荐动态返回的是直接一个list,但是为了便于统一和关注动态列表的逻辑,我们包多一层
|
||||
//返回WorldDynamicListResult
|
||||
if (squareType == SquareFragment.TAB_TYPE_ATTENT) {
|
||||
single = SquareModel.get().getFollowerDynamics(nextDynamicId,
|
||||
CommunityConstant.DYNAMIC_PAGE_SIZE);
|
||||
} else if (squareType == SquareFragment.TAB_TYPE_RECOMMEND) {
|
||||
single = SquareModel.get().getRecommendDynamics(page, CommunityConstant.DYNAMIC_PAGE_SIZE)
|
||||
.map(list -> {
|
||||
WorldDynamicListResult result = new WorldDynamicListResult();
|
||||
result.setDynamicList(list);
|
||||
return result;
|
||||
});
|
||||
} else {
|
||||
single = SquareModel.get().getLatestDynamics(page, CommunityConstant.DYNAMIC_PAGE_SIZE, nextDynamicId);
|
||||
}
|
||||
|
||||
single.compose(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
|
||||
.subscribe(new DontWarnObserver<WorldDynamicListResult>() {
|
||||
@Override
|
||||
public void accept(WorldDynamicListResult result, String error) {
|
||||
super.accept(result, error);
|
||||
refreshLayout.setRefreshing(false);
|
||||
if (error != null) {
|
||||
if (!isRefresh) adapter.loadMoreFail();
|
||||
return;
|
||||
}
|
||||
//接口访问正确的处理
|
||||
nextDynamicId = String.valueOf(result.getNextDynamicId());
|
||||
List<WorldDynamicBean> list = result.getDynamicList();
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
if (isRefresh) {
|
||||
adapter.setNewData(list);
|
||||
adapter.disableLoadMoreIfNotFullPage();
|
||||
if (list.isEmpty()) {
|
||||
String emptyTips = getString(R.string.no_dynamic);
|
||||
if (squareType == SquareFragment.TAB_TYPE_ATTENT) {
|
||||
emptyTips = getString(R.string.recommend_to_have_a_look);
|
||||
}
|
||||
adapter.setEmptyView(EmptyViewHelper.createEmptyTextView(getContext(), emptyTips));
|
||||
}
|
||||
} else {
|
||||
if (list.isEmpty()) {
|
||||
adapter.loadMoreEnd(true);
|
||||
} else {
|
||||
adapter.addData(list);
|
||||
adapter.loadMoreComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断自己是不是该世界的创始人
|
||||
*/
|
||||
private boolean isThisWorldOwner(WorldDynamicBean bean) {
|
||||
return bean != null && bean.getWorldUid() == AuthModel.get().getCurrentUid();
|
||||
}
|
||||
|
||||
private void deleteDynamic(int pos) {
|
||||
getDialogManager().showOkCancelWithTitleDialog(getString(R.string.me_cannot_be_restored),
|
||||
new DialogManager.OkCancelDialogListener() {
|
||||
@Override
|
||||
public void onOk() {
|
||||
WorldDynamicBean bean = adapter.getItem(pos);
|
||||
if (bean == null) {
|
||||
return;
|
||||
}
|
||||
DynamicModel.get().delete(bean.getWorldId(), bean.getDynamicId())
|
||||
.compose(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
|
||||
.subscribe(new DontWarnObserver<String>() {
|
||||
@Override
|
||||
public void accept(String s, String error) {
|
||||
super.accept(s, error);
|
||||
if (error != null) {
|
||||
toast(error);
|
||||
} else {
|
||||
toast(getString(R.string.me_successfully_delete));
|
||||
if (pos < adapter.getData().size()) {
|
||||
if (Objects.equals(bean, adapter.getItem(pos))) {
|
||||
adapter.remove(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onDynamicPublishEvent(DynamicPublishEvent event) {
|
||||
if (squareType == SquareFragment.TAB_TYPE_ATTENT) {
|
||||
loadData(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onLoadLoginUserInfoEvent(LoadLoginUserInfoEvent event) {
|
||||
if (squareType == SquareFragment.TAB_TYPE_ATTENT) {
|
||||
loadData(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onDynamicRefreshEvent(DynamicRefreshEvent event) {
|
||||
loadData(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRootLayoutId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showNoData() {
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,205 @@
|
||||
package com.chwl.app.community.square;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.avroom.adapter.CommonVPAdapter;
|
||||
import com.chwl.app.base.BaseFragment;
|
||||
import com.chwl.app.common.widget.DragLayout;
|
||||
import com.chwl.app.community.publish.view.PublishActivity;
|
||||
import com.chwl.app.home.activity.CommunityNoticeAct;
|
||||
import com.chwl.app.ui.user.adapter.ContactsIndicatorAdapter;
|
||||
import com.chwl.app.ui.widget.magicindicator.MagicIndicator;
|
||||
import com.chwl.app.ui.widget.magicindicator.ViewPagerHelper;
|
||||
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator;
|
||||
import com.chwl.app.utils.HomeUIManager;
|
||||
import com.chwl.core.auth.AuthModel;
|
||||
import com.chwl.core.community.event.UnReadCountEvent;
|
||||
import com.chwl.core.home.model.HomeModel;
|
||||
import com.chwl.core.user.event.LoadLoginUserInfoEvent;
|
||||
import com.chwl.library.language.LanguageHelper;
|
||||
import com.chwl.library.widget.SVGAView;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2020/1/7
|
||||
*/
|
||||
|
||||
public class SquareFragment extends BaseFragment implements ContactsIndicatorAdapter.OnItemSelectListener, View.OnClickListener {
|
||||
public static final String TAG = "SquareFragment";
|
||||
/**
|
||||
* 关注
|
||||
*/
|
||||
public static final int TAB_TYPE_ATTENT = 1;
|
||||
/**
|
||||
* 推荐
|
||||
*/
|
||||
public static final int TAB_TYPE_RECOMMEND = 0;
|
||||
/**
|
||||
* 最新
|
||||
*/
|
||||
public static final int TAB_TYPE_NEW = 2;
|
||||
|
||||
private MagicIndicator magicIndicator;
|
||||
private ViewPager2 viewPager;
|
||||
private DragLayout ivSquarePublish;
|
||||
private FrameLayout flContactList;
|
||||
private View tvCommunityUnread;
|
||||
|
||||
private SVGAView.SVGACache svgaCache = SVGAView.newCache(10);
|
||||
|
||||
public static SquareFragment newInstance() {
|
||||
return new SquareFragment();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
mView = inflater.inflate(R.layout.fragment_square, container, false);
|
||||
magicIndicator = mView.findViewById(R.id.magic_indicator);
|
||||
viewPager = mView.findViewById(R.id.view_pager);
|
||||
ivSquarePublish = mView.findViewById(R.id.iv_square_publish);
|
||||
flContactList = mView.findViewById(R.id.fl_contact_list);
|
||||
tvCommunityUnread = mView.findViewById(R.id.msg_number);
|
||||
EventBus.getDefault().register(this);
|
||||
return mView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiate() {
|
||||
HomeUIManager.INSTANCE.setHomeUI(mView);
|
||||
List<Integer> fragmentPos = new ArrayList<>();
|
||||
fragmentPos.add(TAB_TYPE_RECOMMEND);
|
||||
fragmentPos.add(TAB_TYPE_ATTENT);
|
||||
fragmentPos.add(TAB_TYPE_NEW);
|
||||
List<String> tagList = new ArrayList<>();
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
for (Integer integer : fragmentPos) {
|
||||
if (integer == TAB_TYPE_ATTENT) {
|
||||
tagList.add(getResources().getString(R.string.dys_tab_attent));
|
||||
} else if (integer == TAB_TYPE_RECOMMEND) {
|
||||
tagList.add(getResources().getString(R.string.dys_tab_recommend));
|
||||
} else if (integer == TAB_TYPE_NEW) {
|
||||
tagList.add(getResources().getString(R.string.dys_tab_new));
|
||||
}
|
||||
SquareDynamicFragment fragment = SquareDynamicFragment.newInstance(integer);
|
||||
fragment.setSvgaCache(svgaCache);
|
||||
fragmentList.add(fragment);
|
||||
}
|
||||
|
||||
getUnReadCount();
|
||||
|
||||
//init viewpager
|
||||
|
||||
viewPager.setAdapter(new CommonVPAdapter(getChildFragmentManager(), getLifecycle(), fragmentList));
|
||||
viewPager.setOffscreenPageLimit(3);
|
||||
viewPager.setUserInputEnabled(false);
|
||||
|
||||
CommonNavigator commonNavigator = new CommonNavigator(getContext());
|
||||
if (LanguageHelper.INSTANCE.getCurrentLanguageType().equals("EN")) {
|
||||
commonNavigator.setLeftPadding(40);
|
||||
}
|
||||
ContactsIndicatorAdapter magicIndicatorAdapter = new ContactsIndicatorAdapter(getContext(), tagList);
|
||||
magicIndicatorAdapter.setOnItemSelectListener(this);
|
||||
commonNavigator.setTitleWrapContent(false);
|
||||
commonNavigator.setAdapter(magicIndicatorAdapter);
|
||||
magicIndicator.setNavigator(commonNavigator);
|
||||
commonNavigator.getTitleContainer().setShowDividers(LinearLayout.SHOW_DIVIDER_BEGINNING);
|
||||
//init indicator
|
||||
ViewPagerHelper.bind(magicIndicator, viewPager);
|
||||
viewPager.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
viewPager.setCurrentItem(TAB_TYPE_RECOMMEND);
|
||||
}
|
||||
});
|
||||
// magicIndicator.onPageSelected(TAB_TYPE_RECOMMEND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelect(int position, TextView view) {
|
||||
viewPager.setCurrentItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetListener() {
|
||||
if (ivSquarePublish != null) {
|
||||
ivSquarePublish.setOnClickListener(this);
|
||||
}
|
||||
if (flContactList != null) {
|
||||
flContactList.setOnClickListener(this);
|
||||
}
|
||||
if (ivSquarePublish != null) {
|
||||
ivSquarePublish.setOnClickListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()) {
|
||||
case R.id.iv_square_publish:
|
||||
PublishActivity.start(getDialogManager());
|
||||
break;
|
||||
|
||||
case R.id.fl_contact_list:
|
||||
CommunityNoticeAct.start(mContext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onUnReadCount(UnReadCountEvent event) {
|
||||
setNumber(event.getTotal());
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
public void setNumber(int number) {
|
||||
tvCommunityUnread.setVisibility(number <= 0 ? GONE : VISIBLE);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onLoginUserInfoUpdateEvent(LoadLoginUserInfoEvent event) {
|
||||
getUnReadCount();
|
||||
}
|
||||
|
||||
@SuppressWarnings("CheckResult")
|
||||
private void getUnReadCount() {
|
||||
HomeModel.INSTANCE.getUnreadCount(AuthModel.get().getCurrentUid())
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe((integer, throwable) -> {
|
||||
if (integer != null) {
|
||||
EventBus.getDefault().post(new UnReadCountEvent(integer));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
EventBus.getDefault().unregister(this);
|
||||
svgaCache.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,265 @@
|
||||
package com.chwl.app.community.square.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtils;
|
||||
import com.chwl.app.utils.AvatarHelper;
|
||||
import com.chwl.library.widget.SVGAView;
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
import com.netease.nim.uikit.support.glide.GlideApp;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.UIHelper;
|
||||
import com.chwl.app.community.dynamic.view.DynamicDetailActivity;
|
||||
import com.chwl.app.community.helper.DynamicUiHelper;
|
||||
import com.chwl.app.community.utils.TopicUpTextWrapper;
|
||||
import com.chwl.app.community.widget.DynamicNickDetailWidget;
|
||||
import com.chwl.app.community.widget.ExpandableTextView;
|
||||
import com.chwl.app.community.widget.GridImageWidget;
|
||||
import com.chwl.app.community.widget.TopicLabelWidget;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
|
||||
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
|
||||
import com.chwl.app.utils.TimeUiUtils;
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
import com.chwl.core.community.dynamic.DynamicModel;
|
||||
import com.chwl.core.noble.NobleUtil;
|
||||
import com.chwl.core.utils.net.DontWarnObserver;
|
||||
import com.chwl.core.utils.net.RxHelper;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
import com.chwl.library.utils.SingleToastUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/13
|
||||
*/
|
||||
public class SquareDynamicAdapter extends BaseQuickAdapter<WorldDynamicBean, BaseViewHolder> {
|
||||
|
||||
private SparseBooleanArray mCollapsedStatus = new SparseBooleanArray();
|
||||
private SparseIntArray mCollapsedHeightStatus = new SparseIntArray(2);
|
||||
|
||||
private Context context;
|
||||
private SVGAView.SVGACache svgaCache;
|
||||
|
||||
private int iconWidth;
|
||||
|
||||
private int iconHeight;
|
||||
|
||||
/**
|
||||
* 有文本的图片布局的top-margin
|
||||
*/
|
||||
private int imageTmHasText;
|
||||
/**
|
||||
* 无文本的图片布局的top-margin
|
||||
*/
|
||||
private int imageTmNoText;
|
||||
/**
|
||||
* 图片的边界值
|
||||
*/
|
||||
private int dividerDp;
|
||||
|
||||
private int rvWidth;
|
||||
|
||||
|
||||
public SquareDynamicAdapter(Context context, SVGAView.SVGACache svgaCache) {
|
||||
super(R.layout.item_square_dynamic);
|
||||
this.context = context;
|
||||
this.svgaCache = svgaCache;
|
||||
iconWidth = UIUtil.dip2px(context, 32);
|
||||
iconHeight = UIUtil.dip2px(context, 15);
|
||||
imageTmHasText = UIUtil.dip2px(context, 12f);
|
||||
imageTmNoText = UIUtil.dip2px(context, 7.5f);
|
||||
//0.68
|
||||
int screenWidth = UIUtil.getScreenWidth(context);
|
||||
dividerDp = 9;
|
||||
rvWidth = screenWidth - UIUtil.dip2px(context, 86);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) {
|
||||
BaseViewHolder holder = super.onCreateDefViewHolder(parent, viewType);
|
||||
SVGAView ivHeadWear = holder.getView(R.id.iv_head_wear);
|
||||
ivHeadWear.bindCache(svgaCache);
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, WorldDynamicBean item) {
|
||||
//这个值,有没有文本UI部分,改变图片部分的margin
|
||||
boolean noTextUi = TextUtils.isEmpty(item.getContent());
|
||||
|
||||
helper.setText(R.id.tv_nick, item.getNick());
|
||||
GridImageWidget widgetImage = helper.getView(R.id.widget_image);
|
||||
widgetImage.setDividerDp(dividerDp);
|
||||
widgetImage.setRvWidth(rvWidth);
|
||||
widgetImage.setData(item, noTextUi ? imageTmNoText : imageTmHasText);
|
||||
|
||||
//头饰 贵族头饰
|
||||
SVGAView ivHeadWear = helper.getView(R.id.iv_head_wear);
|
||||
GlideApp.with(ivHeadWear.getContext()).clear(ivHeadWear);
|
||||
String headwearEffect = item.getHeadwearEffect();
|
||||
String headwearPic = item.getHeadwearPic();
|
||||
int headwearType = item.getHeadwearType();
|
||||
String micDecorate = item.getMicDecorate();
|
||||
if (TextUtils.isEmpty(headwearEffect) && TextUtils.isEmpty(headwearPic) && TextUtils.isEmpty(micDecorate)) {
|
||||
ivHeadWear.setVisibility(View.GONE);
|
||||
} else {
|
||||
ivHeadWear.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(headwearEffect)) {
|
||||
AvatarHelper.loadAvatarFrame(ivHeadWear, headwearEffect, headwearType);
|
||||
} else if (!TextUtils.isEmpty(headwearPic)) {
|
||||
AvatarHelper.loadAvatarFrame(ivHeadWear, headwearPic, headwearType);
|
||||
} else if (!TextUtils.isEmpty(micDecorate)) {
|
||||
NobleUtil.loadResource(micDecorate, ivHeadWear);
|
||||
} else {
|
||||
ivHeadWear.setImageDrawable(null);
|
||||
}
|
||||
|
||||
//头像
|
||||
ImageLoadUtils.loadAvatar( item.getAvatar() ,helper.getView(R.id.iv_avatar));
|
||||
|
||||
DynamicNickDetailWidget widget = helper.getView(R.id.widget_nick_detail);
|
||||
widget.setData(item);
|
||||
//widget.setTime(item.getPublishTime());
|
||||
final String time = TimeUiUtils.getDynamicUi(item.getPublishTime());
|
||||
helper.setGone(R.id.tv_time_publish, !TextUtils.isEmpty(time));
|
||||
helper.setText(R.id.tv_time_publish, time);
|
||||
helper.setGone(R.id.iv_in_room, item.getInRoomUid() != null);
|
||||
|
||||
ExpandableTextView etvContent = helper.getView(R.id.etv_content);
|
||||
etvContent.setEventType(4);
|
||||
if (noTextUi && item.getSquareTop() == 0) {
|
||||
etvContent.setVisibility(View.GONE);
|
||||
} else {
|
||||
etvContent.setVisibility(View.VISIBLE);
|
||||
CharSequence formatText = DynamicUiHelper.formatFirstDynamicContent(
|
||||
item, etvContent.mTv, iconWidth, iconHeight);
|
||||
if (item.getSquareTop() == 1) {
|
||||
//置顶
|
||||
formatText = TopicUpTextWrapper.INSTANCE.wrapUp(formatText, context);
|
||||
}
|
||||
etvContent.setText(formatText, mCollapsedStatus, helper.getAdapterPosition(), mCollapsedHeightStatus);
|
||||
}
|
||||
|
||||
//标签
|
||||
final List<String> labels = item.getLabelList();
|
||||
if (labels != null) {
|
||||
((TopicLabelWidget) helper.getView(R.id.topicView)).setLabels(labels);
|
||||
}
|
||||
|
||||
//评论
|
||||
setCommentCount(helper, item.getCommentCount());
|
||||
|
||||
//点赞
|
||||
setLikeCount(helper, item.getLikeCount(), item.isLike(), false);
|
||||
LinearLayout llLike = helper.getView(R.id.ll_like);
|
||||
llLike.setEnabled(true);
|
||||
llLike.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
llLike.setEnabled(false);
|
||||
int status = item.isLike() ? 0 : 1;
|
||||
DynamicModel.get().like(item.getWorldId(), item.getDynamicId(), item.getUid(), status, 4)
|
||||
.compose(RxHelper.bindContext(context))
|
||||
.subscribe(new DontWarnObserver<String>() {
|
||||
@Override
|
||||
public void accept(String s, String error) {
|
||||
super.accept(s, error);
|
||||
llLike.setEnabled(true);
|
||||
if (error != null) {
|
||||
SingleToastUtil.showToast(error);
|
||||
} else {
|
||||
LogUtil.print(ResUtil.getString(R.string.square_adapter_squaredynamicadapter_01));
|
||||
if (status == 1) {
|
||||
item.setLikeCount(item.getLikeCount() + 1);
|
||||
} else {
|
||||
item.setLikeCount(item.getLikeCount() - 1);
|
||||
}
|
||||
item.setLike(status == 1);
|
||||
setLikeCount(helper, item.getLikeCount(), item.isLike(), true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//评论
|
||||
helper.getView(R.id.ll_comment).setOnClickListener(v -> {
|
||||
DynamicDetailActivity.start(context, item.getDynamicId(), item.getWorldId(),
|
||||
helper.getAdapterPosition(), true, 6);
|
||||
}
|
||||
);
|
||||
|
||||
View.OnClickListener toDetailListener = v ->
|
||||
DynamicDetailActivity.start(context, item.getDynamicId(), item.getWorldId(),
|
||||
helper.getAdapterPosition(), false, 6);
|
||||
|
||||
if (etvContent.mTv != null) {
|
||||
etvContent.mTv.setOnClickListener(toDetailListener);
|
||||
}
|
||||
|
||||
//跳转去详情
|
||||
helper.itemView.setOnClickListener(toDetailListener);
|
||||
|
||||
helper.addOnClickListener(R.id.iv_more)
|
||||
.addOnClickListener(R.id.ll_share)
|
||||
.addOnClickListener(R.id.iv_in_room);
|
||||
|
||||
View.OnClickListener userInfoActClick = v -> UIHelper.showUserInfoAct(context, item.getUid());
|
||||
helper.getView(R.id.iv_avatar).setOnClickListener(userInfoActClick);
|
||||
helper.getView(R.id.widget_nick_detail).setOnClickListener(userInfoActClick);
|
||||
|
||||
//话题
|
||||
helper.setGone(R.id.tv_mini_world_name, false);
|
||||
helper.setGone(R.id.space_view, false);
|
||||
// helper.setGone(R.id.tv_mini_world_name, item.getWorldId() > 0);
|
||||
// helper.setGone(R.id.space_view, item.getWorldId() > 0);
|
||||
// helper.setText(R.id.tv_mini_world_name, item.getWorldName());
|
||||
// helper.getView(R.id.tv_mini_world_name).setOnClickListener(v -> {
|
||||
// TopicMainActivity.start(context, String.valueOf(item.getWorldId()));
|
||||
// });
|
||||
}
|
||||
|
||||
private void setLikeCount(BaseViewHolder helper, int likeCount, boolean isLike, boolean isAnim) {
|
||||
TextView tvLike = helper.getView(R.id.tv_like);
|
||||
String likeCountStr;
|
||||
if (likeCount < 0) {
|
||||
likeCountStr = "0";
|
||||
} else if (likeCount >= 1000) {
|
||||
likeCountStr = "999+";
|
||||
} else {
|
||||
likeCountStr = String.valueOf(likeCount);
|
||||
}
|
||||
tvLike.setText(likeCountStr);
|
||||
|
||||
ImageView ivLikeAnim = helper.getView(R.id.iv_like_pic);
|
||||
if (isLike) {
|
||||
ivLikeAnim.setImageResource(R.drawable.icon_square_dynamic_like_checked);
|
||||
} else {
|
||||
ivLikeAnim.setImageResource(R.drawable.icon_square_dynamic_like_normal);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCommentCount(BaseViewHolder helper, int commentCount) {
|
||||
TextView tvComment = helper.getView(R.id.tv_comment);
|
||||
String commentCountStr;
|
||||
if (commentCount < 0) {
|
||||
commentCountStr = "0";
|
||||
} else if (commentCount >= 1000) {
|
||||
commentCountStr = "999+";
|
||||
} else {
|
||||
commentCountStr = String.valueOf(commentCount);
|
||||
}
|
||||
tvComment.setText(commentCountStr);
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package com.chwl.app.community.user_dynamic;
|
||||
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
import com.chwl.library.base.IMvpBaseView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IUserDynamicView extends IMvpBaseView {
|
||||
void refreshSuccess(List<WorldDynamicBean> list);
|
||||
void refreshFail(String error);
|
||||
|
||||
void loadSuccess(List<WorldDynamicBean> list);
|
||||
void loadFail(String error);
|
||||
|
||||
void deleteSuccess(long successId);
|
||||
void deleteFail(String error);
|
||||
}
|
@@ -0,0 +1,285 @@
|
||||
package com.chwl.app.community.user_dynamic;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.chwl.app.photo.BigPhotoActivity;
|
||||
import com.chwl.app.photo.PagerOption;
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.community.helper.CalcSize;
|
||||
import com.chwl.app.community.helper.ImageUiHelper;
|
||||
import com.chwl.app.photo.DynamicImageAdapter;
|
||||
import com.chwl.app.community.utils.ObjectTypeHelper;
|
||||
import com.chwl.app.community.widget.ExpandableTextView;
|
||||
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
|
||||
import com.chwl.app.ui.widget.recyclerview.decoration.GridSpacingItemDecoration;
|
||||
import com.chwl.core.community.bean.DynamicMedia;
|
||||
import com.chwl.core.community.bean.UserDynamicItem;
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
import com.chwl.core.community.dynamic.DynamicModel;
|
||||
import com.chwl.core.utils.net.DontWarnObserver;
|
||||
import com.chwl.core.utils.net.RxHelper;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
import com.chwl.library.utils.ScreenUtils;
|
||||
import com.chwl.library.utils.SingleToastUtil;
|
||||
import com.chwl.library.utils.TimeUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UserDynamicAdapter extends BaseMultiItemQuickAdapter<UserDynamicItem, BaseViewHolder> {
|
||||
private long currentUid;
|
||||
private SparseBooleanArray mCollapsedStatus = new SparseBooleanArray();
|
||||
private SparseIntArray mCollapsedHeightStatus = new SparseIntArray(2);
|
||||
|
||||
private int imageBorder;
|
||||
/**
|
||||
* 这个divider是因为使用的分割线
|
||||
* 默认为top和bottom添加了5dp
|
||||
*/
|
||||
private int divider;
|
||||
|
||||
// 图片宽高一致
|
||||
private int mTwoImageHeight;
|
||||
private int mThreeImageHeight;
|
||||
|
||||
public UserDynamicAdapter(Context context, long currentUid) {
|
||||
super(new ArrayList<>());
|
||||
this.currentUid = currentUid;
|
||||
addItemType(UserDynamicItem.TYPE_DYNAMIC, R.layout.item_user_dynamic_list);
|
||||
addItemType(UserDynamicItem.TYPE_EMPTY, R.layout.item_empty_list);
|
||||
addItemType(UserDynamicItem.TYPE_FIRST_DIVIDER, R.layout.layout_divider_12);
|
||||
imageBorder = (UIUtil.getScreenWidth(context) - UIUtil.dip2px(context, 17+29))
|
||||
* ImageUiHelper.BORDER_MIN / ImageUiHelper.BORDER_MAX;
|
||||
divider = UIUtil.dip2px(context, 10);
|
||||
|
||||
mTwoImageHeight = (ScreenUtils.getScreenWidth(context) - UIUtil.dip2px(context, 17 + 29 + 22.5 + 20 + 10)) / 2;
|
||||
mThreeImageHeight = (ScreenUtils.getScreenWidth(context) - UIUtil.dip2px(context, 17 + 29 + 22.5 + 20 + 20)) / 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, UserDynamicItem item) {
|
||||
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (item.getItemType()) {
|
||||
case UserDynamicItem.TYPE_DYNAMIC:
|
||||
setDynamic(helper, item);
|
||||
break;
|
||||
|
||||
case UserDynamicItem.TYPE_EMPTY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setDynamic(BaseViewHolder helper, UserDynamicItem item) {
|
||||
WorldDynamicBean userDynamicInfo = (WorldDynamicBean) item.getData();
|
||||
if (userDynamicInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<UserDynamicItem> list = getData();
|
||||
int position = list.indexOf(item);
|
||||
helper.setGone(R.id.v_divider_user_dynamic, position != (list.size() - 1));
|
||||
|
||||
helper.setGone(R.id.rv_img, false);
|
||||
helper.setGone(R.id.fl_multi_media_dynamic_list, false);
|
||||
|
||||
switch (userDynamicInfo.getType()) {
|
||||
case 0:
|
||||
helper.setImageResource(R.id.iv_type_img_dynamic_list, R.drawable.ic_text_dynamic);
|
||||
break;
|
||||
case 1:
|
||||
helper.setImageResource(R.id.iv_type_img_dynamic_list, R.drawable.ic_voice_dynamic);
|
||||
break;
|
||||
case 2:
|
||||
helper.setImageResource(R.id.iv_type_img_dynamic_list, R.drawable.ic_img_dynamic)
|
||||
.setGone(R.id.fl_multi_media_dynamic_list, true);
|
||||
setPhoto(helper, userDynamicInfo);
|
||||
break;
|
||||
case 3:
|
||||
helper.setImageResource(R.id.iv_type_img_dynamic_list, R.drawable.ic_video_dynamic);
|
||||
break;
|
||||
}
|
||||
|
||||
if (userDynamicInfo.isSystemDynamic()) { // 系统为未发布过动态的用户自动生成的动态
|
||||
helper.setImageResource(R.id.iv_type_img_dynamic_list, R.drawable.ic_text_dynamic)
|
||||
.setGone(R.id.cl_bottom_user_dynamic_list, false);
|
||||
} else {
|
||||
helper.setGone(R.id.cl_bottom_user_dynamic_list, true);
|
||||
}
|
||||
|
||||
|
||||
String time = TimeUtils.getTimeStringFromMillis(userDynamicInfo.getPublishTime());
|
||||
if (!TextUtils.isEmpty(time)) {
|
||||
helper.setText(R.id.tv_time_dynamic_list, time);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(userDynamicInfo.getTag())) {
|
||||
helper.setText(R.id.tv_name_mini_world, userDynamicInfo.getTag())
|
||||
.setVisible(R.id.tv_name_mini_world, true);
|
||||
} else {
|
||||
helper.setVisible(R.id.tv_name_mini_world, false);
|
||||
}
|
||||
|
||||
ExpandableTextView etvTranslateContent = helper.getView(R.id.tv_content_dynamic_list);
|
||||
etvTranslateContent.setEventType(2);
|
||||
String content = userDynamicInfo.getContent();
|
||||
if (TextUtils.isEmpty(content)) {
|
||||
etvTranslateContent.setVisibility(View.GONE);
|
||||
} else {
|
||||
etvTranslateContent.setVisibility(View.VISIBLE);
|
||||
etvTranslateContent.setText(content, mCollapsedStatus, helper.getAdapterPosition(), mCollapsedHeightStatus);
|
||||
}
|
||||
|
||||
helper.setText(R.id.tv_comment_user_dynamic_list, getNumString(userDynamicInfo.getCommentCount()));
|
||||
|
||||
helper.addOnClickListener(R.id.tv_comment_user_dynamic_list)
|
||||
.addOnClickListener(R.id.iv_share_user_dynamic_list)
|
||||
.addOnClickListener(R.id.iv_more_user_dynamic_list)
|
||||
.addOnClickListener(R.id.cl_item_dynamic_list)
|
||||
.addOnClickListener(R.id.tv_name_mini_world);
|
||||
|
||||
setLikeCount(helper, userDynamicInfo.getLikeCount(), userDynamicInfo.isLike(), false);
|
||||
LinearLayout llLike = helper.getView(R.id.ll_like_user_dynamic_list);
|
||||
long worldId = userDynamicInfo.getWorldId();
|
||||
long dynamicId = userDynamicInfo.getDynamicId();
|
||||
// 点赞
|
||||
llLike.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
llLike.setEnabled(false);
|
||||
int status = userDynamicInfo.isLike() ? 0 : 1;
|
||||
DynamicModel.get().like(worldId, dynamicId, currentUid, status, 2)
|
||||
.compose(RxHelper.bindContext(mContext))
|
||||
.subscribe(new DontWarnObserver<String>() {
|
||||
@Override
|
||||
public void accept(String s, String error) {
|
||||
super.accept(s, error);
|
||||
llLike.setEnabled(true);
|
||||
if (error != null) {
|
||||
SingleToastUtil.showToast(error);
|
||||
} else {
|
||||
LogUtil.print(ResUtil.getString(R.string.community_user_dynamic_userdynamicadapter_01));
|
||||
if (status == 1) {
|
||||
userDynamicInfo.setLikeCount(userDynamicInfo.getLikeCount() + 1);
|
||||
} else {
|
||||
userDynamicInfo.setLikeCount(userDynamicInfo.getLikeCount() - 1);
|
||||
}
|
||||
userDynamicInfo.setLike(status == 1);
|
||||
setLikeCount(helper, userDynamicInfo.getLikeCount(), userDynamicInfo.isLike(), true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void setPhoto(BaseViewHolder helper, WorldDynamicBean userDynamicInfo) {
|
||||
RecyclerView rvImage = helper.getView(R.id.rv_img);
|
||||
rvImage.setNestedScrollingEnabled(false);
|
||||
try {
|
||||
rvImage.removeItemDecorationAt(0);
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
List<DynamicMedia> imageUrl = userDynamicInfo.getDynamicResList();
|
||||
if (imageUrl != null && imageUrl.size() > 0) {
|
||||
CalcSize calcSize = new CalcSize(imageBorder);
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvImage.getLayoutParams();
|
||||
if (imageUrl.size() > 1) {
|
||||
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
} else {
|
||||
//单图的情况,按比例显示
|
||||
DynamicMedia media = null;
|
||||
if (imageUrl.size() > 0) {
|
||||
media = imageUrl.get(0);
|
||||
}
|
||||
if (media == null) {
|
||||
return;
|
||||
}
|
||||
calcSize = ImageUiHelper.calcImage(media, imageBorder);
|
||||
params.width = calcSize.width;
|
||||
params.height = calcSize.height + divider;
|
||||
}
|
||||
rvImage.setLayoutParams(params);
|
||||
|
||||
rvImage.setVisibility(View.VISIBLE);
|
||||
rvImage.setLayoutManager(new GridLayoutManager(mContext, imageUrl.size() > 2 ? 3 : imageUrl.size()));
|
||||
rvImage.addItemDecoration(new GridSpacingItemDecoration(mContext, imageUrl.size() > 2 ? 3 : imageUrl.size(), 10));
|
||||
DynamicImageAdapter adapter = new DynamicImageAdapter(R.layout.item_user_dynamic_image, imageUrl);
|
||||
adapter.setSingleImageHeight(calcSize.height);
|
||||
adapter.setMTwoImageHeight(mTwoImageHeight);
|
||||
adapter.setMThreeImageHeight(mThreeImageHeight);
|
||||
adapter.setOnItemClickListener((adapter1, view, position) -> {
|
||||
PagerOption option = new PagerOption().setSave(true);
|
||||
BigPhotoActivity.start((Activity) mContext, ObjectTypeHelper.mediaToCustomList(imageUrl),
|
||||
position, option);
|
||||
}
|
||||
);
|
||||
rvImage.setAdapter(adapter);
|
||||
|
||||
} else {
|
||||
rvImage.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getNumString(int count) {
|
||||
String countStr;
|
||||
if (count < 0) {
|
||||
countStr = "0";
|
||||
} else if (count >= 1000) {
|
||||
countStr = "999+";
|
||||
} else {
|
||||
countStr = String.valueOf(count);
|
||||
}
|
||||
|
||||
return countStr;
|
||||
|
||||
}
|
||||
|
||||
private void setLikeCount(BaseViewHolder helper, int likeCount, boolean isLike, boolean isAnim) {
|
||||
TextView tvLike = helper.getView(R.id.tv_like_user_dynamic_list);
|
||||
String likeCountStr = getNumString(likeCount);
|
||||
tvLike.setText(likeCountStr);
|
||||
|
||||
ImageView ivLikeAnim = helper.getView(R.id.iv_like_anim);
|
||||
if (isLike) {
|
||||
if (isAnim) {
|
||||
AnimationDrawable drawable = (AnimationDrawable) mContext.getResources()
|
||||
.getDrawable(R.drawable.anim_list_dy_like);
|
||||
ivLikeAnim.setImageDrawable(drawable);
|
||||
drawable.stop();
|
||||
drawable.start();
|
||||
} else {
|
||||
ivLikeAnim.setImageResource(R.drawable.icon_dy_list_like_00013);
|
||||
}
|
||||
} else {
|
||||
ivLikeAnim.setImageResource(R.drawable.icon_dy_list_like_false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,258 @@
|
||||
package com.chwl.app.community.user_dynamic;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.UIHelper;
|
||||
import com.chwl.app.base.BaseMvpFragment;
|
||||
import com.chwl.app.common.widget.dialog.DialogManager;
|
||||
import com.chwl.app.community.dynamic.view.DynamicDetailActivity;
|
||||
import com.chwl.app.community.helper.ShareDynamicHelper;
|
||||
import com.chwl.app.ui.widget.ButtonItem;
|
||||
import com.chwl.core.XConstants;
|
||||
import com.chwl.core.auth.AuthModel;
|
||||
import com.chwl.core.community.bean.UserDynamicItem;
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
import com.chwl.library.base.factory.CreatePresenter;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@CreatePresenter(UserDynamicPresenter.class)
|
||||
public class UserDynamicFrg extends BaseMvpFragment<IUserDynamicView, UserDynamicPresenter> implements IUserDynamicView {
|
||||
|
||||
private UserDynamicAdapter mUserDynamicAdapter;
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
|
||||
private WorldDynamicBean currentUserDynamic;
|
||||
|
||||
public static UserDynamicFrg newInstance(long userId) {
|
||||
UserDynamicFrg userDynamicFrg = new UserDynamicFrg();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putLong("userId", userId);
|
||||
userDynamicFrg.setArguments(bundle);
|
||||
return userDynamicFrg;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitArguments(Bundle bundle) {
|
||||
super.onInitArguments(bundle);
|
||||
if (bundle != null) {
|
||||
long userId = bundle.getLong("userId", 0);
|
||||
getMvpPresenter().setUserId(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRootLayoutId() {
|
||||
return R.layout.frg_user_dynamic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFindViews() {
|
||||
recyclerView = mView.findViewById(R.id.recycler_view);
|
||||
swipeRefreshLayout = mView.findViewById(R.id.srl_user_dynamic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetListener() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiate() {
|
||||
getMvpPresenter().setFromUid(AuthModel.get().getCurrentUid());
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> getMvpPresenter().refreshData());
|
||||
|
||||
mUserDynamicAdapter = new UserDynamicAdapter(getActivity(), getMvpPresenter().getUserId());
|
||||
mUserDynamicAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
|
||||
@Override
|
||||
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
|
||||
List<UserDynamicItem> list = adapter.getData();
|
||||
if (position < list.size()) {
|
||||
UserDynamicItem userDynamicItem = list.get(position);
|
||||
if (userDynamicItem.getItemType() == UserDynamicItem.TYPE_DYNAMIC) {
|
||||
WorldDynamicBean userDynamicInfo = (WorldDynamicBean) userDynamicItem.getData();
|
||||
if (userDynamicInfo != null) {
|
||||
currentUserDynamic = userDynamicInfo;
|
||||
|
||||
switch (view.getId()) {
|
||||
// 点赞在adapter
|
||||
case R.id.tv_comment_user_dynamic_list:// 评论
|
||||
DynamicDetailActivity.start(mContext, userDynamicInfo.getDynamicId(),
|
||||
userDynamicInfo.getWorldId(), true, 2);
|
||||
break;
|
||||
|
||||
case R.id.iv_share_user_dynamic_list:// 分享
|
||||
if (currentUserDynamic.getStatus() == 1) {
|
||||
new ShareDynamicHelper(getActivity()).share(userDynamicInfo, userDynamicInfo.getWorldId());
|
||||
} else if (currentUserDynamic.getStatus() == 0) {
|
||||
toast(ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_03));
|
||||
} else if (currentUserDynamic.getStatus() == 2) {
|
||||
toast(ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_04));
|
||||
}
|
||||
break;
|
||||
|
||||
case R.id.iv_more_user_dynamic_list: // 更多
|
||||
showMoreOptions();
|
||||
break;
|
||||
|
||||
// case R.id.tv_name_mini_world: // 话题
|
||||
// TopicMainActivity.start(mContext,
|
||||
// String.valueOf(currentUserDynamic.getWorldId()));
|
||||
// break;
|
||||
|
||||
case R.id.cl_item_dynamic_list: // 动态详情
|
||||
if (!userDynamicInfo.isSystemDynamic()) {
|
||||
DynamicDetailActivity.start(mContext, userDynamicInfo.getDynamicId(),
|
||||
userDynamicInfo.getWorldId(), 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(mContext,
|
||||
LinearLayoutManager.VERTICAL, false));
|
||||
recyclerView.setAdapter(mUserDynamicAdapter);
|
||||
mUserDynamicAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
|
||||
@Override
|
||||
public void onLoadMoreRequested() {
|
||||
getMvpPresenter().loadMore();
|
||||
|
||||
}
|
||||
}, recyclerView);
|
||||
|
||||
getMvpPresenter().refreshData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshSuccess(List<WorldDynamicBean> list) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
if (mUserDynamicAdapter != null) {
|
||||
// mUserDynamicAdapter.resetStatus();
|
||||
List<UserDynamicItem> tempList = getMvpPresenter().modifyData(list, true);
|
||||
mUserDynamicAdapter.setNewData(tempList);
|
||||
mUserDynamicAdapter.loadMoreComplete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshFail(String error) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
List<UserDynamicItem> userDynamicItems = new ArrayList<>(1);
|
||||
userDynamicItems.add(new UserDynamicItem(UserDynamicItem.TYPE_EMPTY));
|
||||
if (mUserDynamicAdapter != null) {
|
||||
mUserDynamicAdapter.setNewData(userDynamicItems);
|
||||
mUserDynamicAdapter.setEnableLoadMore(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSuccess(List<WorldDynamicBean> list) {
|
||||
mUserDynamicAdapter.loadMoreComplete();
|
||||
if (mUserDynamicAdapter != null) {
|
||||
List<UserDynamicItem> tempList = getMvpPresenter().modifyData(list, false);
|
||||
mUserDynamicAdapter.addData(tempList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFail(String error) {
|
||||
mUserDynamicAdapter.loadMoreComplete();
|
||||
mUserDynamicAdapter.loadMoreEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSuccess(long dynamicId) {
|
||||
|
||||
if (mUserDynamicAdapter != null) {
|
||||
List<UserDynamicItem> list = mUserDynamicAdapter.getData();
|
||||
|
||||
int currentPosition = -1;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
WorldDynamicBean userDynamicInfo = (WorldDynamicBean) (list.get(i)).getData();
|
||||
// 第一个item为分割线,需要判断data是否为空
|
||||
if (userDynamicInfo != null && userDynamicInfo.getDynamicId() == dynamicId) {
|
||||
currentPosition = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentPosition > -1 && currentPosition < list.size()) {
|
||||
mUserDynamicAdapter.remove(currentPosition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFail(String error) {
|
||||
toast(error);
|
||||
}
|
||||
|
||||
private void showMoreOptions() {
|
||||
if (getMvpPresenter().isOwner()) {
|
||||
showDeleteOption();
|
||||
|
||||
} else {
|
||||
showReportOption();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void showReportOption() {
|
||||
ButtonItem buttonItem1 = new ButtonItem(ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_09), () -> {
|
||||
if (currentUserDynamic != null) {
|
||||
UIHelper.showReportPage(mContext, currentUserDynamic.getUid(),
|
||||
XConstants.REPORT_TYPE_PERSONAL_DYNAMIC);
|
||||
}
|
||||
});
|
||||
List<ButtonItem> buttonItems = new ArrayList<>();
|
||||
buttonItems.add(buttonItem1);
|
||||
getDialogManager().showCommonPopupDialog(buttonItems, ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_010), false);
|
||||
|
||||
}
|
||||
|
||||
private void showDeleteOption() {
|
||||
ButtonItem buttonItem1 = new ButtonItem(ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_011), () -> {
|
||||
secondDeleteDialog();
|
||||
});
|
||||
List<ButtonItem> buttonItems = new ArrayList<>();
|
||||
buttonItems.add(buttonItem1);
|
||||
getDialogManager().showCommonPopupDialog(buttonItems, ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_012), false);
|
||||
}
|
||||
|
||||
private void secondDeleteDialog() {
|
||||
getDialogManager().showOkCancelDialog(ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_013),
|
||||
ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_014),
|
||||
ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_015), ResUtil.getString(R.string.community_user_dynamic_userdynamicfrg_016),
|
||||
new DialogManager.OkCancelDialogListener() {
|
||||
@Override
|
||||
public void onOk() {
|
||||
if (currentUserDynamic != null) {
|
||||
getMvpPresenter().deleteDynamic(currentUserDynamic.getWorldId(),
|
||||
currentUserDynamic.getDynamicId());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,146 @@
|
||||
package com.chwl.app.community.user_dynamic;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.base.BaseMvpPresenter;
|
||||
import com.chwl.core.Constants;
|
||||
import com.chwl.core.community.bean.UserDynamicItem;
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
import com.chwl.core.community.dynamic.DynamicModel;
|
||||
import com.chwl.core.user.UserDynamicModel;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.functions.BiConsumer;
|
||||
|
||||
@Keep
|
||||
public class UserDynamicPresenter extends BaseMvpPresenter<IUserDynamicView> {
|
||||
|
||||
private int page = Constants.PAGE_START;
|
||||
private int pageSize = Constants.PAGE_SIZE;
|
||||
private String types = "0,2"; // 0-纯文本 1-语音 2-图片 3-视频
|
||||
private UserDynamicModel userDynamicModel = new UserDynamicModel();
|
||||
private long userId;
|
||||
private long fromUid;
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
public void refreshData() {
|
||||
page = Constants.PAGE_START;
|
||||
|
||||
userDynamicModel.getMyDynamic(userId, types, page, pageSize, fromUid)
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe(new BiConsumer<List<WorldDynamicBean>, Throwable>() {
|
||||
@Override
|
||||
public void accept(List<WorldDynamicBean> userDynamicInfos, Throwable throwable) throws Exception {
|
||||
if (throwable == null) {
|
||||
if (userDynamicInfos != null && userDynamicInfos.size() > 0) {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.refreshSuccess(userDynamicInfos);
|
||||
}
|
||||
} else {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.refreshFail(ResUtil.getString(R.string.community_user_dynamic_userdynamicpresenter_01));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.refreshFail(throwable.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
public void loadMore() {
|
||||
page++;
|
||||
|
||||
userDynamicModel.getMyDynamic(userId, types, page, pageSize, fromUid)
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe(new BiConsumer<List<WorldDynamicBean>, Throwable>() {
|
||||
@Override
|
||||
public void accept(List<WorldDynamicBean> userDynamicInfos, Throwable throwable) throws Exception {
|
||||
if (throwable == null) {
|
||||
if (userDynamicInfos != null && userDynamicInfos.size() > 0) {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.loadSuccess(userDynamicInfos);
|
||||
}
|
||||
} else {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.loadFail(ResUtil.getString(R.string.community_user_dynamic_userdynamicpresenter_02));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
page--;
|
||||
if (mMvpView != null) {
|
||||
mMvpView.loadFail(throwable.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<UserDynamicItem> modifyData(List<WorldDynamicBean> list, boolean isFirst) {
|
||||
List<UserDynamicItem> tempList = new ArrayList<>();
|
||||
if (isFirst) {
|
||||
UserDynamicItem userDynamicItem = new UserDynamicItem(UserDynamicItem.TYPE_FIRST_DIVIDER);
|
||||
tempList.add(userDynamicItem);
|
||||
}
|
||||
for (WorldDynamicBean userDynamicInfo : list) {
|
||||
UserDynamicItem userDynamicItem = new UserDynamicItem(UserDynamicItem.TYPE_DYNAMIC,
|
||||
userDynamicInfo);
|
||||
tempList.add(userDynamicItem);
|
||||
}
|
||||
|
||||
return tempList;
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
public void deleteDynamic(long worldId, long dynamicId) {
|
||||
DynamicModel.get().delete(worldId, dynamicId)
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe(new BiConsumer<String, Throwable>() {
|
||||
@Override
|
||||
public void accept(String s, Throwable throwable) throws Exception {
|
||||
|
||||
if (throwable == null) {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.deleteSuccess(dynamicId);
|
||||
}
|
||||
} else {
|
||||
if (mMvpView != null) {
|
||||
mMvpView.deleteFail(throwable.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setFromUid(long fromUid) {
|
||||
this.fromUid = fromUid;
|
||||
}
|
||||
|
||||
public boolean isOwner() {
|
||||
return fromUid == userId;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
package com.chwl.app.community.utils;
|
||||
|
||||
import com.chwl.core.community.bean.DynamicMedia;
|
||||
import com.example.matisse.internal.entity.CustomItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/19
|
||||
*/
|
||||
public class ObjectTypeHelper {
|
||||
|
||||
public static List<String> customToStringList(List<CustomItem> paramsList) {
|
||||
List<String> resultList = new ArrayList<>();
|
||||
if (paramsList == null) {
|
||||
return resultList;
|
||||
}
|
||||
for (CustomItem item : paramsList) {
|
||||
resultList.add(item.getPath());
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public static List<DynamicMedia> customToMediaList(List<CustomItem> paramsList) {
|
||||
List<DynamicMedia> resultList = new ArrayList<>();
|
||||
if (paramsList == null) {
|
||||
return resultList;
|
||||
}
|
||||
for (CustomItem item : paramsList) {
|
||||
DynamicMedia media = new DynamicMedia();
|
||||
media.setLocalFilePath(item.getPath());
|
||||
media.setWidth(item.getWidth());
|
||||
media.setHeight(item.getHeight());
|
||||
media.setFormat(item.getFormat());
|
||||
resultList.add(media);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public static List<CustomItem> stringToCustomList(List<String> paramsList) {
|
||||
List<CustomItem> resultList = new ArrayList<>();
|
||||
if (paramsList == null) {
|
||||
return resultList;
|
||||
}
|
||||
for (String item : paramsList) {
|
||||
resultList.add(new CustomItem(item, 0));
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public static ArrayList<CustomItem> mediaToCustomList(List<DynamicMedia> paramsList) {
|
||||
ArrayList<CustomItem> resultList = new ArrayList<>();
|
||||
if (paramsList == null) {
|
||||
return resultList;
|
||||
}
|
||||
for (DynamicMedia media : paramsList) {
|
||||
CustomItem item = new CustomItem();
|
||||
item.setPath(media.getResUrl());
|
||||
item.setFileType(CustomItem.UNKOWN);
|
||||
if (media.isJpgOrPng()) {
|
||||
item.setFileType(CustomItem.IMAGE_NORMAL);
|
||||
} else if (media.isGif()) {
|
||||
item.setFileType(CustomItem.GIF);
|
||||
}
|
||||
item.setFormat(media.getFormat());
|
||||
resultList.add(item);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public static ArrayList<CustomItem> pathToCustomItems(String path) {
|
||||
ArrayList<CustomItem> resultList = new ArrayList<>();
|
||||
CustomItem item = new CustomItem();
|
||||
item.setPath(path);
|
||||
item.setFileType(CustomItem.UNKOWN);
|
||||
resultList.add(item);
|
||||
return resultList;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package com.chwl.app.community.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import com.chwl.app.R
|
||||
import com.chwl.app.common.widget.CustomImageSpan
|
||||
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil
|
||||
import com.chwl.library.utils.ResUtil
|
||||
|
||||
object TopicUpTextWrapper {
|
||||
|
||||
//置顶 后期优化结构
|
||||
fun wrapUp(originText: CharSequence, context: Context): SpannableStringBuilder? {
|
||||
val drawable: Drawable = context.resources.getDrawable(R.drawable.topic_up_drawable)
|
||||
drawable.setBounds(0, 0, UIUtil.dip2px(context, 10.0), UIUtil.dip2px(context, 12.0))
|
||||
val builder = SpannableStringBuilder()
|
||||
builder.append("-")
|
||||
builder.append(ResUtil.getString(R.string.community_utils_topicuptextwrapper_01))
|
||||
builder.setSpan(CustomImageSpan(drawable), 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
builder.setSpan(
|
||||
ForegroundColorSpan(Color.parseColor("#E84C46")),
|
||||
1,
|
||||
builder.length,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
builder.append(" ")
|
||||
builder.append(originText)
|
||||
return builder
|
||||
}
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
package com.chwl.app.community.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.netease.nim.uikit.support.glide.GlideApp;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.ui.utils.ImageLoadUtils;
|
||||
import com.chwl.app.utils.NamePlateHelper;
|
||||
import com.chwl.app.utils.RegexUtil;
|
||||
import com.chwl.app.utils.TimeUiUtils;
|
||||
import com.chwl.app.view.GenderAgeTextView;
|
||||
import com.chwl.app.vip.util.VipHelper;
|
||||
import com.chwl.core.user.bean.BaseUserInfo;
|
||||
import com.chwl.library.widget.ShapeConstrainLayout;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/26
|
||||
*/
|
||||
public class DynamicNickDetailWidget extends ShapeConstrainLayout {
|
||||
|
||||
private TextView tvNick;
|
||||
private GenderAgeTextView tvGenderAge;
|
||||
private ImageView ivVipIcon;
|
||||
|
||||
private ImageView ivUserWealthLevel;
|
||||
private ImageView ivUserCharmLevel;
|
||||
|
||||
private ConstraintLayout inOfficialMask;
|
||||
|
||||
private TextView tvTime;
|
||||
|
||||
private Context context;
|
||||
|
||||
public DynamicNickDetailWidget(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public DynamicNickDetailWidget(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public DynamicNickDetailWidget(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
this.context = context;
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
inflate(context, R.layout.layout_dy_nick_detail, this);
|
||||
|
||||
tvNick = findViewById(R.id.tv_nick);
|
||||
tvGenderAge = findViewById(R.id.tv_gender_age);
|
||||
ivVipIcon = findViewById(R.id.iv_vip_icon);
|
||||
ivUserWealthLevel = findViewById(R.id.iv_user_wealth_level);
|
||||
ivUserCharmLevel = findViewById(R.id.iv_user_charm_level);
|
||||
inOfficialMask = findViewById(R.id.in_official_mask);
|
||||
tvTime = findViewById(R.id.tv_time);
|
||||
}
|
||||
|
||||
public void setNickColor(@ColorInt int color) {
|
||||
if (tvNick != null) {
|
||||
tvNick.setTextColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTimeColor(@ColorInt int color) {
|
||||
if (tvTime != null) {
|
||||
tvTime.setTextColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public void setData(BaseUserInfo info) {
|
||||
tvNick.setText(RegexUtil.getPrintableString(info.getNick()));
|
||||
tvGenderAge.setText(String.valueOf(info.getAge()));
|
||||
tvGenderAge.setGender(info.getGender());
|
||||
//财富等级
|
||||
ImageLoadUtils.loadImage(context, info.getExperLevelPic(), ivUserWealthLevel);
|
||||
//魅力等级
|
||||
ImageLoadUtils.loadImage(context, info.getCharmLevelPic(), ivUserCharmLevel);
|
||||
//铭牌
|
||||
NamePlateHelper.INSTANCE.load(inOfficialMask, inOfficialMask.findViewById(R.id.tv_official_mask), inOfficialMask.findViewById(R.id.iv_official_mask), info.getNameplateWord(), info.getNameplatePic(), info.isCustomWord());
|
||||
VipHelper.loadVipIcon(ivVipIcon, info.getUserVipInfoVO());
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
tvTime.setVisibility(View.VISIBLE);
|
||||
tvTime.setText(TimeUiUtils.getDynamicUi(time));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
* Copyright 2014 Manabu Shimobe
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.chwl.app.community.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.Transformation;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
|
||||
public class ExpandableTextView extends LinearLayout implements View.OnClickListener {
|
||||
|
||||
private static final String TAG = ExpandableTextView.class.getSimpleName();
|
||||
|
||||
private static final int EXPAND_INDICATOR_IMAGE_BUTTON = 0;
|
||||
|
||||
private static final int EXPAND_INDICATOR_TEXT_VIEW = 1;
|
||||
|
||||
private static final int DEFAULT_TOGGLE_TYPE = EXPAND_INDICATOR_IMAGE_BUTTON;
|
||||
|
||||
/* The default number of lines */
|
||||
private static final int MAX_COLLAPSED_LINES = 8;
|
||||
|
||||
/* The default animation duration */
|
||||
private static final int DEFAULT_ANIM_DURATION = 300;
|
||||
|
||||
/* The default alpha value when the animation starts */
|
||||
private static final float DEFAULT_ANIM_ALPHA_START = 0.7f;
|
||||
|
||||
public TextView mTv;
|
||||
|
||||
protected View mToggleView; // View to expand/collapse
|
||||
|
||||
private boolean mRelayout;
|
||||
|
||||
private boolean mCollapsed = true; // Show short version as default.
|
||||
|
||||
private int mCollapsedHeight;
|
||||
|
||||
private int mTextHeightWithMaxLines;
|
||||
|
||||
private int mMaxCollapsedLines;
|
||||
|
||||
private int mMarginBetweenTxtAndBottom;
|
||||
|
||||
private ExpandIndicatorController mExpandIndicatorController;
|
||||
|
||||
private int mAnimationDuration;
|
||||
|
||||
private float mAnimAlphaStart;
|
||||
|
||||
private boolean mAnimating;
|
||||
|
||||
@IdRes
|
||||
private int mExpandableTextId = R.id.expandable_text;
|
||||
|
||||
@IdRes
|
||||
private int mExpandCollapseToggleId = R.id.expand_collapse;
|
||||
|
||||
private boolean mExpandToggleOnTextClick;
|
||||
|
||||
/* Listener for callback */
|
||||
private OnExpandStateChangeListener mListener;
|
||||
|
||||
/* For saving collapsed status when used in ListView */
|
||||
private SparseBooleanArray mCollapsedStatus;
|
||||
private int mPosition;
|
||||
/**
|
||||
* 用于列表,文字展开之后记录固定值:mCollapsedHeight, mMarginBetweenTxtAndBottom
|
||||
* 点击收起按钮,避免固定值为0,文字不展示的情况
|
||||
*/
|
||||
private SparseIntArray mCollapsedHeightStatus;
|
||||
|
||||
private int mImageToggleId;
|
||||
private ImageView mIvToggle;
|
||||
/**
|
||||
* 1、世界动态 2 个人主页 3-动态详情 4-动态广场
|
||||
*/
|
||||
@Setter
|
||||
private int eventType;
|
||||
|
||||
public ExpandableTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ExpandableTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrientation(int orientation) {
|
||||
if (LinearLayout.HORIZONTAL == orientation) {
|
||||
throw new IllegalArgumentException("ExpandableTextView only supports Vertical Orientation.");
|
||||
}
|
||||
super.setOrientation(orientation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mToggleView.getVisibility() != View.VISIBLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCollapsed = !mCollapsed;
|
||||
mExpandIndicatorController.changeState(mCollapsed);
|
||||
|
||||
if (mCollapsedStatus != null) {
|
||||
mCollapsedStatus.put(mPosition, mCollapsed);
|
||||
}
|
||||
|
||||
// mark that the animation is in progress
|
||||
mAnimating = true;
|
||||
|
||||
Animation animation;
|
||||
|
||||
if (mCollapsed) {
|
||||
int height = getHeight();
|
||||
if (mCollapsedHeight == 0 && mCollapsedHeightStatus != null) {
|
||||
mCollapsedHeight = mCollapsedHeightStatus.get(0);
|
||||
}
|
||||
|
||||
if (mMarginBetweenTxtAndBottom <= 0 && mCollapsedHeightStatus != null) {
|
||||
mMarginBetweenTxtAndBottom = mCollapsedHeightStatus.get(1);
|
||||
}
|
||||
|
||||
animation = new ExpandCollapseAnimation(this, height, mCollapsedHeight);
|
||||
} else {
|
||||
String label = ResUtil.getString(R.string.community_widget_expandabletextview_01);
|
||||
if (eventType == 2) {
|
||||
label = ResUtil.getString(R.string.community_widget_expandabletextview_02);
|
||||
} else if (eventType == 3) {
|
||||
label = ResUtil.getString(R.string.community_widget_expandabletextview_03);
|
||||
} else if (eventType == 4) {
|
||||
label = ResUtil.getString(R.string.community_widget_expandabletextview_04);
|
||||
}
|
||||
|
||||
int height = getHeight();
|
||||
int tvHeight = mTv.getHeight();
|
||||
animation = new ExpandCollapseAnimation(this, height, height +
|
||||
mTextHeightWithMaxLines - tvHeight);
|
||||
|
||||
if (mCollapsedHeight > 0 && mCollapsedHeightStatus != null) {
|
||||
mCollapsedHeightStatus.put(0, mCollapsedHeight);
|
||||
}
|
||||
if (mMarginBetweenTxtAndBottom > 0 && mCollapsedHeightStatus != null) {
|
||||
mCollapsedHeightStatus.put(1, mMarginBetweenTxtAndBottom);
|
||||
}
|
||||
}
|
||||
|
||||
animation.setFillAfter(true);
|
||||
animation.setAnimationListener(new Animation.AnimationListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {
|
||||
applyAlphaAnimation(mTv, mAnimAlphaStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
// clear animation here to avoid repeated applyTransformation() calls
|
||||
clearAnimation();
|
||||
// clear the animation flag
|
||||
mAnimating = false;
|
||||
|
||||
// notify the listener
|
||||
if (mListener != null) {
|
||||
mListener.onExpandStateChanged(mTv, !mCollapsed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animation animation) {
|
||||
}
|
||||
});
|
||||
|
||||
clearAnimation();
|
||||
startAnimation(animation);
|
||||
|
||||
if (mImageToggleId != 0) {
|
||||
mIvToggle.animate().rotationBy(180).setDuration(DEFAULT_ANIM_DURATION).start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
// while an animation is in progress, intercept all the touch events to children to
|
||||
// prevent extra clicks during the animation
|
||||
return mAnimating;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
findViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// If no change, measure and return
|
||||
if (!mRelayout || getVisibility() == View.GONE) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
return;
|
||||
}
|
||||
mRelayout = false;
|
||||
|
||||
// Setup with optimistic case
|
||||
// i.e. Everything fits. No button needed
|
||||
mToggleView.setVisibility(View.GONE);
|
||||
if (mIvToggle != null) {
|
||||
mIvToggle.setVisibility(GONE);
|
||||
}
|
||||
mTv.setMaxLines(Integer.MAX_VALUE);
|
||||
|
||||
// Measure
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
// If the text fits in collapsed mode, we are done.
|
||||
if (mTv.getLineCount() <= mMaxCollapsedLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Saves the text height w/ max lines
|
||||
mTextHeightWithMaxLines = getRealTextViewHeight(mTv);
|
||||
|
||||
// Doesn't fit in collapsed mode. Collapse text view as needed. Show
|
||||
// button.
|
||||
if (mCollapsed) {
|
||||
mTv.setMaxLines(mMaxCollapsedLines);
|
||||
}
|
||||
mToggleView.setVisibility(View.VISIBLE);
|
||||
if (mIvToggle != null) {
|
||||
mIvToggle.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
// Re-measure with new setup
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
if (mCollapsed) {
|
||||
// Gets the margin between the TextView's bottom and the ViewGroup's bottom
|
||||
mTv.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mMarginBetweenTxtAndBottom = getHeight() - mTv.getHeight();
|
||||
}
|
||||
});
|
||||
// Saves the collapsed height of this ViewGroup
|
||||
mCollapsedHeight = getMeasuredHeight();
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnExpandStateChangeListener(@Nullable OnExpandStateChangeListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
public void setText(@Nullable CharSequence text) {
|
||||
mRelayout = true;
|
||||
mTv.setText(text);
|
||||
setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE);
|
||||
clearAnimation();
|
||||
getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
public void setText(@Nullable CharSequence text, @NonNull SparseBooleanArray collapsedStatus, int position) {
|
||||
mCollapsedStatus = collapsedStatus;
|
||||
mPosition = position;
|
||||
boolean isCollapsed = collapsedStatus.get(position, true);
|
||||
clearAnimation();
|
||||
mCollapsed = isCollapsed;
|
||||
mExpandIndicatorController.changeState(mCollapsed);
|
||||
setText(text);
|
||||
}
|
||||
|
||||
public void setText(@Nullable CharSequence text, @NonNull SparseBooleanArray collapsedStatus, int position,
|
||||
@NonNull SparseIntArray mCollapsedHeightStatus) {
|
||||
this.mCollapsedHeightStatus = mCollapsedHeightStatus;
|
||||
setText(text, collapsedStatus, position);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CharSequence getText() {
|
||||
if (mTv == null) {
|
||||
return "";
|
||||
}
|
||||
return mTv.getText();
|
||||
}
|
||||
|
||||
private void init(AttributeSet attrs) {
|
||||
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ExpandableTextView);
|
||||
mMaxCollapsedLines = typedArray.getInt(R.styleable.ExpandableTextView_maxCollapsedLines, MAX_COLLAPSED_LINES);
|
||||
mAnimationDuration = typedArray.getInt(R.styleable.ExpandableTextView_animDuration, DEFAULT_ANIM_DURATION);
|
||||
mAnimAlphaStart = typedArray.getFloat(R.styleable.ExpandableTextView_animAlphaStart, DEFAULT_ANIM_ALPHA_START);
|
||||
mExpandableTextId = typedArray.getResourceId(R.styleable.ExpandableTextView_expandableTextId, R.id.expandable_text);
|
||||
mExpandCollapseToggleId = typedArray.getResourceId(R.styleable.ExpandableTextView_expandCollapseToggleId, R.id.expand_collapse);
|
||||
mExpandToggleOnTextClick = typedArray.getBoolean(R.styleable.ExpandableTextView_expandToggleOnTextClick, true);
|
||||
|
||||
mExpandIndicatorController = setupExpandToggleController(getContext(), typedArray);
|
||||
|
||||
mImageToggleId = typedArray.getResourceId(R.styleable.ExpandableTextView_imageToggleId, 0);
|
||||
|
||||
typedArray.recycle();
|
||||
|
||||
// enforces vertical orientation
|
||||
setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
// default visibility is gone
|
||||
setVisibility(GONE);
|
||||
}
|
||||
|
||||
private void findViews() {
|
||||
mTv = (TextView) findViewById(mExpandableTextId);
|
||||
if (mExpandToggleOnTextClick) {
|
||||
mTv.setOnClickListener(this);
|
||||
} else {
|
||||
mTv.setOnClickListener(null);
|
||||
}
|
||||
mToggleView = findViewById(mExpandCollapseToggleId);
|
||||
mExpandIndicatorController.setView(mToggleView);
|
||||
mExpandIndicatorController.changeState(mCollapsed);
|
||||
mToggleView.setOnClickListener(this);
|
||||
if (mImageToggleId != 0) {
|
||||
mIvToggle = findViewById(mImageToggleId);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPostHoneycomb() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
|
||||
}
|
||||
|
||||
private static boolean isPostLolipop() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
private static void applyAlphaAnimation(View view, float alpha) {
|
||||
if (isPostHoneycomb()) {
|
||||
view.setAlpha(alpha);
|
||||
} else {
|
||||
AlphaAnimation alphaAnimation = new AlphaAnimation(alpha, alpha);
|
||||
// make it instant
|
||||
alphaAnimation.setDuration(0);
|
||||
alphaAnimation.setFillAfter(true);
|
||||
view.startAnimation(alphaAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private static Drawable getDrawable(@NonNull Context context, @DrawableRes int resId) {
|
||||
Resources resources = context.getResources();
|
||||
if (isPostLolipop()) {
|
||||
return resources.getDrawable(resId, context.getTheme());
|
||||
} else {
|
||||
return resources.getDrawable(resId);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getRealTextViewHeight(@NonNull TextView textView) {
|
||||
int textHeight = textView.getLayout().getLineTop(textView.getLineCount());
|
||||
int padding = textView.getCompoundPaddingTop() + textView.getCompoundPaddingBottom();
|
||||
return textHeight + padding;
|
||||
}
|
||||
|
||||
private static ExpandIndicatorController setupExpandToggleController(@NonNull Context context, TypedArray typedArray) {
|
||||
final int expandToggleType = typedArray.getInt(R.styleable.ExpandableTextView_expandToggleType, DEFAULT_TOGGLE_TYPE);
|
||||
final ExpandIndicatorController expandIndicatorController;
|
||||
switch (expandToggleType) {
|
||||
case EXPAND_INDICATOR_IMAGE_BUTTON:
|
||||
Drawable expandDrawable = typedArray.getDrawable(R.styleable.ExpandableTextView_expandIndicator);
|
||||
Drawable collapseDrawable = typedArray.getDrawable(R.styleable.ExpandableTextView_collapseIndicator);
|
||||
|
||||
if (expandDrawable == null) {
|
||||
expandDrawable = getDrawable(context, R.drawable.ic_back_dynamic);
|
||||
}
|
||||
if (collapseDrawable == null) {
|
||||
collapseDrawable = getDrawable(context, R.drawable.ic_back_dynamic);
|
||||
}
|
||||
expandIndicatorController = new ImageButtonExpandController(expandDrawable, collapseDrawable);
|
||||
break;
|
||||
case EXPAND_INDICATOR_TEXT_VIEW:
|
||||
String expandText = typedArray.getString(R.styleable.ExpandableTextView_expandIndicator);
|
||||
String collapseText = typedArray.getString(R.styleable.ExpandableTextView_collapseIndicator);
|
||||
expandIndicatorController = new TextViewExpandController(expandText, collapseText);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Must be of enum: ExpandableTextView_expandToggleType, one of EXPAND_INDICATOR_IMAGE_BUTTON or EXPAND_INDICATOR_TEXT_VIEW.");
|
||||
}
|
||||
|
||||
return expandIndicatorController;
|
||||
}
|
||||
|
||||
class ExpandCollapseAnimation extends Animation {
|
||||
private final View mTargetView;
|
||||
private final int mStartHeight;
|
||||
private final int mEndHeight;
|
||||
|
||||
public ExpandCollapseAnimation(View view, int startHeight, int endHeight) {
|
||||
mTargetView = view;
|
||||
mStartHeight = startHeight;
|
||||
mEndHeight = endHeight;
|
||||
setDuration(mAnimationDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
||||
final int newHeight = (int) ((mEndHeight - mStartHeight) * interpolatedTime + mStartHeight);
|
||||
mTv.setMaxHeight(newHeight - mMarginBetweenTxtAndBottom);
|
||||
if (Float.compare(mAnimAlphaStart, 1.0f) != 0) {
|
||||
applyAlphaAnimation(mTv, mAnimAlphaStart + interpolatedTime * (1.0f - mAnimAlphaStart));
|
||||
}
|
||||
mTargetView.getLayoutParams().height = newHeight;
|
||||
mTargetView.requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(int width, int height, int parentWidth, int parentHeight) {
|
||||
super.initialize(width, height, parentWidth, parentHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willChangeBounds() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnExpandStateChangeListener {
|
||||
/**
|
||||
* Called when the expand/collapse animation has been finished
|
||||
*
|
||||
* @param textView - TextView being expanded/collapsed
|
||||
* @param isExpanded - true if the TextView has been expanded
|
||||
*/
|
||||
void onExpandStateChanged(TextView textView, boolean isExpanded);
|
||||
}
|
||||
|
||||
public interface ExpandIndicatorController {
|
||||
void changeState(boolean collapsed);
|
||||
|
||||
void setView(View toggleView);
|
||||
}
|
||||
|
||||
static class ImageButtonExpandController implements ExpandIndicatorController {
|
||||
|
||||
private final Drawable mExpandDrawable;
|
||||
private final Drawable mCollapseDrawable;
|
||||
|
||||
private ImageButton mImageButton;
|
||||
|
||||
public ImageButtonExpandController(Drawable expandDrawable, Drawable collapseDrawable) {
|
||||
mExpandDrawable = expandDrawable;
|
||||
mCollapseDrawable = collapseDrawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeState(boolean collapsed) {
|
||||
mImageButton.setImageDrawable(collapsed ? mExpandDrawable : mCollapseDrawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setView(View toggleView) {
|
||||
mImageButton = (ImageButton) toggleView;
|
||||
}
|
||||
}
|
||||
|
||||
static class TextViewExpandController implements ExpandIndicatorController {
|
||||
|
||||
private final String mExpandText;
|
||||
private final String mCollapseText;
|
||||
|
||||
private TextView mTextView;
|
||||
|
||||
public TextViewExpandController(String expandText, String collapseText) {
|
||||
mExpandText = expandText;
|
||||
mCollapseText = collapseText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeState(boolean collapsed) {
|
||||
mTextView.setText(collapsed ? mExpandText : mCollapseText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setView(View toggleView) {
|
||||
mTextView = (TextView) toggleView;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,135 @@
|
||||
package com.chwl.app.community.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.community.helper.CalcSize;
|
||||
import com.chwl.app.community.helper.ImageUiHelper;
|
||||
import com.chwl.app.photo.BigPhotoActivity;
|
||||
import com.chwl.app.photo.DynamicImageAdapter;
|
||||
import com.chwl.app.community.utils.ObjectTypeHelper;
|
||||
import com.chwl.app.photo.PagerOption;
|
||||
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
|
||||
import com.chwl.app.ui.widget.recyclerview.decoration.GridVItemDecoration;
|
||||
import com.chwl.core.community.bean.DynamicMedia;
|
||||
import com.chwl.core.community.bean.WorldDynamicBean;
|
||||
import com.chwl.library.utils.ListUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2020/1/8
|
||||
*/
|
||||
public class GridImageWidget extends FrameLayout {
|
||||
|
||||
@Setter
|
||||
private int maxWidth;
|
||||
|
||||
@Setter
|
||||
private int dividerDp;
|
||||
|
||||
private RecyclerView rvImage;
|
||||
|
||||
private Context context;
|
||||
/**
|
||||
* recycleView格子布局时的宽度
|
||||
* 用于计算item的高度
|
||||
*/
|
||||
@Setter
|
||||
private int rvWidth;
|
||||
|
||||
public GridImageWidget(@NonNull Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public GridImageWidget(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public GridImageWidget(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
inflate(context, R.layout.widget_grid_image, this);
|
||||
this.context = context;
|
||||
maxWidth = UIUtil.getScreenWidth(context) * ImageUiHelper.BORDER_MIN / ImageUiHelper.BORDER_MAX;
|
||||
dividerDp = 10;
|
||||
rvImage = findViewById(R.id.rv_image);
|
||||
}
|
||||
|
||||
public void setData(WorldDynamicBean item, int topMargin) {
|
||||
setVisibility(View.GONE);
|
||||
List<DynamicMedia> dynamicMediaList = item.getDynamicResList();
|
||||
if (item.getType() == WorldDynamicBean.TYPE_IMAGE
|
||||
&& dynamicMediaList != null && dynamicMediaList.size() > 0) {
|
||||
setData(dynamicMediaList, topMargin);
|
||||
}
|
||||
}
|
||||
|
||||
public void setData(List<DynamicMedia> imageUrl, int topMargin) {
|
||||
setVisibility(GONE);
|
||||
if (ListUtils.isListEmpty(imageUrl)) {
|
||||
return;
|
||||
}
|
||||
setVisibility(VISIBLE);
|
||||
|
||||
CalcSize calcSize = new CalcSize(maxWidth);
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvImage.getLayoutParams();
|
||||
if (imageUrl.size() > 1) {
|
||||
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
} else {
|
||||
//单图的情况,按比例显示
|
||||
DynamicMedia media = null;
|
||||
if (imageUrl.size() > 0) {
|
||||
media = imageUrl.get(0);
|
||||
}
|
||||
if (media == null) {
|
||||
return;
|
||||
}
|
||||
calcSize = ImageUiHelper.calcImage(media, maxWidth);
|
||||
params.width = calcSize.width;
|
||||
params.height = calcSize.height;
|
||||
}
|
||||
params.topMargin = topMargin;
|
||||
rvImage.setLayoutParams(params);
|
||||
rvImage.setNestedScrollingEnabled(false);
|
||||
int spanCount = imageUrl.size() > 2 ? 3 : imageUrl.size();
|
||||
if (rvImage.getTag() != null) {
|
||||
if (rvImage.getTag() instanceof RecyclerView.ItemDecoration) {
|
||||
rvImage.removeItemDecoration((RecyclerView.ItemDecoration) rvImage.getTag());
|
||||
}
|
||||
rvImage.setTag(null);
|
||||
}
|
||||
GridVItemDecoration decoration = new GridVItemDecoration(context, dividerDp, spanCount);
|
||||
rvImage.setTag(decoration);
|
||||
rvImage.addItemDecoration(decoration);
|
||||
|
||||
rvImage.setLayoutManager(new GridLayoutManager(context, spanCount));
|
||||
DynamicImageAdapter adapter = new DynamicImageAdapter(R.layout.item_grid_image_widget, imageUrl);
|
||||
//当2列时的高度
|
||||
adapter.setMTwoImageHeight((rvWidth - UIUtil.dip2px(context, 10)) / 2);
|
||||
//当3列时的高度
|
||||
adapter.setMThreeImageHeight((rvWidth - UIUtil.dip2px(context, 20)) / 3);
|
||||
adapter.setSingleImageHeight(calcSize.height);
|
||||
adapter.setOnItemClickListener((adapter1, view, position) -> {
|
||||
PagerOption option = new PagerOption().setSave(true);
|
||||
BigPhotoActivity.start((Activity) context, ObjectTypeHelper.mediaToCustomList(imageUrl),
|
||||
position, option);
|
||||
}
|
||||
);
|
||||
rvImage.setAdapter(adapter);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
package com.chwl.app.community.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.annotation.Nullable
|
||||
import com.chwl.app.ui.utils.ImageLoadUtilsV2
|
||||
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil
|
||||
|
||||
class TopicLabelWidget(context: Context, @Nullable attrs: AttributeSet) :
|
||||
LinearLayout(context, attrs) {
|
||||
private val leftMargin = UIUtil.dip2px(context, 4.toDouble())
|
||||
|
||||
init {
|
||||
orientation = HORIZONTAL
|
||||
}
|
||||
|
||||
fun setLabels(labels: List<String>) {
|
||||
if (childCount != 0) {
|
||||
removeAllViews()
|
||||
}
|
||||
val width = UIUtil.dip2px(context, 28.0)
|
||||
val height = UIUtil.dip2px(context, 14.0)
|
||||
for ((index, item) in labels.withIndex()) {
|
||||
val imageView = ImageView(context)
|
||||
val layoutParams = MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
|
||||
if (index != 0) {
|
||||
layoutParams.leftMargin = leftMargin
|
||||
}
|
||||
imageView.maxWidth = width
|
||||
imageView.maxHeight = height
|
||||
imageView.scaleType=ImageView.ScaleType.CENTER_INSIDE
|
||||
imageView.layoutParams = layoutParams
|
||||
addView(imageView)
|
||||
ImageLoadUtilsV2.loadImage(imageView, item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateLayoutParams(lp: ViewGroup.LayoutParams?): LayoutParams {
|
||||
if (lp is LayoutParams && Build.VERSION.SDK_INT >= 19) {
|
||||
return LayoutParams(lp)
|
||||
}else if (lp is ViewGroup.MarginLayoutParams) {
|
||||
return LayoutParams(lp)
|
||||
}
|
||||
return super.generateLayoutParams(lp)
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package com.chwl.app.community.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.chwl.library.utils.keyboard.KeyboardUtil;
|
||||
|
||||
/**
|
||||
* create by lvzebiao @2019/11/28
|
||||
*/
|
||||
public class TouchHideKeyboardView extends ConstraintLayout {
|
||||
|
||||
public TouchHideKeyboardView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public TouchHideKeyboardView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public TouchHideKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (getContext() instanceof Activity) {
|
||||
KeyboardUtil.hideKeyboard((Activity) getContext());
|
||||
}
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
}
|
@@ -0,0 +1,476 @@
|
||||
package com.chwl.app.community.widget;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
|
||||
|
||||
public class ZoomImageView extends ImageView implements ScaleGestureDetector.OnScaleGestureListener, View.OnTouchListener, ViewTreeObserver.OnGlobalLayoutListener {
|
||||
|
||||
private static final String TAG = ZoomImageView.class.getSimpleName();
|
||||
public static final float SCALE_MAX = 3.0f;
|
||||
private static final float SCALE_MID = 1.5f;
|
||||
|
||||
/**
|
||||
* 初始化时的缩放比例,如果图片宽或高大于屏幕,此值将小于0
|
||||
*/
|
||||
private float initScale = 1.0f;
|
||||
private boolean once = true;
|
||||
|
||||
/**
|
||||
* 用于存放矩阵的9个值
|
||||
*/
|
||||
private final float[] matrixValues = new float[9];
|
||||
|
||||
/**
|
||||
* 缩放的手势检测
|
||||
*/
|
||||
private ScaleGestureDetector mScaleGestureDetector = null;
|
||||
private final Matrix mScaleMatrix = new Matrix();
|
||||
|
||||
/**
|
||||
* 用于双击检测
|
||||
*/
|
||||
private GestureDetector mGestureDetector;
|
||||
private boolean isAutoScale;
|
||||
|
||||
private int mTouchSlop;
|
||||
|
||||
private float mLastX;
|
||||
private float mLastY;
|
||||
|
||||
private boolean isCanDrag;
|
||||
private int lastPointerCount;
|
||||
|
||||
private boolean isCheckTopAndBottom = true;
|
||||
private boolean isCheckLeftAndRight = true;
|
||||
private OnClickListener onClickListener;
|
||||
private OnLongClickListener onLongClickListener;
|
||||
|
||||
public ZoomImageView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ZoomImageView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
super.setScaleType(ScaleType.MATRIX);
|
||||
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||
if (onClickListener != null) {
|
||||
onClickListener.onClick(ZoomImageView.this);
|
||||
return true;
|
||||
}
|
||||
return super.onSingleTapConfirmed(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
if (onLongClickListener != null) {
|
||||
onLongClickListener.onLongClick(ZoomImageView.this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTap(MotionEvent e) {
|
||||
if (isAutoScale)
|
||||
return true;
|
||||
|
||||
float x = e.getX();
|
||||
float y = e.getY();
|
||||
LogUtil.print("DoubleTap, " + getScale() + " , " + initScale);
|
||||
if (getScale() < SCALE_MID) {
|
||||
//postDelayed(); 16 :多久实现一次的定时器操作
|
||||
ZoomImageView.this.postDelayed(new AutoScaleRunnable(SCALE_MID, x, y), 16);
|
||||
isAutoScale = true;
|
||||
} /*else if (getScale() >= SCALE_MID //连续双击放大 可放开
|
||||
&& getScale() < SCALE_MAX) {
|
||||
ZoomImageView.this.postDelayed(new AutoScaleRunnable(SCALE_MAX, x, y), 16);
|
||||
isAutoScale = true;
|
||||
}*/ else {
|
||||
ZoomImageView.this.postDelayed(new AutoScaleRunnable(initScale, x, y), 16);
|
||||
isAutoScale = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
mScaleGestureDetector = new ScaleGestureDetector(context, this);
|
||||
this.setOnTouchListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动缩放的任务
|
||||
*
|
||||
* @author zhy
|
||||
*/
|
||||
private class AutoScaleRunnable implements Runnable {
|
||||
static final float BIGGER = 1.07f;
|
||||
static final float SMALLER = 0.93f;
|
||||
private float mTargetScale;
|
||||
private float tmpScale;
|
||||
|
||||
/**
|
||||
* 缩放的中心
|
||||
*/
|
||||
private float x;
|
||||
private float y;
|
||||
|
||||
/**
|
||||
* 传入目标缩放值,根据目标值与当前值,判断应该放大还是缩小
|
||||
*
|
||||
* @param targetScale
|
||||
*/
|
||||
public AutoScaleRunnable(float targetScale, float x, float y) {
|
||||
this.mTargetScale = targetScale;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
if (getScale() < mTargetScale) {
|
||||
tmpScale = BIGGER;
|
||||
} else {
|
||||
tmpScale = SMALLER;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// 进行缩放
|
||||
mScaleMatrix.postScale(tmpScale, tmpScale, x, y);
|
||||
checkBorderAndCenterWhenScale();
|
||||
setImageMatrix(mScaleMatrix);
|
||||
|
||||
final float currentScale = getScale();
|
||||
// 如果值在合法范围内,继续缩放
|
||||
if (((tmpScale > 1f) && (currentScale < mTargetScale)) || ((tmpScale < 1f) && (mTargetScale < currentScale))) {
|
||||
|
||||
ZoomImageView.this.postDelayed(this, 16);
|
||||
} else {
|
||||
// 设置为目标的缩放比例
|
||||
final float deltaScale = mTargetScale / currentScale;
|
||||
mScaleMatrix.postScale(deltaScale, deltaScale, x, y);
|
||||
checkBorderAndCenterWhenScale();
|
||||
setImageMatrix(mScaleMatrix);
|
||||
isAutoScale = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对图片进行缩放的控制,首先进行缩放范围的判断,然后设置mScaleMatrix的scale值
|
||||
*
|
||||
* @param detector
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
float scale = getScale();
|
||||
float scaleFactor = detector.getScaleFactor();
|
||||
|
||||
if (getDrawable() == null)
|
||||
return true;
|
||||
|
||||
/**
|
||||
* 缩放的范围控制
|
||||
*/
|
||||
if ((scale < SCALE_MAX && scaleFactor > 1.0f) || (scale > initScale && scaleFactor < 1.0f)) {
|
||||
/**
|
||||
* 最大值最小值判断
|
||||
*/
|
||||
if (scaleFactor * scale < initScale) {
|
||||
scaleFactor = initScale / scale;
|
||||
}
|
||||
if (scaleFactor * scale > SCALE_MAX) {
|
||||
scaleFactor = SCALE_MAX / scale;
|
||||
}
|
||||
/**
|
||||
* 设置缩放比例
|
||||
*/
|
||||
mScaleMatrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());
|
||||
|
||||
checkBorderAndCenterWhenScale();
|
||||
setImageMatrix(mScaleMatrix);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在缩放时,进行图片显示范围的控制
|
||||
*/
|
||||
private void checkBorderAndCenterWhenScale() {
|
||||
|
||||
RectF rect = getMatrixRectF();
|
||||
float deltaX = 0;
|
||||
float deltaY = 0;
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
// 如果宽或高大于屏幕,则控制范围
|
||||
if (rect.width() >= width) {
|
||||
if (rect.left > 0) {
|
||||
deltaX = -rect.left;
|
||||
}
|
||||
if (rect.right < width) {
|
||||
deltaX = width - rect.right;
|
||||
}
|
||||
}
|
||||
if (rect.height() >= height) {
|
||||
if (rect.top > 0) {
|
||||
deltaY = -rect.top;
|
||||
}
|
||||
if (rect.bottom < height) {
|
||||
deltaY = height - rect.bottom;
|
||||
}
|
||||
}
|
||||
// 如果宽或高小于屏幕,则让其居中
|
||||
if (rect.width() < width) {
|
||||
deltaX = width * 0.5f - rect.right + 0.5f * rect.width();
|
||||
}
|
||||
if (rect.height() < height) {
|
||||
deltaY = height * 0.5f - rect.bottom + 0.5f * rect.height();
|
||||
}
|
||||
|
||||
|
||||
mScaleMatrix.postTranslate(deltaX, deltaY);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前图片的Matrix获得图片的范围
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private RectF getMatrixRectF() {
|
||||
Matrix matrix = mScaleMatrix;
|
||||
RectF rect = new RectF();
|
||||
Drawable d = getDrawable();
|
||||
if (null != d) {
|
||||
rect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
|
||||
matrix.mapRect(rect);
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScaleBegin(ScaleGestureDetector detector) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScaleEnd(ScaleGestureDetector detector) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 我们让OnTouchListener的MotionEvent交给ScaleGestureDetector进行处理
|
||||
* public boolean onTouch(View v, MotionEvent event){
|
||||
* return mScaleGestureDetector.onTouchEvent(event);
|
||||
* }
|
||||
*/
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
|
||||
if (mGestureDetector.onTouchEvent(event))
|
||||
return true;
|
||||
mScaleGestureDetector.onTouchEvent(event);
|
||||
|
||||
float x = 0, y = 0;
|
||||
// 拿到触摸点的个数
|
||||
final int pointerCount = event.getPointerCount();
|
||||
// 得到多个触摸点的x与y均值
|
||||
for (int i = 0; i < pointerCount; i++) {
|
||||
x += event.getX(i);
|
||||
y += event.getY(i);
|
||||
}
|
||||
x = x / pointerCount;
|
||||
y = y / pointerCount;
|
||||
|
||||
/**
|
||||
* 每当触摸点发生变化时,重置mLasX , mLastY
|
||||
*/
|
||||
if (pointerCount != lastPointerCount) {
|
||||
isCanDrag = false;
|
||||
mLastX = x;
|
||||
mLastY = y;
|
||||
}
|
||||
|
||||
lastPointerCount = pointerCount;
|
||||
RectF rectF = getMatrixRectF();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (rectF.width() > getWidth() || rectF.height() > getHeight()) {
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (rectF.width() > getWidth() || rectF.height() > getHeight()) {
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
|
||||
float dx = x - mLastX;
|
||||
float dy = y - mLastY;
|
||||
|
||||
if (!isCanDrag) {
|
||||
isCanDrag = isCanDrag(dx, dy);
|
||||
}
|
||||
if (isCanDrag) {
|
||||
|
||||
if (getDrawable() != null) {
|
||||
// if (getMatrixRectF().left == 0 && dx > 0)
|
||||
// {
|
||||
// getParent().requestDisallowInterceptTouchEvent(false);
|
||||
// }
|
||||
//
|
||||
// if (getMatrixRectF().right == getWidth() && dx < 0)
|
||||
// {
|
||||
// getParent().requestDisallowInterceptTouchEvent(false);
|
||||
// }
|
||||
isCheckLeftAndRight = isCheckTopAndBottom = true;
|
||||
// 如果宽度小于屏幕宽度,则禁止左右移动
|
||||
if (rectF.width() < getWidth()) {
|
||||
dx = 0;
|
||||
isCheckLeftAndRight = false;
|
||||
}
|
||||
// 如果高度小雨屏幕高度,则禁止上下移动
|
||||
if (rectF.height() < getHeight()) {
|
||||
dy = 0;
|
||||
isCheckTopAndBottom = false;
|
||||
}
|
||||
|
||||
//设置偏移量
|
||||
mScaleMatrix.postTranslate(dx, dy);
|
||||
//再次校验
|
||||
checkMatrixBounds();
|
||||
setImageMatrix(mScaleMatrix);
|
||||
}
|
||||
}
|
||||
mLastX = x;
|
||||
mLastY = y;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
|
||||
lastPointerCount = 0;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得当前的缩放比例
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final float getScale() {
|
||||
mScaleMatrix.getValues(matrixValues);
|
||||
return matrixValues[Matrix.MSCALE_X];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
getViewTreeObserver().addOnGlobalLayoutListener(this);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据图片的宽和高以及屏幕的宽和高,对图片进行缩放以及移动至屏幕的中心。
|
||||
* 如果图片很小,那就正常显示,不放大了~
|
||||
*/
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
if (once) {
|
||||
Drawable d = getDrawable();
|
||||
if (d == null)
|
||||
return;
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
// 拿到图片的宽和高
|
||||
int dw = d.getIntrinsicWidth();
|
||||
int dh = d.getIntrinsicHeight();
|
||||
float scale = 1.0f;
|
||||
// 如果图片的宽或者高大于屏幕,则缩放至屏幕的宽或者高
|
||||
if (dw > width && dh <= height) {
|
||||
scale = width * 1.0f / dw;
|
||||
}
|
||||
if (dh > height && dw <= width) {
|
||||
scale = height * 1.0f / dh;
|
||||
}
|
||||
// 如果宽和高都大于屏幕,则让其按按比例适应屏幕大小
|
||||
if (dw > width && dh > height) {
|
||||
scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);
|
||||
}
|
||||
initScale = scale;
|
||||
|
||||
mScaleMatrix.postTranslate((width - dw) / 2, (height - dh) / 2);
|
||||
mScaleMatrix.postScale(scale, scale, getWidth() / 2, getHeight() / 2);
|
||||
// 图片移动至屏幕中心
|
||||
setImageMatrix(mScaleMatrix);
|
||||
once = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动时,进行边界判断,主要判断宽或高大于屏幕的
|
||||
*/
|
||||
private void checkMatrixBounds() {
|
||||
RectF rect = getMatrixRectF();
|
||||
|
||||
float deltaX = 0, deltaY = 0;
|
||||
final float viewWidth = getWidth();
|
||||
final float viewHeight = getHeight();
|
||||
// 判断移动或缩放后,图片显示是否超出屏幕边界
|
||||
if (rect.top > 0 && isCheckTopAndBottom) {
|
||||
deltaY = -rect.top;
|
||||
}
|
||||
if (rect.bottom < viewHeight && isCheckTopAndBottom) {
|
||||
deltaY = viewHeight - rect.bottom;
|
||||
}
|
||||
if (rect.left > 0 && isCheckLeftAndRight) {
|
||||
deltaX = -rect.left;
|
||||
}
|
||||
if (rect.right < viewWidth && isCheckLeftAndRight) {
|
||||
deltaX = viewWidth - rect.right;
|
||||
}
|
||||
mScaleMatrix.postTranslate(deltaX, deltaY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是推动行为
|
||||
*
|
||||
* @param dx
|
||||
* @param dy
|
||||
* @return
|
||||
*/
|
||||
private boolean isCanDrag(float dx, float dy) {
|
||||
return Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
|
||||
}
|
||||
|
||||
public void setOnClickListener(OnClickListener onClickListener) {
|
||||
this.onClickListener = onClickListener;
|
||||
}
|
||||
|
||||
public void setOnLongClickListener(OnLongClickListener onLongClickListener) {
|
||||
this.onLongClickListener = onLongClickListener;
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/module_community/res/drawable-xhdpi/ic_back_dynamic.webp
Normal file
After Width: | Height: | Size: 296 B |
BIN
app/src/module_community/res/drawable-xhdpi/ic_box_dynamic.webp
Normal file
After Width: | Height: | Size: 376 B |
BIN
app/src/module_community/res/drawable-xhdpi/ic_close_publish.png
Normal file
After Width: | Height: | Size: 415 B |
After Width: | Height: | Size: 466 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 538 B |
BIN
app/src/module_community/res/drawable-xhdpi/ic_img_dynamic.webp
Normal file
After Width: | Height: | Size: 480 B |
After Width: | Height: | Size: 525 B |
After Width: | Height: | Size: 616 B |
After Width: | Height: | Size: 200 B |
After Width: | Height: | Size: 487 B |
After Width: | Height: | Size: 478 B |
BIN
app/src/module_community/res/drawable-xhdpi/ic_square_live.webp
Normal file
After Width: | Height: | Size: 320 B |
After Width: | Height: | Size: 7.4 KiB |
BIN
app/src/module_community/res/drawable-xhdpi/ic_text_dynamic.webp
Normal file
After Width: | Height: | Size: 380 B |
BIN
app/src/module_community/res/drawable-xhdpi/ic_topic_close.webp
Normal file
After Width: | Height: | Size: 224 B |
After Width: | Height: | Size: 404 B |
After Width: | Height: | Size: 344 B |
After Width: | Height: | Size: 364 B |
After Width: | Height: | Size: 368 B |
After Width: | Height: | Size: 443 B |
After Width: | Height: | Size: 451 B |
After Width: | Height: | Size: 777 B |
BIN
app/src/module_community/res/drawable-xhdpi/icon_dy_emoji.webp
Normal file
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 469 B |
After Width: | Height: | Size: 710 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 190 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 810 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 810 B |
After Width: | Height: | Size: 788 B |
After Width: | Height: | Size: 546 B |
After Width: | Height: | Size: 182 B |
After Width: | Height: | Size: 978 B |
After Width: | Height: | Size: 455 B |
After Width: | Height: | Size: 278 B |
After Width: | Height: | Size: 256 B |
After Width: | Height: | Size: 396 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 385 B |
After Width: | Height: | Size: 608 B |
After Width: | Height: | Size: 826 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 196 B |
After Width: | Height: | Size: 756 B |
BIN
app/src/module_community/res/drawable-xhdpi/icon_top.webp
Normal file
After Width: | Height: | Size: 460 B |
61
app/src/module_community/res/drawable/anim_list_dy_like.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:oneshot="true">
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00000"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00001"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00002"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00003"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00004"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00005"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00006"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00007"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00008"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00009"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00010"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00011"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00012"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
<item
|
||||
android:drawable="@drawable/icon_dy_list_like_00013"
|
||||
android:duration="@integer/dy_like_anim_duration" />
|
||||
|
||||
</animation-list>
|
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#1AFFBC51" />
|
||||
<corners
|
||||
android:bottomLeftRadius="@dimen/dp_9"
|
||||
android:bottomRightRadius="@dimen/dp_9"
|
||||
android:topLeftRadius="@dimen/dp_9"
|
||||
android:topRightRadius="@dimen/dp_4" />
|
||||
|
||||
</shape>
|
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_translate_dynamic" android:state_selected="true" />
|
||||
<item android:drawable="@drawable/ic_translate_selected_dynamic" />
|
||||
</selector>
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<size android:width="10dp"
|
||||
android:height="10dp"/>
|
||||
</shape>
|
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/icon_dy_publish_false" android:state_enabled="false" />
|
||||
<item android:drawable="@drawable/icon_dy_publish_true" android:state_enabled="true" />
|
||||
</selector>
|