diff --git a/app/build.gradle b/app/build.gradle
index 83cfd17b1..35a6ab9cf 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -117,6 +117,7 @@ android {
'src/module_treasure_box/java',
'src/module_public_chat/java',
'src/module_game/java',
+ 'src/module_community/java',
]
@@ -133,6 +134,7 @@ android {
'src/module_treasure_box/res',
'src/module_public_chat/res',
'src/module_game/res',
+ 'src/module_community/res',
]
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 34bb2d8b1..362dfab7c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -934,6 +934,15 @@
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/chwl/app/MainActivity.java b/app/src/main/java/com/chwl/app/MainActivity.java
index 51cb6c87c..9f6890f80 100644
--- a/app/src/main/java/com/chwl/app/MainActivity.java
+++ b/app/src/main/java/com/chwl/app/MainActivity.java
@@ -25,6 +25,7 @@ import androidx.lifecycle.ViewModelProvider;
import com.chwl.app.base.GlobalViewModelOwner;
import com.chwl.app.common.widget.dialog.DialogManager;
+import com.chwl.app.community.square.SquareFragment;
import com.chwl.app.game.core.GameStateAbility;
import com.chwl.app.game.data.GameModel2;
import com.chwl.app.game.ui.game.GameActivity;
@@ -143,7 +144,7 @@ public class MainActivity extends BaseMvpActivity
private MainTabLayout mMainTabLayout;
private AnchorCardView anchorCardView;
private View viewClose;
- private int mCurrentTabType = MainTabType.TAB_TYPE_STAR;
+ private int mCurrentTabType = MainTabType.TAB_TYPE_HOME;
/**
* 房间最小化动画,换成属性动画,原先的补间动画影响了activity的生命周期
*/
@@ -162,9 +163,9 @@ public class MainActivity extends BaseMvpActivity
private Runnable touchRunnable;
{
- fragmentArray.put(MainTabType.TAB_TYPE_STAR, new StarFragment());
- fragmentArray.put(MainTabType.TAB_TYPE_GAME, new GameHomeFragment());
fragmentArray.put(MainTabType.TAB_TYPE_HOME, new HomeFragment());
+ fragmentArray.put(MainTabType.TAB_TYPE_GAME, new GameHomeFragment());
+ fragmentArray.put(MainTabType.TAB_TYPE_SQUARE, new SquareFragment());
fragmentArray.put(MainTabType.TAB_TYPE_MSG, new ContactsListFragment());
fragmentArray.put(MainTabType.TAB_TYPE_ME, new MeFragment());
}
diff --git a/app/src/main/java/com/chwl/app/home/adapter/CommunityNoticeAdapter.java b/app/src/main/java/com/chwl/app/home/adapter/CommunityNoticeAdapter.java
index d2349809a..254ce4331 100644
--- a/app/src/main/java/com/chwl/app/home/adapter/CommunityNoticeAdapter.java
+++ b/app/src/main/java/com/chwl/app/home/adapter/CommunityNoticeAdapter.java
@@ -1,6 +1,8 @@
package com.chwl.app.home.adapter;
+
import android.text.TextUtils;
+import android.widget.TextView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
@@ -59,7 +61,8 @@ public class CommunityNoticeAdapter extends BaseQuickAdapter {
+
+ private Context context;
+ @Setter
+ private int mTwoImageHeight;
+ @Setter
+ private int mThreeImageHeight;
+
+ private int imageWidth;
+
+ private int bigImageWidth;
+
+ @Setter
+ private int singleImageHeight;
+
+ public DynamicImageAdapter(int layoutResId, @Nullable List data) {
+ super(layoutResId, data);
+ context = BasicConfig.INSTANCE.getAppContext();
+ imageWidth = UIUtil.getScreenWidth(context) * 2 / 5;
+ bigImageWidth = UIUtil.getScreenWidth(context);
+
+ mTwoImageHeight = (ScreenUtils.getScreenWidth(context) - UIUtil.dip2px(context, 50F)) / 2;
+ mThreeImageHeight = (ScreenUtils.getScreenWidth(context) - UIUtil.dip2px(context, 60F)) / 3;
+ }
+
+ @Override
+ protected void convert(BaseViewHolder helper, DynamicMedia item) {
+ ImageView ivPhoto = helper.getView(R.id.riv_photo);
+ helper.setGone(R.id.iv_gif_tag, item.isGif());
+ ViewGroup.LayoutParams layoutParams = ivPhoto.getLayoutParams();
+ if (helper.itemView instanceof ConstraintLayout && getData().size() > 1) {
+ ImageLoadUtilsV2.loadImage(ivPhoto, item.getResUrl(), imageWidth);
+ } else {
+ switch (getData().size()) {
+ case 1:
+ layoutParams.height = singleImageHeight;
+ ivPhoto.setLayoutParams(layoutParams);
+ ImageLoadUtilsV2.loadImage(ivPhoto, item.getResUrl(), bigImageWidth);
+ break;
+ case 2:
+ layoutParams.height = mTwoImageHeight;
+ ivPhoto.setLayoutParams(layoutParams);
+ ImageLoadUtilsV2.loadImage(ivPhoto, item.getResUrl(), imageWidth);
+ break;
+ case 3:
+ default:
+ layoutParams.height = mThreeImageHeight;
+ ivPhoto.setLayoutParams(layoutParams);
+ ImageLoadUtilsV2.loadImage(ivPhoto, item.getResUrl(), imageWidth);
+ break;
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/chwl/app/ui/im/ImInitHelper.java b/app/src/main/java/com/chwl/app/ui/im/ImInitHelper.java
index edfd74bd3..74369a427 100644
--- a/app/src/main/java/com/chwl/app/ui/im/ImInitHelper.java
+++ b/app/src/main/java/com/chwl/app/ui/im/ImInitHelper.java
@@ -2,7 +2,11 @@ package com.chwl.app.ui.im;
import android.content.Context;
+import com.chwl.app.community.holder.DynamicSysHolder;
+import com.chwl.app.community.im.WorldDynamicShareViewHolder;
import com.chwl.app.module_hall.im.msgholder.FamilyMsgViewHolder;
+import com.chwl.core.community.attachment.DynamicSysAttachment;
+import com.chwl.core.community.im.WorldDynamicAttachment;
import com.chwl.core.module_hall.im.FamilyAttachment;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.contact.ContactEventListener;
@@ -151,6 +155,10 @@ public class ImInitHelper {
//瓜分钻石 三级
NimUIKit.registerMsgItemViewHolder(CarveUpGoldThirdLevelAttachment.class, MsgViewHolderText.class);
+ // 社区动态
+ NimUIKit.registerMsgItemViewHolder(DynamicSysAttachment.class, DynamicSysHolder.class);
+ NimUIKit.registerMsgItemViewHolder(WorldDynamicAttachment.class, WorldDynamicShareViewHolder.class);
+
NimUIKit.registerMsgItemViewHolder(ChatHintAttachment.class, MsgViewHolderChatHint.class);
//技能卡
diff --git a/app/src/main/java/com/chwl/app/ui/user/activity/UserInfoActivity.java b/app/src/main/java/com/chwl/app/ui/user/activity/UserInfoActivity.java
index 9f9ae89c6..244008d20 100644
--- a/app/src/main/java/com/chwl/app/ui/user/activity/UserInfoActivity.java
+++ b/app/src/main/java/com/chwl/app/ui/user/activity/UserInfoActivity.java
@@ -22,6 +22,7 @@ import androidx.viewpager2.widget.ViewPager2;
import com.chwl.app.avroom.adapter.CommonVPAdapter;
import com.chwl.app.ui.user.adapter.UserInfoTopAlbumAdapter;
import com.chwl.app.ui.user.fragment.UserInfoDataFragment;
+import com.chwl.app.ui.user.fragment.UserInfoDynamicFragment;
import com.chwl.app.utils.AppBarStateChangeListener;
import com.chwl.core.decoration.headwear.bean.HeadWearInfo;
import com.chwl.core.noble.NobleUtil;
@@ -201,12 +202,12 @@ public class UserInfoActivity extends BaseBindingActivity fragmentList = new ArrayList<>(1);
+ List fragmentList = new ArrayList<>(2);
fragmentList.add(new UserInfoDataFragment());
-// fragmentList.add(new UserInfoGiftWallFragment());
- final List tagList = new ArrayList<>(1);
+ fragmentList.add(new UserInfoDynamicFragment());
+ final List tagList = new ArrayList<>(2);
tagList.add(getString(R.string.me_data));
-// tagList.add(getString(R.string.me_gift_wall));
+ tagList.add(getString(R.string.me_dynamic));
CommonNavigator commonNavigator = new CommonNavigator(context);
commonNavigator.setTitleWrapContent(false);
UserInfoIndicatorAdapter magicIndicatorAdapter = new UserInfoIndicatorAdapter(context, tagList);
diff --git a/app/src/main/java/com/chwl/app/ui/user/activity/UserInfoModifyActivity.kt b/app/src/main/java/com/chwl/app/ui/user/activity/UserInfoModifyActivity.kt
index caba93c71..e0150e9ae 100644
--- a/app/src/main/java/com/chwl/app/ui/user/activity/UserInfoModifyActivity.kt
+++ b/app/src/main/java/com/chwl/app/ui/user/activity/UserInfoModifyActivity.kt
@@ -35,7 +35,6 @@ import com.chwl.app.ui.widget.dialog.CommonTipDialog
import com.chwl.app.utils.RegexUtil
import com.chwl.core.auth.AuthModel
import com.chwl.core.file.FileModel
-import com.chwl.core.file.cos.CosException
import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.user.bean.UserPhoto
diff --git a/app/src/main/java/com/chwl/app/ui/user/adapter/UserInfoDynamicAdapter.java b/app/src/main/java/com/chwl/app/ui/user/adapter/UserInfoDynamicAdapter.java
new file mode 100644
index 000000000..8c73b06b7
--- /dev/null
+++ b/app/src/main/java/com/chwl/app/ui/user/adapter/UserInfoDynamicAdapter.java
@@ -0,0 +1,249 @@
+package com.chwl.app.ui.user.adapter;
+
+
+import android.app.Activity;
+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 androidx.recyclerview.widget.GridLayoutManager;
+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.community.dynamic.view.DynamicDetailActivity;
+import com.chwl.app.community.helper.CalcSize;
+import com.chwl.app.community.helper.DynamicUiHelper;
+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.photo.BigPhotoActivity;
+import com.chwl.app.photo.PagerOption;
+import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
+import com.chwl.app.utils.TimeUiUtils;
+import com.chwl.core.community.bean.DynamicMedia;
+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.SingleToastUtil;
+import com.netease.nim.uikit.common.util.log.LogUtil;
+
+import java.util.List;
+
+/**
+ * create by lvzebiao @2019/11/13
+ */
+public class UserInfoDynamicAdapter extends BaseQuickAdapter {
+
+ private SparseBooleanArray mCollapsedStatus = new SparseBooleanArray();
+ private SparseIntArray mCollapsedHeightStatus = new SparseIntArray(2);
+
+ private Context context;
+
+ private long worldId;
+
+ private int iconWidth;
+
+ private int iconHeight;
+
+ /**
+ * 单图情况下的边界
+ */
+ private int imageBorder;
+ /**
+ * 图片的边界值
+ */
+ private int divider;
+
+ public UserInfoDynamicAdapter(Context context) {
+ super(R.layout.item_userinfo_dynamic);
+ this.context = context;
+ iconWidth = UIUtil.dip2px(context, 32);
+ iconHeight = UIUtil.dip2px(context, 15);
+ //0.68
+ imageBorder = UIUtil.getScreenWidth(context) * ImageUiHelper.BORDER_MIN / ImageUiHelper.BORDER_MAX;
+ divider = UIUtil.dip2px(context, 10);
+ }
+
+ @Override
+ protected void convert(BaseViewHolder helper, WorldDynamicBean item) {
+ //这个值,有没有文本UI部分,改变图片部分的margin
+ boolean noTextUi = TextUtils.isEmpty(item.getContent());
+ RecyclerView rvImage = helper.getView(R.id.rv_image);
+ List dynamicMediaList = item.getDynamicResList();
+ if (item.getType() == WorldDynamicBean.TYPE_IMAGE
+ && dynamicMediaList != null && dynamicMediaList.size() > 0) {
+ rvImage.setVisibility(View.VISIBLE);
+ initRecyclerView(rvImage, dynamicMediaList, noTextUi);
+ } else {
+ rvImage.setVisibility(View.GONE);
+ }
+
+ //时间
+ helper.setText(R.id.tv_time, TimeUiUtils.getDynamicUi(item.getPublishTime()));
+
+ ExpandableTextView etvContent = helper.getView(R.id.etv_content);
+ etvContent.setEventType(1);
+ if (noTextUi) {
+ etvContent.setVisibility(View.GONE);
+ } else {
+ etvContent.setVisibility(View.VISIBLE);
+ CharSequence formatText = DynamicUiHelper.formatFirstDynamicContent(
+ item, etvContent.mTv, iconWidth, iconHeight);
+ etvContent.setText(formatText, mCollapsedStatus, helper.getAdapterPosition(), mCollapsedHeightStatus);
+ }
+
+ helper.setGone(R.id.layout_root_mini_world, item.getTag() != null);
+ helper.setText(R.id.tv_mini_world_name, "#" + item.getTag());
+
+ //评论
+ 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) {
+ if (item.getDynamicId() == 0) {
+ SingleToastUtil.showToast(ResUtil.getString(R.string.the_default_dynamic_cannot_be_liked));
+ return;
+ }
+ llLike.setEnabled(false);
+ int status = item.isLike() ? 0 : 1;
+ DynamicModel.get().like(worldId, item.getDynamicId(), item.getUid(), status, 1)
+ .compose(RxHelper.bindContext(context))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(String s, String error) {
+ super.accept(s, error);
+ llLike.setEnabled(true);
+ if (error != null) {
+ SingleToastUtil.showToast(error);
+ } else {
+ LogUtil.print(mContext.getString(R.string.me_call_the_like_interface_to_complete));
+ 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 -> {
+ if (item.getDynamicId() == 0) {
+ SingleToastUtil.showToast(ResUtil.getString(R.string.the_default_dynamic_cannot_be_commented));
+ return;
+ }
+ DynamicDetailActivity.start(context, item.getDynamicId(), worldId,
+ helper.getAdapterPosition(), true, 1);
+ }
+ );
+ helper.setVisible(R.id.iv_more, item.getDynamicId() != 0);
+ if (item.getDynamicId() != 0) {
+ helper.addOnClickListener(R.id.iv_more).addOnClickListener(R.id.ll_share);
+ }
+
+ View.OnClickListener toDetailListener = v -> {
+ if (item.getDynamicId() == 0) {
+ return;
+ }
+ DynamicDetailActivity.start(context, item.getDynamicId(), worldId,
+ helper.getAdapterPosition(), false, 1);
+ };
+
+ if (etvContent.mTv != null) {
+ etvContent.mTv.setOnClickListener(toDetailListener);
+ }
+ //跳转去详情
+ helper.itemView.setOnClickListener(toDetailListener);
+ helper.setGone(R.id.line_bottom, getItemCount() - 1 != helper.getLayoutPosition());
+ }
+
+ 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_dy_list_like);
+ } else {
+ ivLikeAnim.setImageResource(R.drawable.icon_dy_list_like_false);
+ }
+
+ }
+
+ private void initRecyclerView(RecyclerView rvImage, List imageUrl, boolean noTextUi) {
+ if (imageUrl == null) {
+ return;
+ }
+ 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 + divider;
+ params.height = calcSize.height + divider;
+ }
+ rvImage.setLayoutParams(params);
+ rvImage.setNestedScrollingEnabled(false);
+ rvImage.setLayoutManager(new GridLayoutManager(mContext, imageUrl.size() > 2 ? 3 : imageUrl.size()));
+ DynamicImageAdapter adapter = new DynamicImageAdapter(R.layout.item_dynamic_image, imageUrl);
+ adapter.setSingleImageHeight(calcSize.height);
+ adapter.setOnItemClickListener((adapter1, view, position) -> {
+ PagerOption option = new PagerOption().setSave(true);
+ BigPhotoActivity.start((Activity) mContext, ObjectTypeHelper.mediaToCustomList(imageUrl),
+ position, option);
+ }
+ );
+ rvImage.setAdapter(adapter);
+ }
+
+ 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);
+ }
+
+}
diff --git a/app/src/main/java/com/chwl/app/ui/user/fragment/UserInfoDataFragment.kt b/app/src/main/java/com/chwl/app/ui/user/fragment/UserInfoDataFragment.kt
index 24de7bdd2..24783de9a 100644
--- a/app/src/main/java/com/chwl/app/ui/user/fragment/UserInfoDataFragment.kt
+++ b/app/src/main/java/com/chwl/app/ui/user/fragment/UserInfoDataFragment.kt
@@ -68,7 +68,7 @@ class UserInfoDataFragment : BaseViewBindingFragment() {
+
+ private val viewModel: UserInfoViewModel by activityViewModels()
+
+ private var adapter: UserInfoDynamicAdapter? = null
+ override fun init() {
+ initView()
+ viewModel.userInfoDetailData.observe(this) {
+ updateList(it.dynamicInfo)
+ }
+ }
+
+ private fun initView() {
+ adapter = UserInfoDynamicAdapter(requireContext())
+ adapter?.setEnableLoadMore(false)
+ adapter?.emptyView = layoutInflater.inflate(R.layout.user_info_tab_empty, null)
+ binding.recyclerView.adapter = adapter
+ adapter?.setOnItemChildClickListener { adapter, view: View, pos: Int ->
+ val bean =
+ adapter?.getItem(pos) as? WorldDynamicBean ?: return@setOnItemChildClickListener
+ if (view.id == R.id.iv_more) {
+ val list: MutableList = ArrayList()
+ if (!UserModel.get().isMyseft(bean.uid)) {
+ val item = ButtonItem(
+ getString(R.string.me_shield_dynamic)
+ ) {
+ UserModel.get().addReport(bean.dynamicId, 0)
+ .subscribe(object : BeanObserver() {
+ override fun onErrorMsg(error: String) {
+ dialogManager.dismissDialog()
+ toast(error)
+ }
+
+ override fun onSuccess(s: String) {
+ dialogManager.dismissDialog()
+ toast(ResUtil.getString(R.string.me_shield_success))
+ val size = adapter?.data?.size ?: 0
+ if (pos < size) {
+ if (bean == adapter?.getItem(pos)) {
+ adapter?.remove(pos)
+ }
+ }
+ }
+ })
+ }
+ list.add(item)
+ }
+ if (!UserModel.get().isMyseft(bean.uid)) {
+ val blackListItem = ButtonItemFactory.createAddToBlackListItem(
+ dialogManager, bean.uid.toString()
+ )
+ list.add(blackListItem)
+ }
+ if (!UserModel.get().isMyseft(bean.uid)) {
+ val item = ButtonItem(
+ getString(R.string.me_report_dynamic)
+ ) {
+ UIHelper.showReportPage(
+ mContext, bean.uid,
+ XConstants.REPORT_TYPE_DYNAMIC_SQUARE
+ )
+ }
+ list.add(item)
+ }
+ if (UserModel.get().isMyseft(bean.uid) ||
+ isThisWorldOwner(bean)
+ ) {
+ val item = ButtonItem(
+ getString(R.string.me_delete)
+ ) { deleteDynamic(pos, this.adapter) }
+ list.add(item)
+ }
+ dialogManager.showCommonPopupDialog(list, getString(R.string.cancel))
+ } else if (view.id == R.id.ll_share) {
+// ShareDynamicHelper(activity).share(bean)
+ }
+ }
+ }
+
+ private fun deleteDynamic(pos: Int, adapter: UserInfoDynamicAdapter?) {
+ dialogManager.showOkCancelWithTitleDialog(getString(R.string.me_cannot_be_restored),
+ DialogManager.OkCancelDialogListener {
+ val bean = adapter?.getItem(pos) ?: return@OkCancelDialogListener
+ DynamicModel.get().delete(bean.worldId, bean.dynamicId)
+ .compose(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
+ .doOnSubscribe { dialogManager.showProgressDialog(mContext) }
+ .subscribe(object : DontWarnObserver() {
+ override fun accept(s: String?, error: String?) {
+ super.accept(s, error)
+ dialogManager.dismissDialog()
+ if (error != null) {
+ toast(error)
+ } else {
+ toast(getString(R.string.me_successfully_delete))
+ if (pos < adapter.data.size) {
+ if (bean == adapter.getItem(pos)) {
+ adapter.remove(pos)
+ }
+ }
+ }
+ }
+ })
+ })
+ }
+
+ /**
+ * 判断自己是不是该世界的创始人
+ */
+ private fun isThisWorldOwner(bean: WorldDynamicBean?): Boolean {
+ return bean != null && bean.worldUid == AuthModel.get().currentUid
+ }
+
+ private fun updateList(list: List?) {
+ adapter?.setNewData(list)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/chwl/app/ui/user/viewmodel/UserInfoViewModel.kt b/app/src/main/java/com/chwl/app/ui/user/viewmodel/UserInfoViewModel.kt
index 527a8c363..3b2024640 100644
--- a/app/src/main/java/com/chwl/app/ui/user/viewmodel/UserInfoViewModel.kt
+++ b/app/src/main/java/com/chwl/app/ui/user/viewmodel/UserInfoViewModel.kt
@@ -3,21 +3,16 @@ package com.chwl.app.ui.user.viewmodel
import android.annotation.SuppressLint
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
import com.chwl.app.base.BaseViewModel
import com.chwl.app.module_hall.HallDataManager
import com.chwl.core.auth.AuthModel
-import com.chwl.core.module_hall.hall.HallModel
-import com.chwl.core.module_hall.hall.bean.ClanAndHallInfo
import com.chwl.core.module_hall.hall.bean.UserClanInfo
-import com.chwl.core.user.UserInfoUiMgr
import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.GiftWallInfo
import com.chwl.core.user.bean.UserDetailInfo
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.utils.net.BeanObserver
import com.chwl.core.utils.extension.toast
-import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
class UserInfoViewModel : BaseViewModel() {
@@ -46,7 +41,7 @@ class UserInfoViewModel : BaseViewModel() {
}
override fun onSuccess(info: UserInfo) {
- _userInfoData.value = info
+ _userInfoData.postValue(info)
}
override fun onSubscribe(d: Disposable) {
@@ -65,7 +60,7 @@ class UserInfoViewModel : BaseViewModel() {
override fun onSuccess(info: UserDetailInfo) {
info.let {
mRoomUid = it.data.roomUid
- _userInfoDetailData.value = it.data
+ _userInfoDetailData.postValue(it.data)
}
}
diff --git a/app/src/main/java/com/chwl/app/ui/widget/MainRedPointTab.java b/app/src/main/java/com/chwl/app/ui/widget/MainRedPointTab.java
index 4d2b83304..7e0fc6a24 100644
--- a/app/src/main/java/com/chwl/app/ui/widget/MainRedPointTab.java
+++ b/app/src/main/java/com/chwl/app/ui/widget/MainRedPointTab.java
@@ -139,8 +139,8 @@ public class MainRedPointTab extends RelativeLayout {
private int getDefaultRes(int tabType, boolean select) {
int resId = select ? R.drawable.ic_main_tab_home_pressed : R.drawable.ic_main_tab_home;
switch (tabType) {
- case MainTabType.TAB_TYPE_STAR:
- resId = select ? R.drawable.ic_main_tab_star_pressed : R.drawable.ic_main_tab_star;
+ case MainTabType.TAB_TYPE_SQUARE:
+ resId = select ? R.drawable.ic_main_tab_square_pressed : R.drawable.ic_main_tab_square;
break;
case MainTabType.TAB_TYPE_GAME:
resId = select ? R.drawable.ic_main_tab_game_pressed : R.drawable.ic_main_tab_game;
diff --git a/app/src/main/java/com/chwl/app/ui/widget/MainTabLayout.java b/app/src/main/java/com/chwl/app/ui/widget/MainTabLayout.java
index 253192fb2..01cef0d1a 100644
--- a/app/src/main/java/com/chwl/app/ui/widget/MainTabLayout.java
+++ b/app/src/main/java/com/chwl/app/ui/widget/MainTabLayout.java
@@ -25,7 +25,7 @@ public class MainTabLayout extends LinearLayout implements View.OnClickListener
private final List tabViewList = new ArrayList<>(4);
private MainRedPointTab homeTab;
- private MainRedPointTab starTab;
+ private MainRedPointTab squareTab;
private MainRedPointTab gameTab;
private MainRedPointTab msgTab;
private MainRedPointTab meTab;
@@ -57,20 +57,20 @@ public class MainTabLayout extends LinearLayout implements View.OnClickListener
inflate(context, R.layout.main_tab_layout, this);
msgTab = findViewById(R.id.main_msg_tab);
- starTab = findViewById(R.id.main_star_tab);
+ squareTab = findViewById(R.id.main_square_tab);
gameTab = findViewById(R.id.main_game_tab);
homeTab = findViewById(R.id.main_home_tab);
meTab = findViewById(R.id.main_me_tab);
homeTab.setOnClickListener(this);
meTab.setOnClickListener(this);
- starTab.setOnClickListener(this);
+ squareTab.setOnClickListener(this);
gameTab.setOnClickListener(this);
msgTab.setOnClickListener(this);
- tabViewList.add(starTab);
- tabViewList.add(gameTab);
tabViewList.add(homeTab);
+ tabViewList.add(gameTab);
+ tabViewList.add(squareTab);
tabViewList.add(msgTab);
tabViewList.add(meTab);
}
@@ -106,8 +106,8 @@ public class MainTabLayout extends LinearLayout implements View.OnClickListener
case R.id.main_home_tab:
select(MainTabType.TAB_TYPE_HOME);
break;
- case R.id.main_star_tab:
- select(MainTabType.TAB_TYPE_STAR);
+ case R.id.main_square_tab:
+ select(MainTabType.TAB_TYPE_SQUARE);
break;
case R.id.main_game_tab:
select(MainTabType.TAB_TYPE_GAME);
@@ -122,10 +122,10 @@ public class MainTabLayout extends LinearLayout implements View.OnClickListener
}
private void select(int tabType) {
- if (tabType == 0) tabType = MainTabType.TAB_TYPE_STAR;
+ if (tabType == 0) tabType = MainTabType.TAB_TYPE_HOME;
if (mLastPosition == tabType) return;
msgTab.select(tabType == MainTabType.TAB_TYPE_MSG);
- starTab.select(tabType == MainTabType.TAB_TYPE_STAR);
+ squareTab.select(tabType == MainTabType.TAB_TYPE_SQUARE);
gameTab.select(tabType == MainTabType.TAB_TYPE_GAME);
homeTab.select(tabType == MainTabType.TAB_TYPE_HOME);
meTab.select(tabType == MainTabType.TAB_TYPE_ME);
diff --git a/app/src/main/res/drawable-xxhdpi/base_status_empty.png b/app/src/main/res/drawable-xxhdpi/base_status_empty.png
new file mode 100644
index 000000000..02ecbd92e
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/base_status_empty.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_main_tab_square.png b/app/src/main/res/drawable-xxhdpi/ic_main_tab_square.png
new file mode 100644
index 000000000..d0eaa4bbb
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_main_tab_square.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_main_tab_square_pressed.png b/app/src/main/res/drawable-xxhdpi/ic_main_tab_square_pressed.png
new file mode 100644
index 000000000..be87661c8
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_main_tab_square_pressed.png differ
diff --git a/app/src/main/res/layout/activity_big_photo.xml b/app/src/main/res/layout/activity_big_photo.xml
index 14ab4a038..c4f004153 100644
--- a/app/src/main/res/layout/activity_big_photo.xml
+++ b/app/src/main/res/layout/activity_big_photo.xml
@@ -9,6 +9,7 @@
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/dp_30"
app:layout_constraintTop_toTopOf="parent" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/main_tab_layout.xml b/app/src/main/res/layout/main_tab_layout.xml
index 7810202b5..1f05a39f0 100644
--- a/app/src/main/res/layout/main_tab_layout.xml
+++ b/app/src/main/res/layout/main_tab_layout.xml
@@ -6,8 +6,15 @@
android:orientation="horizontal"
tools:parentTag="LinearLayout">
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/user_info_tab_empty.xml b/app/src/main/res/layout/user_info_tab_empty.xml
new file mode 100644
index 000000000..ab4a23d4b
--- /dev/null
+++ b/app/src/main/res/layout/user_info_tab_empty.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 8aff7970d..afb5f021a 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -976,7 +976,7 @@
نقرة على وحدة ميزات مركز الفرد
مباشر
المعلومات
- ديناميكيات
+ التحديثات
جدار الهدايا
حجرة الدرع
التقرير
diff --git a/app/src/module_community/java/com/chwl/app/community/ConstantValue.java b/app/src/module_community/java/com/chwl/app/community/ConstantValue.java
new file mode 100644
index 000000000..44c0f318a
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/ConstantValue.java
@@ -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;
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/CommentAdapter.java b/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/CommentAdapter.java
new file mode 100644
index 000000000..ba669476d
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/CommentAdapter.java
@@ -0,0 +1,165 @@
+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.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 {
+
+
+ public CommentAdapter() {
+ super(R.layout.item_dy_comment);
+ }
+
+ @Override
+ protected void convert(BaseViewHolder helper, Comment item) {
+ ImageLoadUtilsV2.loadAvatar(helper.getView(R.id.iv_avatar), item.getAvatar());
+ 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 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 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 list = getData();
+ if (pos >= 0 && pos < list.size()) {
+ list.remove(pos);
+ notifyDataSetChanged();
+ }
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/CommentReplyAdapter.java b/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/CommentReplyAdapter.java
new file mode 100644
index 000000000..894498387
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/CommentReplyAdapter.java
@@ -0,0 +1,74 @@
+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.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 {
+
+ private boolean hasExpandFooter;
+
+ public CommentReplyAdapter(boolean hasExpandFooter) {
+ super(R.layout.item_dy_reply);
+ this.hasExpandFooter = hasExpandFooter;
+ }
+
+ @Override
+ protected void convert(BaseViewHolder helper, Reply item) {
+
+ ImageLoadUtilsV2.loadAvatar(helper.getView(R.id.iv_avatar), item.getAvatar(), true);
+ 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);
+ }
+ }
+
+
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/WorldDynamicAdapter.java b/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/WorldDynamicAdapter.java
new file mode 100644
index 000000000..a7f63bec7
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/dynamic/adapter/WorldDynamicAdapter.java
@@ -0,0 +1,307 @@
+package com.chwl.app.community.dynamic.adapter;
+
+import android.app.Activity;
+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 androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+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.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.CalcSize;
+import com.chwl.app.community.helper.DynamicUiHelper;
+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.utils.TopicUpTextWrapper;
+import com.chwl.app.community.widget.DynamicNickDetailWidget;
+import com.chwl.app.community.widget.ExpandableTextView;
+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.NamePlateHelper;
+import com.chwl.app.utils.TimeUiUtils;
+import com.chwl.core.community.bean.DynamicMedia;
+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 WorldDynamicAdapter extends BaseQuickAdapter {
+
+ private SparseBooleanArray mCollapsedStatus = new SparseBooleanArray();
+ private SparseIntArray mCollapsedHeightStatus = new SparseIntArray(2);
+
+ private Context context;
+
+ private long worldId;
+
+ private int iconWidth;
+
+ private int iconHeight;
+
+ /**
+ * 有文本的图片布局的top-margin
+ */
+ private int imageTmHasText;
+ /**
+ * 无文本的图片布局的top-margin
+ */
+ private int imageTmNoText;
+
+ /**
+ * 单图情况下的边界
+ */
+ private int imageBorder;
+ /**
+ * 图片的边界值
+ */
+ private int divider;
+
+ public WorldDynamicAdapter(Context context, long worldId) {
+ super(R.layout.item_world_dynamic);
+ this.context = context;
+ this.worldId = worldId;
+ iconWidth = UIUtil.dip2px(context, 32);
+ iconHeight = UIUtil.dip2px(context, 15);
+ imageTmHasText = UIUtil.dip2px(context, 15f);
+ imageTmNoText = UIUtil.dip2px(context, 7.5f);
+ //0.68
+ imageBorder = UIUtil.getScreenWidth(context) * ImageUiHelper.BORDER_MIN / ImageUiHelper.BORDER_MAX;
+ divider = UIUtil.dip2px(context, 10);
+ }
+
+ @Override
+ protected void convert(BaseViewHolder helper, WorldDynamicBean item) {
+ //这个值,有没有文本UI部分,改变图片部分的margin
+ boolean noTextUi = TextUtils.isEmpty(item.getContent());
+
+ helper.setText(R.id.tv_nick, item.getNick());
+ RecyclerView rvImage = helper.getView(R.id.rv_image);
+ List dynamicMediaList = item.getDynamicResList();
+ if (item.getType() == WorldDynamicBean.TYPE_IMAGE
+ && dynamicMediaList != null && dynamicMediaList.size() > 0) {
+ rvImage.setVisibility(View.VISIBLE);
+ initRecyclerView(rvImage, dynamicMediaList, noTextUi);
+ } else {
+ rvImage.setVisibility(View.GONE);
+ }
+ //头饰 贵族头饰
+ ImageView ivHeadWear = helper.getView(R.id.iv_head_wear);
+ GlideApp.with(ivHeadWear.getContext()).clear(ivHeadWear);
+ String headwearPic = item.getHeadwearPic();
+ String micDecorate = item.getMicDecorate();
+ if (!TextUtils.isEmpty(headwearPic)) {
+ NobleUtil.loadHeadWear(headwearPic, ivHeadWear);
+ } else if (!TextUtils.isEmpty(micDecorate)) {
+ NobleUtil.loadResource(micDecorate, ivHeadWear);
+ } else {
+ ivHeadWear.setImageDrawable(null);
+ }
+
+ //头像
+ ImageLoadUtilsV2.loadImage(helper.getView(R.id.iv_avatar), item.getAvatar());
+
+ DynamicNickDetailWidget widget = helper.getView(R.id.widget_nick_detail);
+ widget.setData(item);
+ View inOfficialMask = helper.getView(R.id.in_official_mask);
+ NamePlateHelper.INSTANCE.load(inOfficialMask, inOfficialMask.findViewById(R.id.tv_official_mask), inOfficialMask.findViewById(R.id.iv_official_mask), item.getNameplateWord(), item.getNameplatePic(), item.isCustomWord());
+
+ //时间
+ final String time = TimeUiUtils.getDynamicUi(item.getPublishTime());
+ helper.setGone(R.id.tv_time, !TextUtils.isEmpty(time));
+ helper.setText(R.id.tv_time, time);
+
+ ExpandableTextView etvContent = helper.getView(R.id.etv_content);
+ etvContent.setEventType(1);
+ if (noTextUi && item.getTopicTop() == 0) {
+ etvContent.setVisibility(View.GONE);
+ } else {
+ etvContent.setVisibility(View.VISIBLE);
+ CharSequence formatText = DynamicUiHelper.formatFirstDynamicContent(
+ item, etvContent.mTv, iconWidth, iconHeight);
+ if (item.getTopicTop() == 1) {
+ //置顶
+ formatText = TopicUpTextWrapper.INSTANCE.wrapUp(formatText, context);
+ }
+ etvContent.setText(formatText, mCollapsedStatus, helper.getAdapterPosition(), mCollapsedHeightStatus);
+ }
+ //标签
+ final List labels = item.getLabelList();
+ if (labels != null) {
+ ((TopicLabelWidget) helper.getView(R.id.topicView)).setLabels(labels);
+ }
+
+ final String worldName = item.getWorldName();
+ helper.setText(R.id.tv_mini_world_name, "#" + worldName);
+ helper.setGone(R.id.tv_mini_world_name, !TextUtils.isEmpty(worldName));
+ helper.setGone(R.id.space_view, !TextUtils.isEmpty(time) || !TextUtils.isEmpty(worldName));
+ //评论
+ 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(worldId, item.getDynamicId(), item.getUid(), status, 1)
+ .compose(RxHelper.bindContext(context))
+ .subscribe(new DontWarnObserver() {
+ @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.dynamic_adapter_worlddynamicadapter_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(), worldId,
+ helper.getAdapterPosition(), true, 1);
+ }
+ );
+
+ View.OnClickListener toDetailListener = v ->
+ DynamicDetailActivity.start(context, item.getDynamicId(), worldId,
+ helper.getAdapterPosition(), false, 1);
+
+ if (etvContent.mTv != null) {
+ etvContent.mTv.setOnClickListener(toDetailListener);
+ }
+
+ //跳转去详情
+ helper.itemView.setOnClickListener(toDetailListener);
+
+ helper.addOnClickListener(R.id.iv_more)
+ .addOnClickListener(R.id.ll_share);
+
+ 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);
+
+ }
+
+ 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) {
+// if (isAnim) {
+// AnimationDrawable drawable = (AnimationDrawable) context.getResources()
+// .getDrawable(R.drawable.anim_list_dy_like);
+// ivLikeAnim.setImageDrawable(drawable);
+// drawable.stop();
+// drawable.start();
+// } else {
+ ivLikeAnim.setImageResource(R.drawable.icon_dy_list_like);
+// }
+ } else {
+ ivLikeAnim.setImageResource(R.drawable.icon_dy_list_like_false);
+ }
+
+ }
+
+ private void initRecyclerView(RecyclerView rvImage, List imageUrl, boolean noTextUi) {
+ if (imageUrl == null) {
+ return;
+ }
+ 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 + divider;
+ params.height = calcSize.height + divider;
+ }
+ if (noTextUi) {
+ params.topMargin = imageTmNoText;
+ } else {
+ params.topMargin = imageTmHasText;
+ }
+ rvImage.setLayoutParams(params);
+ rvImage.setNestedScrollingEnabled(false);
+ rvImage.setLayoutManager(new GridLayoutManager(mContext, imageUrl.size() > 2 ? 3 : imageUrl.size()));
+ DynamicImageAdapter adapter = new DynamicImageAdapter(R.layout.item_dynamic_image, imageUrl);
+ adapter.setSingleImageHeight(calcSize.height);
+ adapter.setOnItemClickListener((adapter1, view, position) -> {
+ PagerOption option = new PagerOption().setSave(true);
+ BigPhotoActivity.start((Activity) mContext, ObjectTypeHelper.mediaToCustomList(imageUrl),
+ position, option);
+ }
+ );
+ rvImage.setAdapter(adapter);
+ }
+
+ 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);
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/dynamic/view/DynamicDetailActivity.java b/app/src/module_community/java/com/chwl/app/community/dynamic/view/DynamicDetailActivity.java
new file mode 100644
index 000000000..ac3d32d7d
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/dynamic/view/DynamicDetailActivity.java
@@ -0,0 +1,1162 @@
+package com.chwl.app.community.dynamic.view;
+
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+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.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.chwl.app.photo.BigPhotoActivity;
+import com.chwl.app.photo.PagerOption;
+import com.chwl.core.XConstants;
+import com.chwl.core.utils.CoreTextUtils;
+import com.coorchice.library.utils.LogUtils;
+import com.netease.nim.uikit.StatusBarUtil;
+import com.netease.nim.uikit.business.session.emoji.IEmoticonSelectedListener;
+import com.netease.nim.uikit.business.session.emoji.MoonUtil;
+import com.trello.rxlifecycle3.android.ActivityEvent;
+import com.chwl.app.R;
+import com.chwl.app.UIHelper;
+import com.chwl.app.avroom.ButtonItemFactory;
+import com.chwl.app.base.BaseViewBindingActivity;
+import com.chwl.app.common.widget.CircleImageView;
+import com.chwl.app.common.widget.dialog.DialogManager;
+import com.chwl.app.community.dynamic.adapter.CommentAdapter;
+import com.chwl.app.community.helper.CalcSize;
+import com.chwl.app.community.helper.DynamicUiHelper;
+import com.chwl.app.community.helper.ImageUiHelper;
+import com.chwl.app.community.helper.ShareDynamicHelper;
+import com.chwl.app.photo.DynamicImageAdapter;
+import com.chwl.app.community.utils.ObjectTypeHelper;
+import com.chwl.app.community.widget.DynamicNickDetailWidget;
+import com.chwl.app.community.widget.ExpandableTextView;
+import com.chwl.app.databinding.ActivityDynamicDetailBinding;
+import com.chwl.app.ui.utils.ImageLoadUtilsV2;
+import com.chwl.app.ui.widget.ButtonItem;
+import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
+import com.chwl.app.utils.RegexUtil;
+import com.chwl.app.utils.SpannableBuilder;
+import com.chwl.app.utils.TimeUiUtils;
+import com.chwl.core.auth.AuthModel;
+import com.chwl.core.community.bean.Comment;
+import com.chwl.core.community.bean.CommentResult;
+import com.chwl.core.community.bean.DynamicMedia;
+import com.chwl.core.community.bean.WorldDynamicBean;
+import com.chwl.core.community.bean.comment.PopupParams;
+import com.chwl.core.community.bean.comment.Reply;
+import com.chwl.core.community.bean.comment.ReplyResult;
+import com.chwl.core.community.dynamic.DynamicDetailModel;
+import com.chwl.core.community.dynamic.DynamicModel;
+import com.chwl.core.community.event.DynamicDetailFinishEvent;
+import com.chwl.core.community.event.DynamicRefreshEvent;
+import com.chwl.core.noble.NobleUtil;
+import com.chwl.core.user.UserModel;
+import com.chwl.core.user.bean.UserInfo;
+import com.chwl.core.utils.net.BeanObserver;
+import com.chwl.core.utils.net.DontWarnObserver;
+import com.chwl.core.utils.net.RxHelper;
+import com.chwl.library.utils.ListUtils;
+import com.chwl.library.utils.LogUtil;
+import com.chwl.library.utils.ResUtil;
+import com.chwl.library.utils.SingleToastUtil;
+import com.chwl.library.utils.keyboard.KeyboardVisibilityEvent;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import io.reactivex.Single;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+
+/**
+ * create by lvzebiao @2019/11/25
+ */
+public class DynamicDetailActivity extends BaseViewBindingActivity
+ implements IEmoticonSelectedListener, View.OnClickListener {
+
+ private final static String EXTRA_DYNAMIC_ID = "extra_dynamic_id";
+ private final static String EXTRA_WORLD_ID = "extra_world_id";
+ private final static String EXTRA_NEED_KEYBOARD = "extra_need_keyboard";
+ private final static String EXTRA_LIST_POSITION = "extra_list_position";
+
+ CircleImageView ivAvatar;
+ ImageView ivHeadWear;
+ DynamicNickDetailWidget widgetNickDetail;
+ TextView tvTime;
+ ImageView ivMore;
+ RecyclerView rvImage;
+ ExpandableTextView etvContent;
+ TextView tvCommentCount;
+ ConstraintLayout clOption;
+ ImageView ivLikePic;
+ TextView tvLikeCount;
+ ImageView ivCommentPic;
+ ImageView ivSharePic;
+ TextView tvCommentCountOption;
+ TextView tvFlagMiniWorld;
+ ConstraintLayout layoutRootMiniWorld;
+ TextView tvMiniWorldName;
+ private View viewLineDetailHeader;
+
+ private long dynamicId;
+
+ private long worldId;
+
+ private CommentAdapter adapter;
+ /**
+ * 对评论进行回复
+ */
+ public final static int TYPE_TARGET_COMMENT = 1;
+ /**
+ * 对回复进行回复
+ */
+ public final static int TYPE_TARGET_REPLAY = 2;
+
+ private int mReplyType; //0:评论动态, 评论及回复 1:对评论进行回复 2:对回复进行回复
+ private int mReplyPosition = -1;
+
+ private Reply cacheReply;
+ private boolean isErr = false;
+
+ private WorldDynamicBean bean;
+
+ private boolean isLoading;
+
+ private boolean noMoreData;
+
+ private String nextCommentId = null;
+
+ private final static int COMMENT_SIZE = 10;
+ /**
+ * 动态被删除,标记为ture
+ */
+ private boolean hasDeleteThisDynamic = false;
+
+ /**
+ * @param event 统计事件 1-话题客态、2-个人主页、3-APP内分享、4-消息互动通知、5-linkedme 6-动态广场
+ */
+ public static void start(Context context, long dynamicId, long worldId, int listPosition,
+ boolean needKeyboard, int event) {
+ if (dynamicId == 0) {
+ LogUtils.e(ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_01));
+ return;
+ }
+ String label = ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_02);
+ switch (event) {
+ case 1:
+ label = ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_03);
+ break;
+ case 2:
+ label = ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_04);
+ break;
+ case 3:
+ label = ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_05);
+ break;
+ case 4:
+ label = ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_06);
+ break;
+ case 5:
+ label = "linkedme";
+ break;
+ case 6:
+ label = ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_07);
+ break;
+ }
+
+ Intent intent = new Intent(context, DynamicDetailActivity.class);
+ intent.putExtra(EXTRA_DYNAMIC_ID, dynamicId);
+ intent.putExtra(EXTRA_WORLD_ID, worldId);
+ intent.putExtra(EXTRA_NEED_KEYBOARD, needKeyboard);
+ intent.putExtra(EXTRA_LIST_POSITION, listPosition);
+ context.startActivity(intent);
+ }
+
+ public static void start(Context context, long dynamicId, long worldId, boolean needKeyboard, int event) {
+ start(context, dynamicId, worldId, -1, needKeyboard, event);
+ }
+
+ public static void start(Context context, long dynamicId, long worldId, int event) {
+ start(context, dynamicId, worldId, false, event);
+ }
+
+ private View mHeaderView;
+
+ @Override
+ public void init() {
+ dynamicId = getIntent().getLongExtra(EXTRA_DYNAMIC_ID, 0L);
+ worldId = getIntent().getLongExtra(EXTRA_WORLD_ID, 0L);
+ initWhiteTitleBar(ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_09));
+ initRecyclerView();
+ initView();
+ loadComment(true, true);
+ //是否需要弹起键盘
+ if (getIntent().getBooleanExtra(EXTRA_NEED_KEYBOARD, false)) {
+ Single.timer(200, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .doOnSuccess(aLong -> showToCommentDynamicLayout())
+ .subscribe();
+ }
+ }
+
+ private void initView() {
+ binding.tvSend.setOnClickListener(this);
+ binding.ivEmoji.setOnClickListener(this);
+
+ binding.etReply.addTextChangedListener(new TextWatcher() {
+
+ private int start;
+ private int count;
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ this.start = start;
+ this.count = count;
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ MoonUtil.replaceEmoticons(context, s, start, count);
+
+ int editEnd = binding.etReply.getSelectionEnd();
+ binding.etReply.removeTextChangedListener(this);
+ while (s.toString().length() > 500 && editEnd > 0) {
+ s.delete(editEnd - 1, editEnd);
+ editEnd--;
+ }
+ binding.etReply.setSelection(editEnd);
+ binding.etReply.addTextChangedListener(this);
+
+ binding.tvSend.setEnabled(!CoreTextUtils.isEmptyText(s.toString()));
+ }
+ });
+
+ KeyboardVisibilityEvent.registerEventListener(this, isOpen -> {
+ isShowKeyboad = isOpen;
+ if (isOpen) {
+ binding.emoticonPickerView.setVisibility(View.GONE);
+ } else {
+ binding.emoticonPickerView.postDelayed(() -> {
+ if (binding.emoticonPickerView.getVisibility() == View.GONE) {
+ if (currNeedKeyboard) {
+ currNeedKeyboard = false;
+ Single.timer(200, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .doOnSuccess(aLong -> {
+ if (!currNeedKeyboard && !isShowKeyboad) {
+ clOption.setVisibility(View.VISIBLE);
+ mReplyPosition = -1;
+ }
+ })
+ .subscribe();
+ return;
+ }
+ clOption.setVisibility(View.VISIBLE);
+ mReplyPosition = -1;
+ }
+ currNeedKeyboard = false;
+ }, 210);
+
+ }
+ });
+
+ binding.etReply.setOnFocusChangeListener((v, hasFocus) -> {
+ if (hasFocus) {
+ hideEmojiView();
+ }
+ });
+
+ }
+
+ private void initHeaderView() {
+ mHeaderView = LayoutInflater.from(this).inflate(R.layout.head_dynamic_detail, null);
+ ivAvatar = mHeaderView.findViewById(R.id.iv_avatar);
+ ivHeadWear = mHeaderView.findViewById(R.id.iv_head_wear);
+ widgetNickDetail = mHeaderView.findViewById(R.id.widget_nick_detail);
+ tvTime = mHeaderView.findViewById(R.id.tv_time_detail);
+ ivMore = mHeaderView.findViewById(R.id.iv_more);
+ etvContent = mHeaderView.findViewById(R.id.etv_content);
+ rvImage = mHeaderView.findViewById(R.id.rv_image);
+ tvCommentCount = mHeaderView.findViewById(R.id.tv_comment_count);
+ clOption = mHeaderView.findViewById(R.id.cl_option);
+ ivLikePic = mHeaderView.findViewById(R.id.iv_like_pic);
+ tvLikeCount = mHeaderView.findViewById(R.id.tv_like_count);
+ ivCommentPic = mHeaderView.findViewById(R.id.iv_comment_pic);
+ ivSharePic = mHeaderView.findViewById(R.id.iv_share_pic);
+ tvCommentCountOption = mHeaderView.findViewById(R.id.tv_comment_count_option);
+ viewLineDetailHeader = mHeaderView.findViewById(R.id.view_line_detail_header);
+ tvFlagMiniWorld = mHeaderView.findViewById(R.id.tv_flag_mini_world);
+ layoutRootMiniWorld = mHeaderView.findViewById(R.id.layout_root_mini_world);
+ tvMiniWorldName = mHeaderView.findViewById(R.id.tv_mini_world_name);
+ viewLineDetailHeader.setVisibility(View.VISIBLE);
+ }
+
+ private boolean currNeedKeyboard = false;
+
+ private boolean isShowKeyboad = false;
+
+ private void initRecyclerView() {
+ initHeaderView();
+ binding.rvListComment.setLayoutManager(new LinearLayoutManager(context));
+ adapter = new CommentAdapter();
+ adapter.setHeaderAndEmpty(true);
+ adapter.setHeaderView(mHeaderView);
+ adapter.setOnLoadMoreListener(() -> {
+ if (isLoading || noMoreData) {
+ return;
+ }
+ LogUtil.print("onLoadMoreRequested...");
+ binding.rvListComment.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (ListUtils.isListEmpty(adapter.getData())) {
+ adapter.loadMoreEnd();
+ } else {
+ if (!isErr) {
+ //成功获取更多数据
+ LogUtil.print(ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_010));
+ loadComment(false, false);
+ } else {
+ //获取更多数据失败
+ isErr = true;
+ adapter.loadMoreFail();
+ }
+ }
+ }
+ }, 1000);
+ }, binding.rvListComment);
+
+
+ adapter.setOnItemClickListener((a, view, position) -> {
+
+ LogUtil.print(ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_011) + position);
+
+ clickOneLevelComment(position);
+ });
+
+ adapter.setOnItemChildClickListener((adapter, view, position) -> {
+ if (view.getId() == R.id.tv_content) {
+ LogUtil.print(ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_012));
+ clickOneLevelComment(position);
+ }
+ });
+ adapter.setOnItemChildLongClickListener((a, view, position) -> {
+
+ Comment comment = adapter.getDataItem(position);
+ if (comment == null) {
+ return false;
+ }
+ PopupParams params = new PopupParams();
+ params.setType(1);
+ params.setGroupPostion(position);
+ params.setCopyContent(comment.getContent());
+ params.setDeteleId(comment.getCommentId());
+ params.setCommentOwnerUid(comment.getUid());
+ showCopyPopup(view, params);
+ return true;
+ });
+ binding.rvListComment.setAdapter(adapter);
+
+
+ //动态详情回复项的点击事件
+ adapter.setOnCommentReplyItemChildClickListener(new CommentAdapter.OnCommentReplyItemChildClickListener() {
+ @Override
+ public void onCommentReplyItemChildClick(View view, int groupPosition, int childPosition) {
+
+ LogUtil.print("groupPosition:" + groupPosition);
+
+ LogUtil.print("childPosition:" + childPosition);
+
+ Comment comment = adapter.getDataItem(groupPosition);
+ if (comment == null) {
+ return;
+ }
+ cacheReply = comment.getItemReply(childPosition);
+ if (cacheReply == null) {
+ return;
+ }
+ if (view.getId() == R.id.item_reply_constraintlayout || view.getId() == R.id.tv_content) { //整个item项,回复事件
+ if (!UserModel.get().isMyseft(cacheReply.getUid()) && isBindPhone()) {
+ mReplyType = TYPE_TARGET_REPLAY;
+ mReplyPosition = groupPosition;
+ clOption.setVisibility(View.INVISIBLE);
+ binding.llReply.setVisibility(View.VISIBLE);
+ String nick = cacheReply.getNick();
+ binding.etReply.setHint(String.format(getString(R.string.dy_reply_someone),
+ RegexUtil.getPrintableString(nick)));
+ binding.etReply.requestFocus();
+ currNeedKeyboard = true;
+ showIME(binding.etReply);
+ }
+ }
+ }
+
+ @Override
+ public void onCommentReplyItemChildLongClick(View view, int groupPosition, int childPosition) {
+ if (view.getId() == R.id.tv_content) {
+ Comment comment = adapter.getDataItem(groupPosition);
+ if (comment == null) {
+ return;
+ }
+ List list = comment.getReplyList();
+ Reply reply = null;
+ if (childPosition >= 0 && childPosition < list.size()) {
+ reply = list.get(childPosition);
+ }
+ if (reply == null) {
+ return;
+ }
+ PopupParams params = new PopupParams();
+ params.setType(2);
+ params.setGroupPostion(groupPosition);
+ params.setChildPosition(childPosition);
+ params.setCopyContent(reply.getContent());
+ params.setCommentOwnerUid(reply.getUid());
+ params.setDeteleId(reply.getReplyId());
+ showCopyPopup(view, params);
+ }
+ }
+
+ @Override
+ public void onLoadMoreClick(long commentId, long timestamp, int groupPosition) {
+ DynamicDetailModel.get().getReplyList(dynamicId, commentId, 5, String.valueOf(timestamp))
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(ReplyResult replyResult, String error) {
+ super.accept(replyResult, error);
+ if (error != null) {
+ toast(error);
+ return;
+ }
+ getMoreReplySuccess(replyResult, groupPosition);
+ }
+ });
+ }
+ });
+
+ //刷新
+ binding.refreshLayout.setOnRefreshListener(() -> {
+ if (isLoading) {
+ return;
+ }
+ loadComment(true, true);
+ });
+
+ }
+
+ private void clickOneLevelComment(int position) {
+ if (!isBindPhone()) {
+ return;
+ }
+ mReplyType = TYPE_TARGET_COMMENT;
+ mReplyPosition = position;
+ clOption.setVisibility(View.INVISIBLE);
+ binding.llReply.setVisibility(View.VISIBLE);
+ Comment bean = adapter.getData().get(position);
+ binding.etReply.setHint(String.format(getString(R.string.dy_reply_someone), bean.getNick()));
+ binding.etReply.requestFocus();
+ currNeedKeyboard = true;
+ showIME(binding.etReply);
+ }
+
+ private void loadComment(boolean isRefresh, boolean reloadDetail) {
+ if (reloadDetail) {
+ loadDetail();
+ }
+ if (isLoading) {
+ return;
+ }
+ isLoading = true;
+ if (isRefresh) {
+ isErr = false;
+ noMoreData = false;
+ nextCommentId = null;
+ }
+ DynamicDetailModel.get().getCommentList(dynamicId, nextCommentId, COMMENT_SIZE)
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(CommentResult commentResult, String error) {
+ super.accept(commentResult, error);
+ binding.refreshLayout.setRefreshing(false);
+ isLoading = false;
+ if (error != null) {
+ isErr = true;
+ } else {
+ isErr = false;
+ }
+ List list = null;
+ if (commentResult != null) {
+ list = commentResult.getCommentList();
+ nextCommentId = String.valueOf(commentResult.getNextTimestamp());
+ }
+
+ if (list == null) {
+ list = new ArrayList<>();
+ }
+
+ if (isRefresh) {
+ adapter.setNewData(list);
+ adapter.disableLoadMoreIfNotFullPage(binding.rvListComment);
+ } else {
+ adapter.addData(list);
+ }
+
+ if (ListUtils.isListEmpty(list)) {
+ noMoreData = true;
+ }
+
+ if (!ListUtils.isListEmpty(adapter.getData()) && ListUtils.isListEmpty(list)) {
+ adapter.loadMoreEnd();
+ } else {
+ adapter.loadMoreComplete();
+ }
+
+ viewLineDetailHeader.setVisibility(View.VISIBLE);
+ if (adapter.getData().isEmpty()) {
+ viewLineDetailHeader.setVisibility(View.INVISIBLE);
+ View emptyView = getLayoutInflater().inflate(R.layout.dy_empty_dynamic_comment, null);
+
+ ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ UIUtil.dip2px(context, 260));
+ emptyView.setLayoutParams(layoutParams);
+ ((ImageView) emptyView.findViewById(R.id.no_data_icon))
+ .setImageResource(R.drawable.icon_common_failure);
+ ((TextView) emptyView.findViewById(R.id.no_data_text))
+ .setText(R.string.dy_empty_comment_tips);
+ adapter.setEmptyView(emptyView);
+ }
+
+ }
+ });
+ }
+
+ private void showCopyPopup(View v, PopupParams params) {
+
+ View view = LayoutInflater.from(this).inflate(R.layout.popup_dy_comment, null);
+ PopupWindow popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ TextView tvCopy = view.findViewById(R.id.tv_copy);
+ tvCopy.setOnClickListener(v1 -> {
+ ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+ cm.setText(params.getCopyContent());
+ toast(R.string.copy_success);
+ popupWindow.dismiss();
+ });
+ View llContainer = view.findViewById(R.id.ll_container);
+ TextView tvDelete = view.findViewById(R.id.tv_delete);
+ TextView tvReport = view.findViewById(R.id.tv_report);
+
+ //如果是帖子发布者uid
+ long dynamicOwnerUid = 0;
+ if (bean != null) {
+ dynamicOwnerUid = bean.getUid();
+ }
+ //这里就不画.9图了,直接采用2张不同背景图来处理
+ llContainer.setBackgroundResource(R.drawable.bg_dy_popup_comment);
+ tvDelete.setVisibility(View.GONE);
+ tvReport.setVisibility(View.GONE);
+ if (UserModel.get().isMyseft(dynamicOwnerUid)) {
+ tvDelete.setVisibility(View.VISIBLE);
+ if (!UserModel.get().isMyseft(params.getCommentOwnerUid())) {
+ //如果是自己发的动态,但是不是自己的评论,举报 删除都有
+ tvReport.setVisibility(View.VISIBLE);
+ llContainer.setBackgroundResource(R.drawable.bg_dy_popup_comment_three);
+ }
+ } else {
+ if (UserModel.get().isMyseft(params.getCommentOwnerUid())) {
+ tvDelete.setVisibility(View.VISIBLE);
+ } else {
+ tvReport.setVisibility(View.VISIBLE);
+ }
+ }
+
+ tvDelete.setOnClickListener(v1 -> {
+ popupWindow.dismiss();
+ DynamicDetailModel.get().deleteComment(params.getDeteleId())
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(String s, String error) {
+ super.accept(s, error);
+ if (error != null) {
+ toast(error);
+ return;
+ }
+ deleteCommentSuccess(params);
+ }
+ });
+ });
+
+ tvReport.setOnClickListener(v1 -> {
+ popupWindow.dismiss();
+ UIHelper.showReportPage(context, params.getCommentOwnerUid(), XConstants.REPORT_TYPE_DYNAMICCOMMENT);
+ });
+
+ popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ popupWindow.setOutsideTouchable(true);
+ popupWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ int[] vLoc = new int[2];
+ v.getLocationInWindow(vLoc);
+ int offsetHeight = 0;
+ int minHeight = UIUtil.dip2px(context, 120f);
+ if (vLoc[1] < minHeight) {
+ offsetHeight = minHeight - vLoc[1];
+ }
+ popupWindow.showAsDropDown(v, UIUtil.dip2px(context, 40), -v.getHeight()
+ - popupWindow.getContentView().getMeasuredHeight() + offsetHeight);
+
+ }
+
+
+ private void loadDetail() {
+ DynamicDetailModel.get().getDetail(dynamicId, worldId)
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(WorldDynamicBean bean, String error) {
+ super.accept(bean, error);
+ if (error != null) {
+ toast(error);
+ finish();
+ return;
+ }
+ showDynamicDetails(bean);
+ }
+ });
+ }
+
+ private void showDynamicDetails(WorldDynamicBean info) {
+ bean = info;
+ if (bean == null) {
+ return;
+ }
+ ImageLoadUtilsV2.loadAvatar(ivAvatar, bean.getAvatar());
+ widgetNickDetail.setData(bean);
+
+ //更多
+ ivMore.setOnClickListener(v -> {
+ header_more();
+ });
+
+
+ tvTime.setText(TimeUiUtils.getDynamicUi(bean.getPublishTime()));
+ etvContent.setVisibility(View.GONE);
+ etvContent.setEventType(3);
+ if (!TextUtils.isEmpty(bean.getContent())) {
+ etvContent.setVisibility(View.VISIBLE);
+ int iconWidth = UIUtil.dip2px(context, 32);
+ int iconHeight = UIUtil.dip2px(context, 15);
+ CharSequence formatText = DynamicUiHelper.formatFirstDynamicContent(
+ bean, etvContent.mTv, iconWidth, iconHeight);
+ etvContent.setText(formatText);
+ }
+
+ initImageRv();
+
+ setLikeCount(false);
+
+ updateCommentCount();
+
+ //头饰 贵族头饰
+ String headwearEffect = bean.getHeadwearEffect();
+ String headwearPic = bean.getHeadwearPic();
+ String micDecorate = bean.getMicDecorate();
+ if (!TextUtils.isEmpty(headwearEffect)) {
+ NobleUtil.loadHeadWear(headwearEffect, ivHeadWear);
+ } else if (!TextUtils.isEmpty(headwearPic)) {
+ NobleUtil.loadHeadWear(headwearPic, ivHeadWear);
+ } else if (!TextUtils.isEmpty(micDecorate)) {
+ NobleUtil.loadResource(micDecorate, ivHeadWear);
+ } else {
+ ivHeadWear.setImageDrawable(null);
+ }
+
+ View.OnClickListener infoListener = v -> {
+ if (bean == null) {
+ return;
+ }
+ UIHelper.showUserInfoAct(context, bean.getUid());
+ };
+ ivHeadWear.setOnClickListener(infoListener);
+ widgetNickDetail.setOnClickListener(infoListener);
+
+ //话题显示
+ layoutRootMiniWorld.setVisibility(View.GONE);
+// layoutRootMiniWorld.setVisibility(bean.getWorldId() > 0 ? View.VISIBLE : View.GONE);
+// if (!TextUtils.isEmpty(bean.getWorldName())) {
+// tvMiniWorldName.setText("#" + bean.getWorldName());
+// }
+// //去看看
+// tvFlagMiniWorld.setVisibility(bean.isInWorld() ? View.GONE : View.GONE);
+
+
+// tvMiniWorldName.setOnClickListener(v -> {
+// TopicMainActivity.start(context, String.valueOf(bean.getWorldId()));
+// });
+
+ //点赞
+ ivLikePic.setOnClickListener(v -> {
+ header_like();
+ });
+
+ //评论
+ ivCommentPic.setOnClickListener(v -> {
+ showToCommentDynamicLayout();
+ });
+
+ //分享动态
+ ivSharePic.setOnClickListener(v -> {
+ new ShareDynamicHelper(DynamicDetailActivity.this)
+ .share(bean, worldId);
+ });
+
+ }
+
+ /**
+ * header - 更多
+ */
+ private void header_more() {
+ List 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() {
+ @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));
+ EventBus.getDefault().post(new DynamicRefreshEvent());
+ finish();
+ }
+ });
+ });
+ 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(context, bean.getUid(),
+ XConstants.REPORT_TYPE_WORLDDYNAMIC);
+ });
+ list.add(item);
+ }
+ if (UserModel.get().isMyseft(bean.getUid()) ||
+ isThisWorldOwner(bean)) {
+ ButtonItem item = new ButtonItem(ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_020), () -> deleteDynamic(bean));
+ list.add(item);
+ }
+ getDialogManager().showCommonPopupDialog(list, getString(R.string.cancel));
+ }
+
+ /**
+ * header - 点赞
+ */
+ private void header_like() {
+ ivLikePic.setEnabled(false);
+ int status = bean.isLike() ? 0 : 1;
+ DynamicModel.get().like(worldId, dynamicId, bean.getUid(), status, 3)
+ .compose(RxHelper.bindContext(context))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(String s, String error) {
+ super.accept(s, error);
+ ivLikePic.setEnabled(true);
+ if (error != null) {
+ SingleToastUtil.showToast(error);
+ } else {
+ if (bean == null) {
+ return;
+ }
+ if (status == 1) {
+ bean.setLikeCount(bean.getLikeCount() + 1);
+ } else {
+ bean.setLikeCount(bean.getLikeCount() - 1);
+ }
+ bean.setLike(status == 1);
+ setLikeCount(true);
+ }
+ }
+ });
+ }
+
+ private void deleteDynamic(WorldDynamicBean bean) {
+ getDialogManager().showOkCancelWithTitleDialog(ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_023),
+ new DialogManager.OkCancelDialogListener() {
+ @Override
+ public void onOk() {
+ if (bean == null) {
+ return;
+ }
+ DynamicModel.get().delete(worldId, bean.getDynamicId())
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(String s, String error) {
+ super.accept(s, error);
+ if (error != null) {
+ toast(error);
+ } else {
+ toast(R.string.delete_success);
+ hasDeleteThisDynamic = true;
+ finish();
+ }
+ }
+ });
+
+ }
+ });
+ }
+
+ private boolean isThisWorldOwner(WorldDynamicBean bean) {
+ return bean != null && AuthModel.get().getCurrentUid() == bean.getWorldUid();
+ }
+
+ private void initImageRv() {
+ List imageUrl = bean.getDynamicResList();
+ if (ListUtils.isListEmpty(imageUrl)) {
+ rvImage.setVisibility(View.GONE);
+ return;
+ }
+ rvImage.setVisibility(View.VISIBLE);
+ rvImage.setNestedScrollingEnabled(false);
+ rvImage.setLayoutManager(new GridLayoutManager(this, imageUrl.size() > 2 ? 3 : imageUrl.size()));
+
+ int imageBorder = UIUtil.getScreenWidth(context) *
+ ImageUiHelper.BORDER_MIN / ImageUiHelper.BORDER_MAX;
+ int divider = UIUtil.dip2px(context, 10);
+ 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 + divider;
+ params.height = calcSize.height + divider;
+ }
+ rvImage.setLayoutParams(params);
+
+ DynamicImageAdapter adapter = new DynamicImageAdapter(R.layout.item_dynamic_image, imageUrl);
+ adapter.setSingleImageHeight(calcSize.height);
+ adapter.setOnItemClickListener((adapter1, view, position) -> {
+ PagerOption option = new PagerOption().setSave(true);
+ BigPhotoActivity.start(DynamicDetailActivity.this, ObjectTypeHelper.mediaToCustomList(imageUrl),
+ position, option);
+ }
+ );
+ rvImage.setAdapter(adapter);
+ }
+
+ private void setLikeCount(boolean isAnim) {
+ int likeCount = bean.getLikeCount();
+ String likeCountStr;
+ if (likeCount < 0) {
+ likeCountStr = "0";
+ } else if (likeCount >= 100000) {
+ likeCountStr = "99999+";
+ } else {
+ likeCountStr = String.valueOf(likeCount);
+ }
+ tvLikeCount.setText(likeCountStr);
+
+ if (bean.isLike()) {
+ ivLikePic.setImageResource(R.drawable.icon_dy_list_like);
+ } else {
+ ivLikePic.setImageResource(R.drawable.icon_dy_list_like_false);
+ }
+ }
+
+ private void updateCommentCount() {
+ if (bean == null) {
+ return;
+ }
+ SpannableBuilder builder = new SpannableBuilder();
+ if (bean.getCommentCount() < 0) {
+ bean.setCommentCount(0);
+ }
+ String commentCountStr = String.valueOf(bean.getCommentCount());
+ if (bean.getCommentCount() >= 100000) {
+ commentCountStr = "99999+";
+ }
+ String comment = ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_024) + commentCountStr + ")";
+ tvCommentCount.setText(comment);
+ tvCommentCountOption.setText(commentCountStr);
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (bean == null) {
+ return;
+ }
+ switch (view.getId()) {
+
+ case R.id.tv_send:
+ binding.tvSend.setEnabled(false);
+ String content = binding.etReply.getText().toString();
+ if (mReplyType == TYPE_TARGET_COMMENT || mReplyType == TYPE_TARGET_REPLAY) {
+ //对一级评论回复
+ long paramId = 0;
+ if (mReplyType == TYPE_TARGET_REPLAY) {
+ if (cacheReply != null) {
+ paramId = cacheReply.getReplyId();
+ }
+ } else {
+ paramId = adapter.getItemCommentId(mReplyPosition);
+ }
+ DynamicDetailModel.get().reply(dynamicId, paramId, content)
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(Reply reply, String error) {
+ super.accept(reply, error);
+ if (error != null) {
+ toast(error);
+ return;
+ }
+ replySuccess(reply, mReplyPosition);
+ }
+ });
+ } else {
+ DynamicDetailModel.get().publishComment(dynamicId, content)
+ .compose(bindUntilEvent(ActivityEvent.DESTROY))
+ .subscribe(new DontWarnObserver() {
+ @Override
+ public void accept(String s, String error) {
+ super.accept(s, error);
+ if (error != null) {
+ toast(error);
+ return;
+ }
+ onAddCommentSuccess();
+ }
+ });
+ }
+ break;
+
+ case R.id.iv_emoji:
+ showEmojiView();
+ break;
+ }
+ }
+
+ private void onAddCommentSuccess() {
+ toast(ResUtil.getString(R.string.dynamic_view_dynamicdetailactivity_026));
+ recoverBottomView();
+ loadComment(true, false);
+ if (bean != null) {
+ bean.setCommentCount(bean.getCommentCount() + 1);
+ updateCommentCount();
+ }
+ }
+
+ private void recoverBottomView() {
+ hideIME(binding.etReply);
+ mReplyType = 0;
+ binding.etReply.setHint(R.string.dy_pub_comment);
+ binding.etReply.setText("");
+ clOption.setVisibility(View.VISIBLE);
+ binding.emoticonPickerView.setVisibility(View.GONE);
+ }
+
+ private void replySuccess(Reply result, int replyPosition) {
+ recoverBottomView();
+ Comment listBean = adapter.getDataItem(mReplyPosition);
+ if (listBean == null) {
+ return;
+ }
+ if (result.getParentId() != listBean.getCommentId()) {
+ //一般是通过
+ return;
+ }
+ if (listBean.getReplyInfo().getLeftCount() <= 0) {
+ //如果已经没有下一页回复了,回复成功后,直接添加一项
+ listBean.addReply(result);
+ }
+ //更新下,剩余的回复数量
+ int newLeftCount = result.getReplyCount() - listBean.getReplyList().size();
+ if (newLeftCount < 0) {
+ newLeftCount = 0;
+ }
+ listBean.getReplyInfo().setLeftCount(newLeftCount);
+ adapter.notifyItemChanged(replyPosition + 1);
+ if (bean != null) {
+ bean.setCommentCount(bean.getCommentCount() + 1);
+ updateCommentCount();
+ }
+ }
+
+ public void getMoreReplySuccess(ReplyResult newReplyInfo, int groupPosition) {
+ Comment listBean = adapter.getDataItem(groupPosition);
+ if (listBean == null) {
+ return;
+ }
+ ReplyResult oldReplyInfo = listBean.getReplyInfo();
+ oldReplyInfo.setLeftCount(newReplyInfo.getLeftCount());
+ oldReplyInfo.setNextTimestamp(newReplyInfo.getNextTimestamp());
+ List oldReplyList = oldReplyInfo.getReplyList();
+ if (!ListUtils.isListEmpty(newReplyInfo.getReplyList())) {
+ oldReplyList.addAll(newReplyInfo.getReplyList());
+ }
+ adapter.notifyItemChanged(groupPosition + 1);
+ }
+
+
+ @Override
+ public void onEmojiSelected(String key) {
+ try {
+ Editable mEditable = binding.etReply.getText();
+ if (key.equals("/DEL")) {
+ binding.etReply.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
+ } else {
+ int start = binding.etReply.getSelectionStart();
+ int end = binding.etReply.getSelectionEnd();
+ start = (start < 0 ? 0 : start);
+ end = (start < 0 ? 0 : end);
+ mEditable.replace(start, end, key);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onStickerSelected(String categoryName, String stickerName) {
+
+ }
+
+ private void deleteCommentSuccess(PopupParams params) {
+ toast(R.string.delete_success);
+ if (params.getType() == 1) {
+ //删除评论
+ if (bean != null) {
+ Comment comment = adapter.getDataItem(params.getGroupPostion());
+ if (comment == null) {
+ return;
+ }
+ ReplyResult result = comment.getReplyInfo();
+ int replyCount = result.getLeftCount();
+ if (!ListUtils.isListEmpty(result.getReplyList())) {
+ replyCount += result.getReplyList().size();
+ }
+ bean.setCommentCount(bean.getCommentCount() - replyCount - 1);
+ updateCommentCount();
+ }
+ adapter.safeDelete(params.getGroupPostion());
+ } else if (params.getType() == 2) {
+ //删除评论中的回复
+ if (bean != null) {
+ bean.setCommentCount(bean.getCommentCount() - 1);
+ updateCommentCount();
+ }
+ Comment comment = adapter.getDataItem(params.getGroupPostion());
+ if (comment == null) {
+ return;
+ }
+ List list = comment.getReplyList();
+ if (params.getChildPosition() >= 0 && params.getChildPosition() < list.size()) {
+ list.remove(params.getChildPosition());
+ adapter.notifyDataSetChanged();
+ }
+ }
+ }
+
+ private void hideEmojiView() {
+ binding.emoticonPickerView.setVisibility(View.GONE);
+ }
+
+ private void showEmojiView() {
+ binding.etReply.clearFocus();
+ hideIME(binding.etReply);
+ binding.emoticonPickerView.postDelayed(() -> {
+ binding.emoticonPickerView.setVisibility(View.VISIBLE);
+ binding.emoticonPickerView.show(this);
+ }, 200);
+ }
+
+ /**
+ * 展示对动态进行评论的输入布局
+ */
+ private void showToCommentDynamicLayout() {
+ if (!isBindPhone()) {
+ return;
+ }
+ mReplyType = 0;
+ mReplyPosition = -1;
+ clOption.setVisibility(View.INVISIBLE);
+ binding.llReply.setVisibility(View.VISIBLE);
+ binding.etReply.requestFocus();
+ binding.etReply.setHint(R.string.dy_pub_comment);
+ showIME(binding.etReply);
+ }
+
+ @Override
+ public void finish() {
+ int listPosition = getIntent().getIntExtra(EXTRA_LIST_POSITION, -1);
+ if (listPosition >= 0 && bean != null) {
+ EventBus.getDefault().post(new DynamicDetailFinishEvent(listPosition, bean, hasDeleteThisDynamic));
+ }
+ super.finish();
+ }
+
+ private boolean isBindPhone() {
+ UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
+ if (userInfo == null) {
+ SingleToastUtil.showToast(ResUtil.getString(R.string.yizhuan_xchat_android_constants_xchatconstants_016));
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected boolean needSteepStateBar() {
+ return true;
+ }
+
+ @Override
+ protected void setStatusBar() {
+ super.setStatusBar();
+ StatusBarUtil.transparencyBar(this);
+ StatusBarUtil.StatusBarLightMode(this);
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/helper/CalcSize.java b/app/src/module_community/java/com/chwl/app/community/helper/CalcSize.java
new file mode 100644
index 000000000..8a1e74534
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/helper/CalcSize.java
@@ -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;
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/helper/DynamicUiHelper.java b/app/src/module_community/java/com/chwl/app/community/helper/DynamicUiHelper.java
new file mode 100644
index 000000000..01dcc458b
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/helper/DynamicUiHelper.java
@@ -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();
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/helper/ImageUiHelper.java b/app/src/module_community/java/com/chwl/app/community/helper/ImageUiHelper.java
new file mode 100644
index 000000000..95f5fd88b
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/helper/ImageUiHelper.java
@@ -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);
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/helper/ShareDynamicHelper.java b/app/src/module_community/java/com/chwl/app/community/helper/ShareDynamicHelper.java
new file mode 100644
index 000000000..bf9f5affd
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/helper/ShareDynamicHelper.java
@@ -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;
+ }
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/holder/DynamicSysHolder.java b/app/src/module_community/java/com/chwl/app/community/holder/DynamicSysHolder.java
new file mode 100644
index 000000000..be12dd20a
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/holder/DynamicSysHolder.java
@@ -0,0 +1,133 @@
+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.fastjson.JSON;
+import com.chwl.core.msg.sys.bean.ErbanSysMsgComponent;
+import com.chwl.core.msg.sys.bean.ErbanSysMsgInfo;
+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 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)));
+ }
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/im/WorldDynamicShareViewHolder.java b/app/src/module_community/java/com/chwl/app/community/im/WorldDynamicShareViewHolder.java
new file mode 100644
index 000000000..0040a4c4d
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/im/WorldDynamicShareViewHolder.java
@@ -0,0 +1,103 @@
+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.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();
+ ImageLoadUtilsV2.loadAvatar(rivCover, dynamicImMsg.getImageUrl());
+
+ 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();
+ }
+
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/publish/ImageAdapter.java b/app/src/module_community/java/com/chwl/app/community/publish/ImageAdapter.java
new file mode 100644
index 000000000..7867f8169
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/publish/ImageAdapter.java
@@ -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 {
+
+
+ public ImageAdapter(int layoutResId, @Nullable List 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);
+
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/publish/presenter/PublishPresenter.java b/app/src/module_community/java/com/chwl/app/community/publish/presenter/PublishPresenter.java
new file mode 100644
index 000000000..8f3d88669
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/publish/presenter/PublishPresenter.java
@@ -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 {
+
+ private PublishBody publishBody;
+ private Disposable mImageUploadSubscribe;
+
+ private boolean isOriginalImage;
+
+ private MiniWorldChooseInfo miniWorldChooseInfo = new MiniWorldChooseInfo();
+
+ public void publishDy(List list, long worldId, String content, boolean isOriginalImage) {
+ publishBody = new PublishBody();
+ List 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>) s ->
+ PublishModel.get().publish(publishBody))
+ .subscribe(new DontWarnObserver() {
+ @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 uploadImage(List 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 imagePaths) {
+ if (imagePaths == null || imagePaths.size() == 0) {
+ return;
+ }
+ DynamicMedia item = imagePaths.get(0);
+ String file = item.getLocalFilePath();
+ Single.create((SingleOnSubscribe) 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>)
+ path -> FileModel.get().uploadFile(path))
+ .compose(bindUntilEvent(PresenterEvent.DESTROY))
+ .subscribe(new DontWarnObserver() {
+ @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>() {
+ @Override
+ public void onSubscribe(Disposable d) {
+
+ }
+
+ @Override
+ public void onSuccess(List 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();
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/publish/presenter/WorldChoosePresenter.java b/app/src/module_community/java/com/chwl/app/community/publish/presenter/WorldChoosePresenter.java
new file mode 100644
index 000000000..b1c170205
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/publish/presenter/WorldChoosePresenter.java
@@ -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 {
+
+ 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>() {
+ @Override
+ public void onSubscribe(Disposable d) {
+
+ }
+
+ @Override
+ public void onSuccess(List 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;
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/publish/view/IPublishView.java b/app/src/module_community/java/com/chwl/app/community/publish/view/IPublishView.java
new file mode 100644
index 000000000..05fe44421
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/publish/view/IPublishView.java
@@ -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 list);
+ void recommendWorldsFails(String error);
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/publish/view/IWorldsChooseView.java b/app/src/module_community/java/com/chwl/app/community/publish/view/IWorldsChooseView.java
new file mode 100644
index 000000000..98ff2b322
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/publish/view/IWorldsChooseView.java
@@ -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 list);
+ void squareWorldsFails(String error);
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/publish/view/PublishActivity.java b/app/src/module_community/java/com/chwl/app/community/publish/view/PublishActivity.java
new file mode 100644
index 000000000..d1d2c2b53
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/publish/view/PublishActivity.java
@@ -0,0 +1,656 @@
+
+package com.chwl.app.community.publish.view;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+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.photo.BigPhotoActivity;
+import com.chwl.app.photo.PagerOption;
+import com.chwl.core.utils.CoreTextUtils;
+import com.example.matisse.Matisse;
+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 com.chwl.app.R;
+import com.chwl.app.base.BaseMvpActivity;
+import com.chwl.app.common.widget.dialog.DialogManager;
+import com.chwl.app.community.ConstantValue;
+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.ui.widget.dialog.CommonTipDialog;
+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.SharedPreferenceUtils;
+import com.chwl.core.utils.net.DontWarnObserver;
+import com.chwl.library.base.factory.CreatePresenter;
+import com.chwl.library.common.photo.PhotoProvider;
+import com.chwl.library.common.util.PhotoCompressUtil;
+import com.chwl.library.common.util.PhotosCompressCallback;
+import com.chwl.library.easypermisssion.EasyPermissions;
+import com.chwl.library.easyphoto.models.album.entity.Photo;
+import com.chwl.library.easyphoto.utils.settings.SettingsUtils;
+import com.chwl.library.utils.ResUtil;
+import com.chwl.library.utils.SingleToastUtil;
+import com.example.matisse.internal.entity.CustomItem;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import io.reactivex.Single;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import kotlin.Unit;
+import kotlin.jvm.functions.Function1;
+import kotlinx.coroutines.Job;
+
+/**
+ * create by lvzebiao @2019/11/11
+ */
+@CreatePresenter(PublishPresenter.class)
+public class PublishActivity extends BaseMvpActivity
+ implements IPublishView, WorldsChooseFrg.ChooseWorldCallback, EasyPermissions.PermissionCallbacks,
+ 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 imageShowList = new ArrayList<>();
+
+ private List 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) 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 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
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_CODE_STORAGE) {
+ checkStoragePermission();
+ } else if (resultCode == RESULT_OK) {
+ switch (requestCode) {
+ case REQUEST_CODE_OPEN_PHOTO_PROVIDER:
+ if (data == null) {
+ return;
+ }
+ PhotoProvider.getResultPathListAsync(data, new Function1, Unit>() {
+ @Override
+ public Unit invoke(List extends Photo> list) {
+ if (list.isEmpty()) {
+ return null;
+ } else {
+ if (mJob != null) {
+ mJob.cancel(null);
+ }
+ ArrayList pathList = new ArrayList<>();
+ for (Photo photo : list) {
+ pathList.add(photo.path);
+ }
+ mJob = PhotoCompressUtil.compress(PublishActivity.this, pathList,
+ PhotoCompressUtil.getCompressCachePath("publish")
+ , new PhotosCompressCallback() {
+ @Override
+ public void onSuccess(@NonNull ArrayList compressedImgList) {
+ List pathResult = new ArrayList<>();
+ for (int i = 0; i < compressedImgList.size(); i++) {
+ if (i < list.size()) {
+ Photo photo = list.get(i);
+ String format = "image/jpeg";
+ if (photo.type != null) {
+ format = photo.type;
+ }
+ pathResult.add(new CustomItem(compressedImgList.get(i), CustomItem.IMAGE_NORMAL, format, photo.width, photo.height));
+ }
+ }
+ 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);
+ }
+ return null;
+ }
+ });
+ break;
+
+ case ConstantValue.CODE_CHOOSE_PHOTO:
+ String mimeType = Matisse.obtainMineResult(data);
+ List pathResult = Matisse.obtainPathResult(data);
+ if ("video".equals(mimeType)) {
+ toast(ResUtil.getString(R.string.publish_view_publishactivity_04));
+ return;
+ }
+ if (pathResult == null) {
+ return;
+ }
+ LogUtil.print(pathResult);
+
+ uploadList.addAll(pathResult);
+ updateImagesData();
+
+ isOriginalImage = Matisse.obtainOriginalImageResult(data);
+ LogUtil.print("isOriginalImage:" + isOriginalImage);
+ SharedPreferenceUtils.put(KEY_SP_ORIGINAL_IMAGE, isOriginalImage);
+
+ break;
+
+ case BigPhotoActivity.CODE_DELETE_PHOTO:
+ List newList = data.getParcelableArrayListExtra(
+ BigPhotoActivity.KEY_IMG_URL);
+ uploadList.clear();
+ uploadList.addAll(newList);
+ updateImagesData();
+ break;
+
+ }
+ }
+ }
+
+ @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() {
+ @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 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 miniWorldChooseInfoList;
+
+ private void addMiniWorldList(List 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);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
+ }
+
+ @Override
+ public void onPermissionsGranted(int requestCode, @NonNull List perms) {
+ if (requestCode == PERMISSION_CODE_STORAGE) {
+ checkStoragePermission();
+ }
+ }
+
+ @Override
+ public void onPermissionsDenied(int requestCode, @NonNull List perms) {
+ if (requestCode == PERMISSION_CODE_STORAGE) {
+ String requestTip = getString(R.string.permission_storage_denied);
+ CommonTipDialog mPrivacyDialog = new CommonTipDialog(context);
+ mPrivacyDialog.setTipMsg(requestTip);
+ mPrivacyDialog.setOkText(getString(R.string.room_perform_go_update));
+ mPrivacyDialog.setOnActionListener(new CommonTipDialog.OnActionListener() {
+ @Override
+ public void onOk() {
+ //同意跳到应用详情页面
+ SettingsUtils.startMyApplicationDetailsForResult(PublishActivity.this,
+ getPackageName());
+ }
+
+ @Override
+ public void onCancel() {
+ CommonTipDialog.OnActionListener.super.onCancel();
+ //取消跳到应用详情页面
+ ToastUtils.show(getString(R.string.permission_storage_refused));
+ }
+ });
+ mPrivacyDialog.show();
+ }
+ }
+
+ private void checkStoragePermission() {
+ if (!EasyPermissions.hasPermissions(
+ this,
+ Build.VERSION.SDK_INT >= 33 ? Manifest.permission.READ_MEDIA_IMAGES : Manifest.permission.READ_EXTERNAL_STORAGE
+ )
+ ) {
+ EasyPermissions.requestPermissions(
+ this,
+ getString(R.string.permission_storage_rationale),
+ PERMISSION_CODE_STORAGE,
+ Build.VERSION.SDK_INT >= 33 ? Manifest.permission.READ_MEDIA_IMAGES : Manifest.permission.READ_EXTERNAL_STORAGE
+ );
+ } else {
+ PhotoProvider.photoProvider(
+ this,
+ maxSelect - uploadList.size(),
+ true,
+ REQUEST_CODE_OPEN_PHOTO_PROVIDER,
+ true,
+ true
+ );
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mJob != null) {
+ mJob.cancel(null);
+ }
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/publish/view/WorldChooseAdapter.java b/app/src/module_community/java/com/chwl/app/community/publish/view/WorldChooseAdapter.java
new file mode 100644
index 000000000..d0bbe74ec
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/publish/view/WorldChooseAdapter.java
@@ -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 {
+
+ 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);
+
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/publish/view/WorldsChooseFrg.java b/app/src/module_community/java/com/chwl/app/community/publish/view/WorldsChooseFrg.java
new file mode 100644
index 000000000..eb366d2c8
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/publish/view/WorldsChooseFrg.java
@@ -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 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 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 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);
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/square/SquareDynamicFragment.java b/app/src/module_community/java/com/chwl/app/community/square/SquareDynamicFragment.java
new file mode 100644
index 000000000..12a2b0a2d
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/square/SquareDynamicFragment.java
@@ -0,0 +1,313 @@
+package com.chwl.app.community.square;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+import androidx.viewpager.widget.ViewPager;
+
+import com.chwl.app.base.BaseFragment;
+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;
+
+ 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());
+ 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 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() {
+ @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);
+ }
+
+ private void loadData(boolean isRefresh) {
+ if (isRefresh) {
+ nextDynamicId = null;
+ page = 1;
+ } else {
+ page++;
+ }
+
+ Single 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() {
+ @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 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() {
+ @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() {
+
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/square/SquareFragment.java b/app/src/module_community/java/com/chwl/app/community/square/SquareFragment.java
new file mode 100644
index 000000000..bcbfbb484
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/square/SquareFragment.java
@@ -0,0 +1,193 @@
+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.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 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 = 0;
+ /**
+ * 推荐
+ */
+ public static final int TAB_TYPE_RECOMMEND = 1;
+ /**
+ * 最新
+ */
+ public static final int TAB_TYPE_NEW = 2;
+
+ private MagicIndicator magicIndicator;
+ private ViewPager2 viewPager;
+ private DragLayout ivSquarePublish;
+ private FrameLayout flContactList;
+ private View tvCommunityUnread;
+
+ 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() {
+ List fragmentPos = new ArrayList<>();
+ fragmentPos.add(TAB_TYPE_ATTENT);
+ fragmentPos.add(TAB_TYPE_RECOMMEND);
+ fragmentPos.add(TAB_TYPE_NEW);
+ List tagList = new ArrayList<>();
+ List 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));
+ }
+ fragmentList.add(SquareDynamicFragment.newInstance(integer));
+ }
+
+ getUnReadCount();
+
+ //init viewpager
+
+ viewPager.setAdapter(new CommonVPAdapter(getChildFragmentManager(), getLifecycle(), fragmentList));
+ viewPager.setOffscreenPageLimit(3);
+ viewPager.setUserInputEnabled(false);
+
+ CommonNavigator commonNavigator = new CommonNavigator(getContext());
+ ContactsIndicatorAdapter magicIndicatorAdapter = new ContactsIndicatorAdapter(getContext(), tagList);
+ magicIndicatorAdapter.setOnItemSelectListener(this);
+ commonNavigator.setTitleWrapContent(true);
+ commonNavigator.setAdapter(magicIndicatorAdapter);
+ magicIndicator.setNavigator(commonNavigator);
+ commonNavigator.getTitleContainer().setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
+ //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);
+ }
+
+}
+
diff --git a/app/src/module_community/java/com/chwl/app/community/square/adapter/SquareDynamicAdapter.java b/app/src/module_community/java/com/chwl/app/community/square/adapter/SquareDynamicAdapter.java
new file mode 100644
index 000000000..64812c625
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/square/adapter/SquareDynamicAdapter.java
@@ -0,0 +1,250 @@
+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.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.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 {
+
+ private SparseBooleanArray mCollapsedStatus = new SparseBooleanArray();
+ private SparseIntArray mCollapsedHeightStatus = new SparseIntArray(2);
+
+ private Context context;
+
+ 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) {
+ super(R.layout.item_square_dynamic);
+ this.context = context;
+ 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 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);
+
+ //头饰 贵族头饰
+ ImageView ivHeadWear = helper.getView(R.id.iv_head_wear);
+ GlideApp.with(ivHeadWear.getContext()).clear(ivHeadWear);
+ String headwearEffect = item.getHeadwearEffect();
+ String headwearPic = item.getHeadwearPic();
+ 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)) {
+ NobleUtil.loadHeadWear(headwearEffect, ivHeadWear);
+ } else if (!TextUtils.isEmpty(headwearPic)) {
+ NobleUtil.loadHeadWear(headwearPic, ivHeadWear);
+ } else if (!TextUtils.isEmpty(micDecorate)) {
+ NobleUtil.loadResource(micDecorate, ivHeadWear);
+ } else {
+ ivHeadWear.setImageDrawable(null);
+ }
+
+ //头像
+ ImageLoadUtilsV2.loadImage(helper.getView(R.id.iv_avatar), item.getAvatar());
+
+ 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 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() {
+ @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);
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/user_dynamic/IUserDynamicView.java b/app/src/module_community/java/com/chwl/app/community/user_dynamic/IUserDynamicView.java
new file mode 100644
index 000000000..e03531daf
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/user_dynamic/IUserDynamicView.java
@@ -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 list);
+ void refreshFail(String error);
+
+ void loadSuccess(List list);
+ void loadFail(String error);
+
+ void deleteSuccess(long successId);
+ void deleteFail(String error);
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicAdapter.java b/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicAdapter.java
new file mode 100644
index 000000000..cd7f92bbe
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicAdapter.java
@@ -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 {
+ 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 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() {
+ @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 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);
+ }
+
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicFrg.java b/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicFrg.java
new file mode 100644
index 000000000..2f956da02
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicFrg.java
@@ -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 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 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 list) {
+ swipeRefreshLayout.setRefreshing(false);
+ if (mUserDynamicAdapter != null) {
+// mUserDynamicAdapter.resetStatus();
+ List tempList = getMvpPresenter().modifyData(list, true);
+ mUserDynamicAdapter.setNewData(tempList);
+ mUserDynamicAdapter.loadMoreComplete();
+ }
+
+ }
+
+ @Override
+ public void refreshFail(String error) {
+ swipeRefreshLayout.setRefreshing(false);
+ List 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 list) {
+ mUserDynamicAdapter.loadMoreComplete();
+ if (mUserDynamicAdapter != null) {
+ List 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 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 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 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());
+ }
+ }
+ });
+
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicPresenter.java b/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicPresenter.java
new file mode 100644
index 000000000..fbb50c264
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/user_dynamic/UserDynamicPresenter.java
@@ -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 {
+
+ 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, Throwable>() {
+ @Override
+ public void accept(List 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, Throwable>() {
+ @Override
+ public void accept(List 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 modifyData(List list, boolean isFirst) {
+ List 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() {
+ @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;
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/utils/ObjectTypeHelper.java b/app/src/module_community/java/com/chwl/app/community/utils/ObjectTypeHelper.java
new file mode 100644
index 000000000..933affb12
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/utils/ObjectTypeHelper.java
@@ -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 customToStringList(List paramsList) {
+ List resultList = new ArrayList<>();
+ if (paramsList == null) {
+ return resultList;
+ }
+ for (CustomItem item : paramsList) {
+ resultList.add(item.getPath());
+ }
+ return resultList;
+ }
+
+ public static List customToMediaList(List paramsList) {
+ List 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 stringToCustomList(List paramsList) {
+ List resultList = new ArrayList<>();
+ if (paramsList == null) {
+ return resultList;
+ }
+ for (String item : paramsList) {
+ resultList.add(new CustomItem(item, 0));
+ }
+ return resultList;
+ }
+
+ public static ArrayList mediaToCustomList(List paramsList) {
+ ArrayList 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 pathToCustomItems(String path) {
+ ArrayList resultList = new ArrayList<>();
+ CustomItem item = new CustomItem();
+ item.setPath(path);
+ item.setFileType(CustomItem.UNKOWN);
+ resultList.add(item);
+ return resultList;
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/utils/TopicUpTextWrapper.kt b/app/src/module_community/java/com/chwl/app/community/utils/TopicUpTextWrapper.kt
new file mode 100644
index 000000000..2e92fffb2
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/utils/TopicUpTextWrapper.kt
@@ -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
+ }
+}
\ No newline at end of file
diff --git a/app/src/module_community/java/com/chwl/app/community/widget/DynamicNickDetailWidget.java b/app/src/module_community/java/com/chwl/app/community/widget/DynamicNickDetailWidget.java
new file mode 100644
index 000000000..e722a66d4
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/widget/DynamicNickDetailWidget.java
@@ -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));
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/widget/ExpandableTextView.java b/app/src/module_community/java/com/chwl/app/community/widget/ExpandableTextView.java
new file mode 100644
index 000000000..b47bff879
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/widget/ExpandableTextView.java
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/module_community/java/com/chwl/app/community/widget/GridImageWidget.java b/app/src/module_community/java/com/chwl/app/community/widget/GridImageWidget.java
new file mode 100644
index 000000000..9a9cb20fe
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/widget/GridImageWidget.java
@@ -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 dynamicMediaList = item.getDynamicResList();
+ if (item.getType() == WorldDynamicBean.TYPE_IMAGE
+ && dynamicMediaList != null && dynamicMediaList.size() > 0) {
+ setData(dynamicMediaList, topMargin);
+ }
+ }
+
+ public void setData(List 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);
+
+ }
+
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/widget/TopicLabelWidget.kt b/app/src/module_community/java/com/chwl/app/community/widget/TopicLabelWidget.kt
new file mode 100644
index 000000000..868fcc4eb
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/widget/TopicLabelWidget.kt
@@ -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) {
+ 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)
+ }
+}
\ No newline at end of file
diff --git a/app/src/module_community/java/com/chwl/app/community/widget/TouchHideKeyboardView.java b/app/src/module_community/java/com/chwl/app/community/widget/TouchHideKeyboardView.java
new file mode 100644
index 000000000..ce1a93411
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/widget/TouchHideKeyboardView.java
@@ -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);
+ }
+}
diff --git a/app/src/module_community/java/com/chwl/app/community/widget/ZoomImageView.java b/app/src/module_community/java/com/chwl/app/community/widget/ZoomImageView.java
new file mode 100644
index 000000000..40cbf8bca
--- /dev/null
+++ b/app/src/module_community/java/com/chwl/app/community/widget/ZoomImageView.java
@@ -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;
+ }
+}
diff --git a/app/src/module_community/res/drawable-xhdpi/bg_dy_popup_comment.png b/app/src/module_community/res/drawable-xhdpi/bg_dy_popup_comment.png
new file mode 100644
index 000000000..96f394a08
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/bg_dy_popup_comment.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/bg_dy_popup_comment_three.png b/app/src/module_community/res/drawable-xhdpi/bg_dy_popup_comment_three.png
new file mode 100644
index 000000000..b517938d9
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/bg_dy_popup_comment_three.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_back_dynamic.webp b/app/src/module_community/res/drawable-xhdpi/ic_back_dynamic.webp
new file mode 100644
index 000000000..4b92b8b35
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_back_dynamic.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_box_dynamic.png b/app/src/module_community/res/drawable-xhdpi/ic_box_dynamic.png
new file mode 100644
index 000000000..de1c33bad
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_box_dynamic.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_close_publish.png b/app/src/module_community/res/drawable-xhdpi/ic_close_publish.png
new file mode 100644
index 000000000..3b7da1944
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_close_publish.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_communicate_community_list.png b/app/src/module_community/res/drawable-xhdpi/ic_communicate_community_list.png
new file mode 100644
index 000000000..21cf88050
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_communicate_community_list.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_dy_square_in_room.webp b/app/src/module_community/res/drawable-xhdpi/ic_dy_square_in_room.webp
new file mode 100644
index 000000000..80482d0c1
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_dy_square_in_room.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_female_age_community_notice.png b/app/src/module_community/res/drawable-xhdpi/ic_female_age_community_notice.png
new file mode 100644
index 000000000..f6bb44d5b
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_female_age_community_notice.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_img_dynamic.png b/app/src/module_community/res/drawable-xhdpi/ic_img_dynamic.png
new file mode 100644
index 000000000..5a1ad4096
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_img_dynamic.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_like_community_list.png b/app/src/module_community/res/drawable-xhdpi/ic_like_community_list.png
new file mode 100644
index 000000000..70e759ca0
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_like_community_list.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_male_community_notice.png b/app/src/module_community/res/drawable-xhdpi/ic_male_community_notice.png
new file mode 100644
index 000000000..8656a04cf
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_male_community_notice.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_more_community_list.png b/app/src/module_community/res/drawable-xhdpi/ic_more_community_list.png
new file mode 100644
index 000000000..0fdfd0093
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_more_community_list.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_name_community_notice_list.png b/app/src/module_community/res/drawable-xhdpi/ic_name_community_notice_list.png
new file mode 100644
index 000000000..83d70842c
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_name_community_notice_list.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_share_community_list.png b/app/src/module_community/res/drawable-xhdpi/ic_share_community_list.png
new file mode 100644
index 000000000..b61233a31
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_share_community_list.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_square_live.png b/app/src/module_community/res/drawable-xhdpi/ic_square_live.png
new file mode 100644
index 000000000..6cc68589b
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_square_live.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_square_publish.webp b/app/src/module_community/res/drawable-xhdpi/ic_square_publish.webp
new file mode 100644
index 000000000..37f190964
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_square_publish.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_text_dynamic.png b/app/src/module_community/res/drawable-xhdpi/ic_text_dynamic.png
new file mode 100644
index 000000000..6389e0335
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_text_dynamic.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_topic_close.png b/app/src/module_community/res/drawable-xhdpi/ic_topic_close.png
new file mode 100644
index 000000000..825e49056
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_topic_close.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_translate_dynamic.png b/app/src/module_community/res/drawable-xhdpi/ic_translate_dynamic.png
new file mode 100644
index 000000000..3ba63302a
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_translate_dynamic.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_translate_selected_dynamic.webp b/app/src/module_community/res/drawable-xhdpi/ic_translate_selected_dynamic.webp
new file mode 100644
index 000000000..24b168315
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_translate_selected_dynamic.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_video_dynamic.png b/app/src/module_community/res/drawable-xhdpi/ic_video_dynamic.png
new file mode 100644
index 000000000..a5bc7306b
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_video_dynamic.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/ic_voice_dynamic.png b/app/src/module_community/res/drawable-xhdpi/ic_voice_dynamic.png
new file mode 100644
index 000000000..bca20e20a
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/ic_voice_dynamic.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_detail_comment.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_detail_comment.png
new file mode 100644
index 000000000..bd09941b1
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_detail_comment.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_detail_share.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_detail_share.png
new file mode 100644
index 000000000..5c15b6b55
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_detail_share.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_dynamic_publisher.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_dynamic_publisher.png
new file mode 100644
index 000000000..49491e058
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_dynamic_publisher.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_emoji.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_emoji.png
new file mode 100644
index 000000000..ff5c90c1f
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_emoji.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_first_dynamic.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_first_dynamic.png
new file mode 100644
index 000000000..48c50bdb2
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_first_dynamic.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_item_more.webp b/app/src/module_community/res/drawable-xhdpi/icon_dy_item_more.webp
new file mode 100644
index 000000000..cc950ad3f
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_item_more.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_comment.webp b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_comment.webp
new file mode 100644
index 000000000..0f74d2b7d
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_comment.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_female.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_female.png
new file mode 100644
index 000000000..235275bb4
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_female.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like.webp b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like.webp
new file mode 100644
index 000000000..3e9df0182
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00000.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00000.png
new file mode 100644
index 000000000..2c7a0559c
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00000.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00001.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00001.png
new file mode 100644
index 000000000..a9c96ee38
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00001.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00002.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00002.png
new file mode 100644
index 000000000..c6014dc7d
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00002.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00003.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00003.png
new file mode 100644
index 000000000..95cc50924
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00003.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00004.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00004.png
new file mode 100644
index 000000000..935b88743
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00004.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00005.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00005.png
new file mode 100644
index 000000000..faae9e673
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00005.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00006.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00006.png
new file mode 100644
index 000000000..6e28f3062
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00006.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00007.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00007.png
new file mode 100644
index 000000000..a4956ba94
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00007.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00008.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00008.png
new file mode 100644
index 000000000..3fd37d60c
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00008.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00009.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00009.png
new file mode 100644
index 000000000..37389ff93
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00009.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00010.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00010.png
new file mode 100644
index 000000000..00d484521
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00010.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00011.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00011.png
new file mode 100644
index 000000000..47ea42305
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00011.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00012.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00012.png
new file mode 100644
index 000000000..b7686370f
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00012.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00013.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00013.png
new file mode 100644
index 000000000..2c7a0559c
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_00013.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_false.webp b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_false.webp
new file mode 100644
index 000000000..5f6802834
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_false.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_true.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_true.png
new file mode 100644
index 000000000..5881cc041
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_like_true.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_male.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_male.png
new file mode 100644
index 000000000..82e6dd8b6
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_male.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_list_share.webp b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_share.webp
new file mode 100644
index 000000000..6fbf2d0c3
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_list_share.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_miniworld.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_miniworld.png
new file mode 100644
index 000000000..41316ad8e
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_miniworld.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_copy.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_copy.png
new file mode 100644
index 000000000..d0321a5e7
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_copy.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_delete.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_delete.png
new file mode 100644
index 000000000..e74532c11
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_delete.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_report.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_report.png
new file mode 100644
index 000000000..4ad26c307
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_popup_report.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_examine.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_examine.png
new file mode 100644
index 000000000..243d470a0
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_examine.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_false.png b/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_false.png
new file mode 100644
index 000000000..356fec169
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_false.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_true.webp b/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_true.webp
new file mode 100644
index 000000000..f5e1edd5c
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_dy_publish_true.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_comment.webp b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_comment.webp
new file mode 100644
index 000000000..84cb5597d
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_comment.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_like_checked.webp b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_like_checked.webp
new file mode 100644
index 000000000..32be4b625
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_like_checked.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_like_normal.webp b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_like_normal.webp
new file mode 100644
index 000000000..ddf8316d5
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_like_normal.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_more.png b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_more.png
new file mode 100644
index 000000000..0f65acbd5
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_more.png differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_share.webp b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_share.webp
new file mode 100644
index 000000000..e75cf61ee
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_square_dynamic_share.webp differ
diff --git a/app/src/module_community/res/drawable-xhdpi/icon_top.png b/app/src/module_community/res/drawable-xhdpi/icon_top.png
new file mode 100644
index 000000000..46d1f4eb7
Binary files /dev/null and b/app/src/module_community/res/drawable-xhdpi/icon_top.png differ
diff --git a/app/src/module_community/res/drawable/anim_list_dy_like.xml b/app/src/module_community/res/drawable/anim_list_dy_like.xml
new file mode 100644
index 000000000..de7ec3e39
--- /dev/null
+++ b/app/src/module_community/res/drawable/anim_list_dy_like.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/bg_round_1affbc51_9_4.xml b/app/src/module_community/res/drawable/bg_round_1affbc51_9_4.xml
new file mode 100644
index 000000000..da38d7295
--- /dev/null
+++ b/app/src/module_community/res/drawable/bg_round_1affbc51_9_4.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/btn_translate_dynamic_selector.xml b/app/src/module_community/res/drawable/btn_translate_dynamic_selector.xml
new file mode 100644
index 000000000..d7ccf828a
--- /dev/null
+++ b/app/src/module_community/res/drawable/btn_translate_dynamic_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/divider_flexlayout.xml b/app/src/module_community/res/drawable/divider_flexlayout.xml
new file mode 100644
index 000000000..ef1416188
--- /dev/null
+++ b/app/src/module_community/res/drawable/divider_flexlayout.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/selector_dy_publish_btn_status.xml b/app/src/module_community/res/drawable/selector_dy_publish_btn_status.xml
new file mode 100644
index 000000000..6dee3582d
--- /dev/null
+++ b/app/src/module_community/res/drawable/selector_dy_publish_btn_status.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/shape_bg_mini_world_added.xml b/app/src/module_community/res/drawable/shape_bg_mini_world_added.xml
new file mode 100644
index 000000000..58591efa7
--- /dev/null
+++ b/app/src/module_community/res/drawable/shape_bg_mini_world_added.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/shape_bg_mini_world_name.xml b/app/src/module_community/res/drawable/shape_bg_mini_world_name.xml
new file mode 100644
index 000000000..dc4afa03e
--- /dev/null
+++ b/app/src/module_community/res/drawable/shape_bg_mini_world_name.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/shape_bg_square_list.xml b/app/src/module_community/res/drawable/shape_bg_square_list.xml
new file mode 100644
index 000000000..5671ff429
--- /dev/null
+++ b/app/src/module_community/res/drawable/shape_bg_square_list.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/shape_round.xml b/app/src/module_community/res/drawable/shape_round.xml
new file mode 100644
index 000000000..44a080885
--- /dev/null
+++ b/app/src/module_community/res/drawable/shape_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/drawable/topic_up_drawable.xml b/app/src/module_community/res/drawable/topic_up_drawable.xml
new file mode 100644
index 000000000..25905721e
--- /dev/null
+++ b/app/src/module_community/res/drawable/topic_up_drawable.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/activity_dynamic_detail.xml b/app/src/module_community/res/layout/activity_dynamic_detail.xml
new file mode 100644
index 000000000..9d4281a91
--- /dev/null
+++ b/app/src/module_community/res/layout/activity_dynamic_detail.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/activity_publish.xml b/app/src/module_community/res/layout/activity_publish.xml
new file mode 100644
index 000000000..50b03ada0
--- /dev/null
+++ b/app/src/module_community/res/layout/activity_publish.xml
@@ -0,0 +1,207 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/dialog_dy_publish_success.xml b/app/src/module_community/res/layout/dialog_dy_publish_success.xml
new file mode 100644
index 000000000..6d1bbdd70
--- /dev/null
+++ b/app/src/module_community/res/layout/dialog_dy_publish_success.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/dy_empty_dynamic_comment.xml b/app/src/module_community/res/layout/dy_empty_dynamic_comment.xml
new file mode 100644
index 000000000..0e15efa1d
--- /dev/null
+++ b/app/src/module_community/res/layout/dy_empty_dynamic_comment.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/dy_footer_loadmore.xml b/app/src/module_community/res/layout/dy_footer_loadmore.xml
new file mode 100644
index 000000000..bc98eebb0
--- /dev/null
+++ b/app/src/module_community/res/layout/dy_footer_loadmore.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/fragment_square.xml b/app/src/module_community/res/layout/fragment_square.xml
new file mode 100644
index 000000000..4ecd096be
--- /dev/null
+++ b/app/src/module_community/res/layout/fragment_square.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/fragment_square_dynamic.xml b/app/src/module_community/res/layout/fragment_square_dynamic.xml
new file mode 100644
index 000000000..ed55cf0a9
--- /dev/null
+++ b/app/src/module_community/res/layout/fragment_square_dynamic.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/frg_user_dynamic.xml b/app/src/module_community/res/layout/frg_user_dynamic.xml
new file mode 100644
index 000000000..62c4e38ee
--- /dev/null
+++ b/app/src/module_community/res/layout/frg_user_dynamic.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/frg_worlds_choose.xml b/app/src/module_community/res/layout/frg_worlds_choose.xml
new file mode 100644
index 000000000..2b42dc392
--- /dev/null
+++ b/app/src/module_community/res/layout/frg_worlds_choose.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/head_dynamic_detail.xml b/app/src/module_community/res/layout/head_dynamic_detail.xml
new file mode 100644
index 000000000..cb3b94e71
--- /dev/null
+++ b/app/src/module_community/res/layout/head_dynamic_detail.xml
@@ -0,0 +1,305 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_dy_comment.xml b/app/src/module_community/res/layout/item_dy_comment.xml
new file mode 100644
index 000000000..b72093265
--- /dev/null
+++ b/app/src/module_community/res/layout/item_dy_comment.xml
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_dy_reply.xml b/app/src/module_community/res/layout/item_dy_reply.xml
new file mode 100644
index 000000000..7ea890f7e
--- /dev/null
+++ b/app/src/module_community/res/layout/item_dy_reply.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_dynamic_image.xml b/app/src/module_community/res/layout/item_dynamic_image.xml
new file mode 100644
index 000000000..2fb7e88d8
--- /dev/null
+++ b/app/src/module_community/res/layout/item_dynamic_image.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_dynamic_sys.xml b/app/src/module_community/res/layout/item_dynamic_sys.xml
new file mode 100644
index 000000000..b6b7d91ab
--- /dev/null
+++ b/app/src/module_community/res/layout/item_dynamic_sys.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_grid_image_widget.xml b/app/src/module_community/res/layout/item_grid_image_widget.xml
new file mode 100644
index 000000000..01ded47fb
--- /dev/null
+++ b/app/src/module_community/res/layout/item_grid_image_widget.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_label_mini_world.xml b/app/src/module_community/res/layout/item_label_mini_world.xml
new file mode 100644
index 000000000..170b8f33f
--- /dev/null
+++ b/app/src/module_community/res/layout/item_label_mini_world.xml
@@ -0,0 +1,16 @@
+
+
+
diff --git a/app/src/main/res/layout/item_publish_image.xml b/app/src/module_community/res/layout/item_publish_image.xml
similarity index 100%
rename from app/src/main/res/layout/item_publish_image.xml
rename to app/src/module_community/res/layout/item_publish_image.xml
diff --git a/app/src/module_community/res/layout/item_reply_footer_view.xml b/app/src/module_community/res/layout/item_reply_footer_view.xml
new file mode 100644
index 000000000..c5586316a
--- /dev/null
+++ b/app/src/module_community/res/layout/item_reply_footer_view.xml
@@ -0,0 +1,10 @@
+
+
diff --git a/app/src/module_community/res/layout/item_square_dynamic.xml b/app/src/module_community/res/layout/item_square_dynamic.xml
new file mode 100644
index 000000000..8b520eeb0
--- /dev/null
+++ b/app/src/module_community/res/layout/item_square_dynamic.xml
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_user_dynamic_image.xml b/app/src/module_community/res/layout/item_user_dynamic_image.xml
new file mode 100644
index 000000000..00b96779b
--- /dev/null
+++ b/app/src/module_community/res/layout/item_user_dynamic_image.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/module_community/res/layout/item_user_dynamic_list.xml b/app/src/module_community/res/layout/item_user_dynamic_list.xml
new file mode 100644
index 000000000..4f5b40292
--- /dev/null
+++ b/app/src/module_community/res/layout/item_user_dynamic_list.xml
@@ -0,0 +1,269 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_world_dynamic.xml b/app/src/module_community/res/layout/item_world_dynamic.xml
new file mode 100644
index 000000000..a15145ce9
--- /dev/null
+++ b/app/src/module_community/res/layout/item_world_dynamic.xml
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/item_worlds_choose.xml b/app/src/module_community/res/layout/item_worlds_choose.xml
new file mode 100644
index 000000000..a3e73742b
--- /dev/null
+++ b/app/src/module_community/res/layout/item_worlds_choose.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/layout_dy_nick_detail.xml b/app/src/module_community/res/layout/layout_dy_nick_detail.xml
new file mode 100644
index 000000000..2e711be81
--- /dev/null
+++ b/app/src/module_community/res/layout/layout_dy_nick_detail.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/popup_dy_comment.xml b/app/src/module_community/res/layout/popup_dy_comment.xml
new file mode 100644
index 000000000..633e06c99
--- /dev/null
+++ b/app/src/module_community/res/layout/popup_dy_comment.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/view_holder_world_dynamic_share.xml b/app/src/module_community/res/layout/view_holder_world_dynamic_share.xml
new file mode 100644
index 000000000..767baafe6
--- /dev/null
+++ b/app/src/module_community/res/layout/view_holder_world_dynamic_share.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/layout/widget_grid_image.xml b/app/src/module_community/res/layout/widget_grid_image.xml
new file mode 100644
index 000000000..eb49035d7
--- /dev/null
+++ b/app/src/module_community/res/layout/widget_grid_image.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/values-ar/strings.xml b/app/src/module_community/res/values-ar/strings.xml
new file mode 100644
index 000000000..6b16ca61f
--- /dev/null
+++ b/app/src/module_community/res/values-ar/strings.xml
@@ -0,0 +1,20 @@
+
+
+ نشر الرسومات والنصوص
+ نشر
+ سجل حياتك في الوقت الحالي وشاركها مع الأشخاص المثيرين للاهتمام
+ نشر التعليقات
+ تكبير
+ غلق
+ يُمنع الإعلانات التجارية وأرقام الهواتف والألفاظ البذيئة والإباحية والمخيفة والعنيفة والمهينة، وسيتم حظر حساباتهم!
+ %s رد
+ تعال واحصل على مقعدك
+ قم بتكبير %sالردود
+ تعليق
+ ترشيح
+ متابعة
+ الأحدث
+ الساحة
+ اذهب والقى نظرة
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/values-zh-rTW/strings.xml b/app/src/module_community/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000..e639d258c
--- /dev/null
+++ b/app/src/module_community/res/values-zh-rTW/strings.xml
@@ -0,0 +1,19 @@
+
+
+ 圖文發佈
+ 發布
+ 記錄你此刻生活,分享給有趣的人看...
+ 發表評論
+ 展開
+ 收起
+ 禁止出現商業廣告、電話號碼, 以及低俗、色情、恐怖、暴力和具有侮辱性語言等內容,違規者封號處理 !
+ 回復 %s
+ 快來搶占沙發吧~
+ 展開%s條回復
+ 評論
+ 推薦
+ 關註
+ 最新
+ 廣場
+ 去看看
+
\ No newline at end of file
diff --git a/app/src/module_community/res/values/attrs.xml b/app/src/module_community/res/values/attrs.xml
new file mode 100644
index 000000000..cc7f0fd93
--- /dev/null
+++ b/app/src/module_community/res/values/attrs.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/values/dimens.xml b/app/src/module_community/res/values/dimens.xml
new file mode 100644
index 000000000..56a345bd6
--- /dev/null
+++ b/app/src/module_community/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+
+ 51.5dp
+ 70dp
+ 2.5dp
+ 7dp
+
+
\ No newline at end of file
diff --git a/app/src/module_community/res/values/strings.xml b/app/src/module_community/res/values/strings.xml
new file mode 100644
index 000000000..49393faf2
--- /dev/null
+++ b/app/src/module_community/res/values/strings.xml
@@ -0,0 +1,19 @@
+
+
+ Post graphics and text
+ Post
+ Record your life at this moment and share it with interesting people...
+ Comment
+ Expand
+ Close
+ Commercial advertisements, phone numbers, and content that is vulgar, pornographic, terrifying, violent, and insulting are prohibited. Violators will be blocked!
+ Reply %s
+ Come and have your seat
+ Expand %s replies
+ Comment
+ Recommend
+ Follow
+ Newest
+ Square
+ Go to see
+
\ No newline at end of file
diff --git a/core/src/main/java/com/chwl/core/XConstants.java b/core/src/main/java/com/chwl/core/XConstants.java
index 27fbcc9d6..577f8ae3b 100644
--- a/core/src/main/java/com/chwl/core/XConstants.java
+++ b/core/src/main/java/com/chwl/core/XConstants.java
@@ -61,7 +61,10 @@ public class XConstants {
public static final String REPORT_TYPE_ROOM = "room"; // 房間
public static final String REPORT_TYPE_VOICE = "voice"; // 聲音瓶子
public static final String REPORT_TYPE_USERCARD = "USERCARD"; // 資料卡片
-
+ public static final String REPORT_TYPE_WORLDDYNAMIC = "WORLDDYNAMIC"; // 世界動態
+ public static final String REPORT_TYPE_DYNAMICCOMMENT = "DYNAMICCOMMENT"; // 世界動態
+ public static final String REPORT_TYPE_PERSONAL_DYNAMIC = "PERSONAL_DYNAMIC"; // 個人頁動態
+ public static final String REPORT_TYPE_DYNAMIC_SQUARE = "DYNAMIC_SQUARE";//廣場動態
/**
* Referer (DEBUG)
*/
diff --git a/core/src/main/java/com/chwl/core/home/bean/MainTabType.java b/core/src/main/java/com/chwl/core/home/bean/MainTabType.java
index bb13e4ff5..6bd2a4a01 100644
--- a/core/src/main/java/com/chwl/core/home/bean/MainTabType.java
+++ b/core/src/main/java/com/chwl/core/home/bean/MainTabType.java
@@ -1,10 +1,11 @@
package com.chwl.core.home.bean;
public interface MainTabType {
- //tabType(1-派对,2-广场,3-赛事,4-消息,5-我的)
- int TAB_TYPE_STAR = 1;
- int TAB_TYPE_HOME = 2;
- int TAB_TYPE_MSG = 3;
- int TAB_TYPE_ME = 4;
- int TAB_TYPE_GAME = 5;
+ // int TAB_TYPE_STAR = 1;
+ int TAB_TYPE_HOME = 1;
+ int TAB_TYPE_GAME = 2;
+ int TAB_TYPE_SQUARE = 3;
+ int TAB_TYPE_MSG = 4;
+ int TAB_TYPE_ME = 5;
+
}
diff --git a/core/src/main/java/com/chwl/core/initial/InitialModel.java b/core/src/main/java/com/chwl/core/initial/InitialModel.java
index 9ab1cb4ab..223a87c15 100644
--- a/core/src/main/java/com/chwl/core/initial/InitialModel.java
+++ b/core/src/main/java/com/chwl/core/initial/InitialModel.java
@@ -395,8 +395,8 @@ public class InitialModel extends BaseModel implements IInitialModel {
new MainTabInfo(
"",
"",
- "Star",
- MainTabType.TAB_TYPE_STAR,
+ ResUtil.getString(R.string.xchat_android_core_initial_initialmodel_03),
+ MainTabType.TAB_TYPE_HOME,
null
),
new MainTabInfo(
@@ -409,8 +409,8 @@ public class InitialModel extends BaseModel implements IInitialModel {
new MainTabInfo(
"",
"",
- ResUtil.getString(R.string.xchat_android_core_initial_initialmodel_03),
- MainTabType.TAB_TYPE_HOME,
+ "Square",
+ MainTabType.TAB_TYPE_SQUARE,
null
),
new MainTabInfo(
diff --git a/core/src/main/java/com/chwl/core/user/bean/BaseUserInfo.java b/core/src/main/java/com/chwl/core/user/bean/BaseUserInfo.java
index fc27c375f..84fba2176 100644
--- a/core/src/main/java/com/chwl/core/user/bean/BaseUserInfo.java
+++ b/core/src/main/java/com/chwl/core/user/bean/BaseUserInfo.java
@@ -47,6 +47,7 @@ public class BaseUserInfo implements Serializable {
// 铭牌文字
private String nameplateWord;
+ private boolean isCustomWord;
// 在哪个房间id
private Long inRoomUid;
diff --git a/core/src/model_community/java/com/chwl/core/community/attachment/DynamicSysAttachment.java b/core/src/model_community/java/com/chwl/core/community/attachment/DynamicSysAttachment.java
index 1aa98c68b..81f39b5e0 100644
--- a/core/src/model_community/java/com/chwl/core/community/attachment/DynamicSysAttachment.java
+++ b/core/src/model_community/java/com/chwl/core/community/attachment/DynamicSysAttachment.java
@@ -1,10 +1,13 @@
package com.chwl.core.community.attachment;
+import androidx.annotation.Keep;
+
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.chwl.core.im.custom.bean.CustomAttachment;
import com.chwl.core.msg.sys.bean.ErbanSysMsgInfo;
+@Keep
public class DynamicSysAttachment extends CustomAttachment {
private ErbanSysMsgInfo erbanSysMsgInfo;
diff --git a/core/src/model_community/java/com/chwl/core/community/attachment/UnReadCountAttachment.java b/core/src/model_community/java/com/chwl/core/community/attachment/UnReadCountAttachment.java
index 3bc008efa..6feead31e 100644
--- a/core/src/model_community/java/com/chwl/core/community/attachment/UnReadCountAttachment.java
+++ b/core/src/model_community/java/com/chwl/core/community/attachment/UnReadCountAttachment.java
@@ -1,8 +1,11 @@
package com.chwl.core.community.attachment;
+import androidx.annotation.Keep;
+
import com.alibaba.fastjson.JSONObject;
import com.chwl.core.im.custom.bean.CustomAttachment;
+@Keep
public class UnReadCountAttachment extends CustomAttachment {
private int total;
diff --git a/core/src/model_community/java/com/chwl/core/community/im/DynamicImMsg.java b/core/src/model_community/java/com/chwl/core/community/im/DynamicImMsg.java
index ffbc83872..6d211c0d6 100644
--- a/core/src/model_community/java/com/chwl/core/community/im/DynamicImMsg.java
+++ b/core/src/model_community/java/com/chwl/core/community/im/DynamicImMsg.java
@@ -1,5 +1,7 @@
package com.chwl.core.community.im;
+import androidx.annotation.Keep;
+
import com.chwl.core.community.bean.WorldDynamicBean;
import java.io.Serializable;
@@ -10,6 +12,7 @@ import lombok.Data;
* create by lvzebiao @2019/11/22
*/
@Data
+@Keep
public class DynamicImMsg implements Serializable {
private long dynamicId;
diff --git a/core/src/model_community/java/com/chwl/core/community/im/WorldDynamicAttachment.java b/core/src/model_community/java/com/chwl/core/community/im/WorldDynamicAttachment.java
index 46b885e58..adf6fe958 100644
--- a/core/src/model_community/java/com/chwl/core/community/im/WorldDynamicAttachment.java
+++ b/core/src/model_community/java/com/chwl/core/community/im/WorldDynamicAttachment.java
@@ -1,5 +1,7 @@
package com.chwl.core.community.im;
+import androidx.annotation.Keep;
+
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netease.nimlib.sdk.msg.MessageBuilder;
@@ -13,6 +15,7 @@ import lombok.Setter;
/**
* create by lvzebiao @2019/11/22
*/
+@Keep
public class WorldDynamicAttachment extends CustomAttachment {
@Setter
diff --git a/library/src/main/java/com/chwl/library/utils/TimeUtils.java b/library/src/main/java/com/chwl/library/utils/TimeUtils.java
index a973e4c7b..cf81d12f3 100644
--- a/library/src/main/java/com/chwl/library/utils/TimeUtils.java
+++ b/library/src/main/java/com/chwl/library/utils/TimeUtils.java
@@ -196,6 +196,7 @@ public class TimeUtils {
return null;
}
final Calendar cal = Calendar.getInstance();
+ cal.setTimeZone(TimeZone.getTimeZone("GMT+8"));
cal.setTimeInMillis(timeMillis);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
@@ -205,7 +206,7 @@ public class TimeUtils {
int sec = cal.get(Calendar.SECOND);
String timeString = null;
try {
- timeString = String.format(format, year, month, day, hour, min, sec);
+ timeString = String.format(Locale.ENGLISH, format, year, month, day, hour, min, sec);
} catch (IllegalFormatException e) {
MLog.error("TimeUtils", "getTimeStringFromMillis error! " + e.toString());
}
diff --git a/app/src/main/java/com/chwl/app/common/photo/PhotoProvider.kt b/library/src/module_common/java/com/chwl/library/common/photo/PhotoProvider.kt
similarity index 87%
rename from app/src/main/java/com/chwl/app/common/photo/PhotoProvider.kt
rename to library/src/module_common/java/com/chwl/library/common/photo/PhotoProvider.kt
index ce52cea6d..ebb2afa6b 100644
--- a/app/src/main/java/com/chwl/app/common/photo/PhotoProvider.kt
+++ b/library/src/module_common/java/com/chwl/library/common/photo/PhotoProvider.kt
@@ -11,14 +11,20 @@ import com.chwl.library.common.application.BaseApp
import com.chwl.library.common.delegate.SpDelegate
import com.chwl.library.common.file.FileHelper
import com.chwl.library.common.glide.GlideEngine
-import com.chwl.library.common.util.LibLogger
import com.chwl.library.easyphoto.EasyPhotos
import com.chwl.library.easyphoto.models.album.entity.Photo
import com.chwl.library.utils.TimeUtils
import com.chwl.library.utils.TimeUtils.TIME_FORMAT
+import com.example.lib_utils.log.LogUtil
import kotlinx.coroutines.*
import java.io.File
+/**
+ * Created by wushaocheng on 2022/11/15
+ * Desc:图片选择二次封装
+ */
+
+
/**
* Created by wushaocheng on 2022/11/15
* Desc:图片选择二次封装
@@ -58,11 +64,11 @@ object PhotoProvider {
withContext(Dispatchers.IO) { clearCache() }
}
EasyPhotos.createAlbum(activity, false, false, GlideEngine())
- .setCount(maxSelect)//参数说明:最大可选数,默认1
- .setPuzzleMenu(false)
- .onlyVideo()
- .setCleanMenu(false)
- .start(resultCode)
+ .setCount(maxSelect)//参数说明:最大可选数,默认1
+ .setPuzzleMenu(false)
+ .onlyVideo()
+ .setCleanMenu(false)
+ .start(resultCode)
}
}
@@ -85,13 +91,25 @@ object PhotoProvider {
@JvmStatic
@JvmOverloads
- fun photoProvider(activity: FragmentActivity, maxSelect: Int = 1, canChooseGif: Boolean = false, resultCode: Int, isClearCache: Boolean = true) {
+ fun photoProvider(
+ activity: FragmentActivity,
+ maxSelect: Int = 1,
+ canChooseGif: Boolean = false,
+ resultCode: Int,
+ isClearCache: Boolean = true,
+ useWidth: Boolean = false
+ ) {
cancelJop()
mPhotoJob = MainScope().launch {
if (isClearCache && isClearByTime()) {
withContext(Dispatchers.IO) { clearCache() }
}
- EasyPhotos.createAlbum(activity, false, false, GlideEngine())//参数说明:上下文,是否显示相机按钮,是否使用宽高数据(false时宽高数据为0,扫描速度更快),[配置Glide为图片加载引擎](https://github.com/HuanTanSheng/EasyPhotos/wiki/12-%E9%85%8D%E7%BD%AEImageEngine%EF%BC%8C%E6%94%AF%E6%8C%81%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E5%8A%A0%E8%BD%BD%E5%BA%93)
+ EasyPhotos.createAlbum(
+ activity,
+ false,
+ useWidth,
+ GlideEngine()
+ )//参数说明:上下文,是否显示相机按钮,是否使用宽高数据(false时宽高数据为0,扫描速度更快),[配置Glide为图片加载引擎](https://github.com/HuanTanSheng/EasyPhotos/wiki/12-%E9%85%8D%E7%BD%AEImageEngine%EF%BC%8C%E6%94%AF%E6%8C%81%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E5%8A%A0%E8%BD%BD%E5%BA%93)
.setCount(maxSelect)//参数说明:最大可选数,默认1
.setGif(canChooseGif)
.setPuzzleMenu(false)
@@ -158,7 +176,7 @@ object PhotoProvider {
val path = "$foldPath${it.name}"
if (FileHelper.copyFileFromUri(it.uri, path, true)) {
it.path = path
- LibLogger.debug(TAG, "path: ${it.path} , displayName: ${it.name} , newPath: $path ")
+ LogUtil.d(TAG, "path: ${it.path} , displayName: ${it.name} , newPath: $path ")
}
}
}
@@ -172,7 +190,7 @@ object PhotoProvider {
* 清除复制缓存
*/
fun clearCache() {
- LibLogger.debug(
+ LogUtil.d(
TAG, "clearCache => mLastSelectTime: ${TimeUtils.getDateTimeString(
mLastSelectTime, TIME_FORMAT)}")
FileHelper.removeAllFile(getInternalPath() + File.separator)