diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c63abfff70..ee2dc85167 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -579,6 +579,10 @@ android:screenOrientation="portrait" android:theme="@style/TransparentStatusBarAndNavigationBar"/> + + (activity); + this.shareIcon = icon; + this.shareUrl = url; + this.mSummary = shareSummary; + this.mTitle = shareTitle; + this.mShareEntrance = shareEntrance; + ShareUtils.shareEntrance = mShareEntrance; + ShareUtils.resourceId = id; + ShareUtils.shareEntity = new ShareEntity(shareUrl, mTitle, mSummary); + LogUtils.uploadShareEnter(mShareEntrance.getName(), shareUrl, mTitle, mSummary, id); + + View contentView = View.inflate(mActivity.get(), R.layout.popup_share_dialog, null); + contentView.setFocusable(true); + contentView.setFocusableInTouchMode(true); + + View wechatType = contentView.findViewById(R.id.item_wechat); + View wechatMomentsType = contentView.findViewById(R.id.item_wechat_moments); + View qqType = contentView.findViewById(R.id.item_qq); + View qqZoneType = contentView.findViewById(R.id.item_qq_zone); + View weiboType = contentView.findViewById(R.id.item_weibo); + + wechatType.setOnClickListener((v) -> wechatShare()); + wechatMomentsType.setOnClickListener((v) -> wechatMomentsShare()); + qqType.setOnClickListener((v) -> qqShare()); + qqZoneType.setOnClickListener((v) -> qZoneShare()); + weiboType.setOnClickListener((v) -> sinaWeiboShare()); + + popupWindow = new WeakReference<>(new SharePopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT + , LinearLayout.LayoutParams.MATCH_PARENT, true)); +// popupWindow.get().setAnimationStyle(R.style.popwindow_exit_only_anim_style); + //解决PopupWindow无法覆盖状态栏 + popupWindow.get().setClippingEnabled(false); + + int bottomLocation = -DisplayUtils.retrieveNavigationHeight(activity); + if (!DisplayUtils.isNavigationBarShow(activity)) { + bottomLocation = 0; + } + try { + popupWindow.get().showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation); + } catch (Exception e) { + e.printStackTrace(); + } + + contentView.setOnClickListener(v -> safelyDismiss()); + + contentView.setOnKeyListener((v, keyCode, event) -> { + if (keyCode == KeyEvent.KEYCODE_BACK + && event.getRepeatCount() == 0 + && popupWindow.get() != null + && popupWindow.get().isShowing()) { + if (callBack != null) { + callBack.onCancel(); + } + safelyDismiss(); + } + return false; + }); + } + public void showShareWindowsCallback(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, ShareCallBack callBack) { if (activity.isFinishing()) return; this.mActivity = new WeakReference<>(activity); diff --git a/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt b/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt index 05efd5ada1..e05c9c0f8d 100644 --- a/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt @@ -75,6 +75,9 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { @BindView(R.id.background_view) lateinit var mBackgroundView: View + @BindView(R.id.btn_save_pic) + lateinit var mSavePicBtn: View + private var adapter: ViewImageAdapter? = null private var mImagePipeline: ImagePipeline? = null private var mShowBase64Image = false @@ -82,9 +85,11 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { private var mViewedSet: HashSet? = null // 让调用者知道该图片是否被看过了 private var mImageInfoMap: MutableMap? = null private var mBigImageView: BigImageView? = null + private var mFinalUrl = "" private var mInitialPosition = 0 private var mUseEnterAndExitAnimation = false + private var mShowSaveBtn = false private var mLimitWidth = 0 private var mOriginLeft = 0 @@ -121,8 +126,10 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { mUrlList = it.getStringArrayList(KEY_URL_LIST) mInitialPosition = it.getInt(KEY_CURRENT, 0) } + mShowSaveBtn = it.getBoolean(KEY_SHOW_SAVE) mUseEnterAndExitAnimation = it.getBoolean(KEY_USE_ENTER_AND_EXIT_ANIMATION) } + mSavePicBtn.visibleIf(mShowSaveBtn) mIndicatorMask.goneIf(mUrlList?.size == 1) mIndicatorTv.text = String.format("%d/%d", mInitialPosition + 1, mUrlList!!.size) @@ -169,6 +176,15 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { } } + mSavePicBtn.setOnClickListener { + checkStoragePermissionBeforeAction { + mBigImageView?.currentImageFile?.run { + adapter?.saveImageToFile(this, mFinalUrl) + } + } + + } + initEnterAnimation() DisplayUtils.transparentStatusAndNavigation(this) } @@ -187,6 +203,44 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { mViewPager.onDestroy() // 注销EventBus } + private fun saveImageToFile(src: File, curUrl: String?) { + var `in`: InputStream? = null + var out: OutputStream? = null + try { + val fileName: String = if (mShowBase64Image) { + MD5Utils.getUrlMD5(curUrl!!.substring(0, 50)) + ".png" + } else { + curUrl!!.substring(curUrl.lastIndexOf("/")) + } + val savePath = Environment.getExternalStorageDirectory().absolutePath + "/Pictures/ghzhushou/" + val file = File(savePath) + if (!file.exists()) { + file.mkdirs() + } + val dst = File(savePath, fileName) + if (dst.exists()) { + dst.delete() + } + `in` = FileInputStream(src) + out = FileOutputStream(dst) + val buf = ByteArray(1024) + var len: Int + while (`in`.read(buf).also { len = it } > 0) { + out.write(buf, 0, len) + } + Utils.toast(this@ImageViewerActivity, "图片已保存到/Pictures/ghzhushou/") + MessageShareUtils.refreshImage(this@ImageViewerActivity, dst) + } catch (e: Exception) { + Utils.log("图片保存失败:$e") + } finally { + try { + out?.close() + `in`?.close() + } catch (ignore: Exception) { + } + } + } + @SuppressLint("SetTextI18n") override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { @@ -463,6 +517,8 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { decoratedUrl = getTransformLimitUrl(originalUrl, mLimitWidth, applicationContext) } val finalUrl = decoratedUrl + mFinalUrl = finalUrl ?: "" + imageView.setImageLoaderCallback(object : SimpleImageLoader() { override fun onSuccess(image: File) { if (finalUrl != mUrlList!![position]) { @@ -529,7 +585,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { return view } - private fun saveImageToFile(src: File, curUrl: String?) { + fun saveImageToFile(src: File, curUrl: String?) { var `in`: InputStream? = null var out: OutputStream? = null try { @@ -587,6 +643,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { private const val KEY_BASE64 = "base64" private const val KEY_URL_LIST = "urls" private const val KEY_CURRENT = "current" + private const val KEY_SHOW_SAVE = "showSave" private const val KEY_USE_ENTER_AND_EXIT_ANIMATION = "use_enter_and_exit_animation" private const val KEY_LEFT = "left" @@ -605,17 +662,23 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { @JvmStatic fun getIntent(context: Context, list: ArrayList, position: Int = 0, entrance: String?): Intent { - return getIntent(context, list, position, null, entrance) + return getIntent(context, list, position, null, entrance, false) + } + + @JvmStatic + fun getIntent(context: Context, list: ArrayList, position: Int = 0, originalView: View? = null, entrance: String?): Intent { + return getIntent(context, list, position, originalView, entrance, false) } /** * 传入 view 代表使用渐入渐出动画 */ @JvmStatic - fun getIntent(context: Context, list: ArrayList, position: Int = 0, originalView: View? = null, entrance: String?): Intent { + fun getIntent(context: Context, list: ArrayList, position: Int = 0, originalView: View? = null, entrance: String?, isShowSaveBtn: Boolean): Intent { val intent = Intent(context, ImageViewerActivity::class.java) intent.putExtra(KEY_URL_LIST, list) intent.putExtra(KEY_CURRENT, position) + intent.putExtra(KEY_SHOW_SAVE, isShowSaveBtn) intent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance) val location = IntArray(2) diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ExcellentCommentsHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ExcellentCommentsHolder.java new file mode 100644 index 0000000000..1fffa1906a --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ExcellentCommentsHolder.java @@ -0,0 +1,22 @@ +package com.gh.gamecenter.adapter.viewholder; + +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.gh.base.BaseRecyclerViewHolder; +import com.gh.gamecenter.R; + +import butterknife.BindView; + +public class ExcellentCommentsHolder extends BaseRecyclerViewHolder { + + @BindView(R.id.excellentCommentMore) + public View excellentCommentMore; + @BindView(R.id.excellentCommentList) + public RecyclerView excellentCommentList; + + public ExcellentCommentsHolder(View itemView) { + super(itemView); + } +} diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/UserCommentTitleHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/UserCommentTitleHolder.java new file mode 100644 index 0000000000..ae25257a0d --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/UserCommentTitleHolder.java @@ -0,0 +1,18 @@ +package com.gh.gamecenter.adapter.viewholder; + +import android.view.View; +import android.widget.TextView; +import com.gh.base.BaseRecyclerViewHolder; +import com.gh.gamecenter.R; + +import butterknife.BindView; + +public class UserCommentTitleHolder extends BaseRecyclerViewHolder { + + @BindView(R.id.title) + public TextView title; + + public UserCommentTitleHolder(View itemView) { + super(itemView); + } +} diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ViewHolder.kt b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ViewHolder.kt index 6e14708476..6d43361622 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/ViewHolder.kt @@ -1,12 +1,11 @@ package com.gh.gamecenter.adapter.viewholder import com.gh.base.BaseRecyclerViewHolder -import com.gh.gamecenter.databinding.GameColumnCollectionItemBinding -import com.gh.gamecenter.databinding.PersonalHomeRatingBinding -import com.gh.gamecenter.databinding.PrivacyItemBinding -import com.gh.gamecenter.databinding.SearchGameFooterBinding +import com.gh.gamecenter.databinding.* class SearchGameFooterViewHolder(val binding: SearchGameFooterBinding) : BaseRecyclerViewHolder(binding.root) class PersonalHomeRatingViewHolder(val binding: PersonalHomeRatingBinding) : BaseRecyclerViewHolder(binding.root) class GameColumnCollectionItemViewHolder(val binding: GameColumnCollectionItemBinding) : BaseRecyclerViewHolder(binding.root) -class PrivacyPolicyItemViewHolder(val binding: PrivacyItemBinding) : BaseRecyclerViewHolder(binding.root) \ No newline at end of file +class PrivacyPolicyItemViewHolder(val binding: PrivacyItemBinding) : BaseRecyclerViewHolder(binding.root) +class UserCommentHistoryItemViewHolder(val binding: ItemUserCommentHistoryBinding) : BaseRecyclerViewHolder(binding.root) +class UserHomeAmwayItemViewHolder(val binding: UserHomeAmwayItemBinding) : BaseRecyclerViewHolder(binding.root) \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/entity/FollowersOrFansEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/FollowersOrFansEntity.kt index 562a7f3a6f..ef606f9302 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/FollowersOrFansEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/FollowersOrFansEntity.kt @@ -7,6 +7,7 @@ data class FollowersOrFansEntity( val id: String = "", val icon: String = "", val name: String = "", + var introduce: String? = "", val count: Count = Count(), val me: MeEntity = MeEntity(), val auth: Auth = Auth(), diff --git a/app/src/main/java/com/gh/gamecenter/entity/PersonalEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/PersonalEntity.kt index b1f0aa4c77..fac1daafbb 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/PersonalEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/PersonalEntity.kt @@ -19,7 +19,9 @@ data class PersonalEntity( var border: String = "", @SerializedName("icon_border") var iconBorder: AvatarBorderEntity? = null, - var backgroundImageEntity: BackgroundImageEntity? = null + var background: BackgroundImageEntity? = null, + @SerializedName("last_visitor") + val lastVisitor: LastVisitor? = null ) : Parcelable { @Parcelize @@ -34,12 +36,20 @@ data class PersonalEntity( val communityArticle: Int = 0, @SerializedName("game_comment") val gameComment: Int = 0, - val video: Int = 0) : Parcelable { + val video: Int = 0, + @SerializedName("today_visit") + val todayVisit: Int? = 0) : Parcelable { fun getQaCount() = answer + question + communityArticle } } +@Parcelize +data class LastVisitor( + var id: String = "", + var name: String = "", + var icon: String = "") : Parcelable + @Parcelize data class Badge( var name: String = "", diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java index f43c9085ca..4e6d32c5d5 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java +++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.java @@ -12,6 +12,14 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import com.facebook.drawee.view.SimpleDraweeView; import com.gh.base.fragment.BaseLazyFragment; import com.gh.common.databind.BindingAdapters; @@ -83,13 +91,6 @@ import java.util.ArrayList; import java.util.Locale; import java.util.concurrent.TimeUnit; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.core.content.ContextCompat; -import androidx.lifecycle.ViewModelProviders; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -118,6 +119,8 @@ public class PersonalFragment extends BaseLazyFragment { TextView mLoginMessageHint; @BindView(R.id.personal_user_icon) AvatarBorderView mUserIcon; + @BindView(R.id.personal_user_default_icon) + ImageView mUserDefaultIcon; @BindView(R.id.personal_user_small_icon) SimpleDraweeView mUserIconSmall; // @BindView(R.id.personal_user_badge) @@ -142,6 +145,8 @@ public class PersonalFragment extends BaseLazyFragment { RecyclerView mFuncRecyclerView; @BindView(R.id.personal_new_fans_tips) View personalNewFansTips; + @BindView(R.id.personal_background) + SimpleDraweeView mPersonalBackground; public final static String LOGIN_TAG = "login_tag"; //登入标识 public final static String LOGOUT_TAG = "logout_tag"; // 登出标识 @@ -316,15 +321,16 @@ public class PersonalFragment extends BaseLazyFragment { mPersonalBadgeTv.setText("领取徽章"); } else { mPersonalBadgeTv.setText(String.format(Locale.CHINA, "%d枚徽章", badgeEntities.size())); - } - for (BadgeEntity badgeEntity : badgeEntities) { - if (badgeEntity.getWear()) { - ImageUtils.display(mPersonalBadgeIcon, badgeEntity.getIcon()); - mPersonalBadgeIcon.setOnClickListener(v -> DialogUtils.showViewBadgeDialog(requireContext(), new Badge(badgeEntity.getName(), badgeEntity.getIcon(), badgeEntity.getActions()), - () -> DirectUtils.directToBadgeWall(requireContext(), mUserInfoEntity.getUserId(), mUserInfoEntity.getName(), mUserInfoEntity.getIcon()))); + for (BadgeEntity badgeEntity : badgeEntities) { + if (badgeEntity.getWear()){ + ImageUtils.display(mPersonalBadgeIcon, badgeEntity.getIcon()); - break; + mPersonalBadgeIcon.setOnClickListener(v -> DialogUtils.showViewBadgeDialog(requireContext(), new Badge(badgeEntity.getName(), badgeEntity.getIcon(), badgeEntity.getActions()), + () -> DirectUtils.directToBadgeWall(requireContext(), mUserInfoEntity.getUserId(), mUserInfoEntity.getName(), mUserInfoEntity.getIcon()))); + + break; + } } } }); @@ -693,6 +699,11 @@ public class PersonalFragment extends BaseLazyFragment { private void changeLoginState(boolean isLogin) { if (isLogin) { + // 设置背景 + if (mUserInfoEntity.getBackground() != null) { + ImageUtils.display(mPersonalBackground, mUserInfoEntity.getBackground().getUrl()); + } + SignEntity signEntity = mDatabase.signDao().getSignEntityById(UserManager.getInstance().getUserId()); if (signEntity != null && !isCanSign(signEntity.getLastTime())) { mPersonalSign.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.personal_sign_icon_yellow)); @@ -700,6 +711,8 @@ public class PersonalFragment extends BaseLazyFragment { mPersonalSign.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.personal_sign_icon_white)); } if (mUserInfoEntity != null) { + mUserDefaultIcon.setVisibility(View.GONE); + mUserIcon.setVisibility(View.VISIBLE); mUserIcon.display(mUserInfoEntity.getIconBorder() == null ? "" : mUserInfoEntity.getIconBorder().getUrl(), mUserInfoEntity.getIcon(), mUserInfoEntity.getAuth() == null ? "" : mUserInfoEntity.getAuth().getIcon()); ImageUtils.displayIcon(mUserIconSmall, mUserInfoEntity.getIcon()); @@ -709,6 +722,10 @@ public class PersonalFragment extends BaseLazyFragment { mPersonalLogin.setVisibility(View.GONE); mPersonalUserName.setText(mUserInfoEntity.getName()); mPersonalUserNameSmall.setText(mUserInfoEntity.getName()); +// if (mUserInfoEntity.getAuth() != null) { +// mUserBadge.setVisibility(View.VISIBLE); +// ImageUtils.display(mUserBadge, mUserInfoEntity.getAuth().getIcon()); +// } } mUserHomeViewModel.setUserId(UserManager.getInstance().getUserId()); mUserHomeViewModel.getBadgeList(); @@ -716,9 +733,12 @@ public class PersonalFragment extends BaseLazyFragment { MessageUnreadRepository.INSTANCE.loadMessageUnreadTotal(true); } else { mUserIcon.display("", "", ""); + mUserDefaultIcon.setVisibility(View.VISIBLE); + mUserIcon.setVisibility(View.GONE); mUserIconSmall.setImageURI(""); mPersonalBadgeTv.setText("领取徽章"); mPersonalUserNameSmall.setText("立即登录"); +// mUserBadge.setVisibility(View.GONE); mPersonalUserName.setVisibility(View.GONE); mPersonalHome.setVisibility(View.GONE); mPersonalBadge.setVisibility(View.GONE); diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/FollowersOrFansAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/FollowersOrFansAdapter.kt index 713d2024c0..b85074785e 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/FollowersOrFansAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/FollowersOrFansAdapter.kt @@ -45,29 +45,33 @@ class FollowersOrFansAdapter(context: Context, val mViewModel: FollowersOrFansVi } override fun getItemCount(): Int { - return if (mEntityList == null || mEntityList.isEmpty()) 0 else mEntityList.size + ListAdapter.FOOTER_ITEM_COUNT + return if (mEntityList == null || mEntityList.isEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT } override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, position: Int) { if (holder is FollowersOrFansViewHolder) { val entity = mEntityList[position] holder.binding.entity = entity + + holder.binding.divider.visibility = if (position == 0) View.GONE else View.VISIBLE holder.binding.userIcon.display(entity.border, entity.icon, entity.auth.icon) holder.binding.followerBtn.run { - if (entity.id == UserManager.getInstance().userId) { - setText(R.string.myself) - setTextColor(ContextCompat.getColor(mContext, R.color.text_999999)) - setBackgroundResource(R.drawable.questions_detail_tag_bg) - } else if (entity?.me?.isFollower!!) { - setText(R.string.concerned) - setTextColor(ContextCompat.getColor(mContext, R.color.text_999999)) - setBackgroundResource(R.drawable.questions_detail_tag_bg) - } else { - setText(R.string.concern) - setTextColor(R.color.theme_font.toColor()) - setBackgroundResource(R.drawable.questions_detail_tag_bg) + when { + entity.id == UserManager.getInstance().userId -> { + setText(R.string.myself) + setTextColor(ContextCompat.getColor(mContext, R.color.text_999999)) + } + entity?.me?.isFollower!! -> { + setText(R.string.concerned) + setTextColor(ContextCompat.getColor(mContext, R.color.text_999999)) + } + else -> { + setText(R.string.concern) + setTextColor(R.color.theme_font.toColor()) + } } } + holder.binding.followerBtn.setOnClickListener { mContext.ifLogin("个人主页-粉丝-[关注]") { if (entity.id != UserManager.getInstance().userId) { diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/FollowersOrFansFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/FollowersOrFansFragment.kt index 51b3475b01..80ff28d426 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/FollowersOrFansFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/FollowersOrFansFragment.kt @@ -6,6 +6,8 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.gh.common.util.EntranceUtils import com.gh.common.util.MtaHelper +import com.gh.common.util.dip2px +import com.gh.common.view.SpacingItemDecoration import com.gh.gamecenter.baselist.ListFragment import com.gh.gamecenter.entity.FollowersOrFansEntity import com.gh.gamecenter.manager.UserManager @@ -36,6 +38,8 @@ class FollowersOrFansFragment : ListFragment + if (badge.wear) { + ImageUtils.display(mHomeBinding?.userBadgeIcon, badge.icon) + mHomeBinding?.userBadgeIcon?.setOnClickListener { + DialogUtils.showViewBadgeDialog(requireContext(), Badge(badge.name, badge.icon, badge.actions)) { + directToBadgeWall(requireContext(), mPersonalEntity.id, mPersonalEntity.name, mPersonalEntity.icon) + } + } + return@outside + } + } + } updateUserBadge(it) } else { mHomeBinding?.userBadge?.visibility = View.GONE + mHomeBinding?.userBadgeTv?.text = "领取徽章" } } } @@ -126,12 +160,14 @@ class UserHomeFragment : NormalFragment() { reuse_no_connection.setOnClickListener { mUserHomeViewModel.getUserInfo() mUserHomeViewModel.getUserPlayedGame() + mUserHomeViewModel.getUserPlayedGameCount() } toast("网络异常") } mUserHomeViewModel.playedGames.observe(this, Observer { if (!it.isNullOrEmpty()) { + mPlayGameCount = it.size showPlayedGames(it) } val installedList = PackagesManager.filterSameApk(PackagesManager.filterDownloadBlackPackage(PackagesManager.getInstalledList())) @@ -145,10 +181,16 @@ class UserHomeFragment : NormalFragment() { mDialog.show() mDialog.onConfirmClickListener = { mUserHomeViewModel.getUserPlayedGame() + mUserHomeViewModel.getUserPlayedGameCount() } } }) + // 记录玩过的游戏总数 + mUserHomeViewModel.playGamesCount.observe(this, Observer { + mPlayGameCount = it + }) + mMessageUnreadViewModel.liveData.observeNonNull(this) { updateUnreadInfo(it) } @@ -156,12 +198,13 @@ class UserHomeFragment : NormalFragment() { mUserViewModel.editObsUserinfo.observeNonNull(this) { it.data?.let { updatedUserInfo -> if (mUserHomeViewModel.userId == UserManager.getInstance().userId) { - val personalData = mUserHomeViewModel.userInfo.value - if (personalData != null) { - personalData.icon = updatedUserInfo.icon!! - personalData.name = updatedUserInfo.name!! - personalData.introduce = updatedUserInfo.introduce!! - updateUserInfo(personalData) + mUserHomeViewModel.userInfo.value?.run { + icon = updatedUserInfo.icon!! + name = updatedUserInfo.name!! + introduce = updatedUserInfo.introduce!! + iconBorder = updatedUserInfo.iconBorder!! + background = updatedUserInfo.background!! + updateUserInfo(this) } } } @@ -171,18 +214,22 @@ class UserHomeFragment : NormalFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - setNavigationTitle("个人主页") + mHomeBinding?.run { + val statusBarHeight = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) 0 else DisplayUtils.getStatusBarHeight(resources) + val params: ViewGroup.LayoutParams = toolbar.layoutParams + params.height = DisplayUtils.dip2px(50f) + statusBarHeight + toolbar.layoutParams = params - appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, offset -> - val absVerticalOffset = abs(offset) - val total = appBarLayout.totalScrollRange - - if (absVerticalOffset > total / 5) { - setNavigationTitle(mUserHomeViewModel.userInfo.value?.name ?: "个人主页") - } else { - setNavigationTitle("个人主页") - } - }) + appbar.addOnOffsetChangedListener(OnOffsetChangedListener { _: AppBarLayout?, verticalOffset: Int -> + val absOffset = abs(verticalOffset) + val invisibleOffset = DisplayUtils.dip2px(240f - statusBarHeight) + if (absOffset <= invisibleOffset) { + toolbar.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.transparent)) + } else { + toolbar.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.theme)) + } + }) + } } private fun updateTab(personalData: PersonalEntity) { @@ -195,21 +242,35 @@ class UserHomeFragment : NormalFragment() { when { count.gameComment > 0 -> 0 count.getQaCount() > 0 -> 1 - count.video > 0 -> 2 + count.video > 0 -> { + if (count.getQaCount() == 0) 1 else 2 + } else -> 0 } } val tag = "android:switcher:${mHomeBinding?.viewpager?.id}:" - val commentFragment = childFragmentManager.findFragmentByTag("${tag}0") - ?: UserHistoryFragment.getInstance(mUserHomeViewModel.userId, UserHistoryViewModel.SCENE.COMMENT, count) - val qaFragment = childFragmentManager.findFragmentByTag("${tag}1") - ?: UserHistoryFragment.getInstance(mUserHomeViewModel.userId, UserHistoryViewModel.SCENE.QUESTION_ANSWER, count) - val videoFragment = childFragmentManager.findFragmentByTag("${tag}2") - ?: UserVideoHistoryFragment.getInstance(mUserHomeViewModel.userId, count) + val fragmentList = ArrayList() + val titleList = ArrayList() - val fragmentList = listOf(commentFragment, qaFragment, videoFragment) - val titleList = listOf("游戏评论", "论坛", "视频") + val commentFragment = childFragmentManager.findFragmentByTag("${tag}0") + ?: UserCommentHistoryFragment.getInstance(mUserHomeViewModel.userId) + fragmentList.add(commentFragment) + titleList.add("游戏评论 ${count.gameComment}") + + if (count.getQaCount() > 0) { + val qaFragment = childFragmentManager.findFragmentByTag("${tag}1") + ?: UserHistoryFragment.getInstance(mUserHomeViewModel.userId, UserHistoryViewModel.SCENE.QUESTION_ANSWER, count) + fragmentList.add(qaFragment) + titleList.add("问答 ${count.getQaCount()}") + } + + if (count.video > 0) { + val videoFragment = childFragmentManager.findFragmentByTag("${tag}2") + ?: UserVideoHistoryFragment.getInstance(mUserHomeViewModel.userId, count) + fragmentList.add(videoFragment) + titleList.add("视频 ${count.video}") + } viewpager.offscreenPageLimit = fragmentList.size viewpager.adapter = FragmentAdapter(childFragmentManager, fragmentList, titleList) @@ -260,43 +321,58 @@ class UserHomeFragment : NormalFragment() { private fun updateUserInfo(personalData: PersonalEntity) { mHomeBinding?.run { + mPersonalEntity = personalData entity = personalData +// personalData.auth?.let { +// userAuthCommand.text = it.text +// userAuthCommand.setTextColor(Color.parseColor("#" + it.color)) +// it.articleId?.let { +// userAuthCommand.setOnClickListener { +// startActivity(NewsDetailActivity.getIntentById(requireContext(), personalData.auth.articleId, "$mEntrance+(个人主页)")) +// } +// } +// } + + // 设置有边框挂件的头像 userIcon.display(personalData.iconBorder?.url, personalData.icon, personalData.auth?.icon) - personalData.auth?.let { - userAuthCommand.text = it.text - userAuthCommand.setTextColor(Color.parseColor("#" + it.color)) - it.articleId?.let { - userAuthCommand.setOnClickListener { - startActivity(NewsDetailActivity.getIntentById(requireContext(), personalData.auth.articleId, "$mEntrance+(个人主页)")) - } - } - } if (mUserHomeViewModel.userId != UserManager.getInstance().userId) { userFansCountHint.visibility = View.GONE - userConcernOrEdit.run { - typeface = Typeface.defaultFromStyle(Typeface.BOLD) - if (personalData.me.isFollower) { - setText(R.string.concerned) - setTextColor(R.color.text_999999.toColor()) - setBackgroundResource(R.drawable.questions_detail_tag_bg) - } else { - setText(R.string.concern) - setTextColor(R.color.theme_font.toColor()) - setBackgroundResource(R.drawable.questions_detail_tag_bg) - } + userConcernBtn.run { + visibility = View.VISIBLE + setText(if (personalData.me.isFollower) R.string.concerned else R.string.concern) } } else { - userConcernOrEdit.text = "编辑" + userEditBtn.visibility = View.VISIBLE + userChangeBgBtn.visibility = View.VISIBLE + recentVisitContainer.visibility = View.VISIBLE + recentVisitIcon.setOnClickListener { + DirectUtils.directToHomeActivity(requireContext(), personalData.lastVisitor?.id, "个人主页-最近来访") + } + + // 跳转更换背景页 + userChangeBgBtn.setOnClickListener { + startActivity(PersonalityBackgroundActivity.getIntent(requireContext())) + } } - userConcernOrEdit.visibility = View.VISIBLE userBadgeTitle.text = if (mUserHomeViewModel.userId == UserManager.getInstance().userId) "我的徽章" else "TA的徽章" - userIcon.setOnClickListener { - MtaHelper.onEvent("个人主页详情", "个人主页详情", "头像") - startActivity(ImageViewerActivity.getIntent(requireContext(), arrayListOf(personalData.icon), 0, userIcon, "$mEntrance+($mPath)")) + personalData.background?.url?.let { + userBackground.setOnClickListener { + startActivity(ImageViewerActivity.getIntent(requireContext(), arrayListOf(personalData.background!!.url), 0, userIcon, "$mEntrance+($mPath)", true)) + } } + + userIcon.setOnClickListener { + if (mUserHomeViewModel.userId == UserManager.getInstance().userId) { + MtaHelper.onEvent("个人主页详情", "个人主页详情", "头像") + startActivity(AvatarBorderActivity.getIntent(requireContext())) + } else { + startActivity(ImageViewerActivity.getIntent(requireContext(), arrayListOf(personalData.icon), 0, userIcon, "$mEntrance+($mPath)", true)) + } + } + userFollowerContainer.setOnClickListener { MtaHelper.onEvent("个人主页详情", "个人主页详情", "关注数") startActivity(FollowersActivity.getIntent(requireContext(), mUserHomeViewModel.userId, mEntrance, mPath)) @@ -309,21 +385,20 @@ class UserHomeFragment : NormalFragment() { MtaHelper.onEvent("个人主页详情", "个人主页详情", "赞同数") Utils.toast(requireContext(), "共获得 " + NumberUtils.transSimpleCount(entity?.count?.vote!!) + " 赞同") } - userConcernOrEdit.setOnClickListener { + userEditBtn.setOnClickListener { + MtaHelper.onEvent("个人主页详情", "个人主页详情", "编辑按钮") + requireContext().startActivity(UserInfoActivity.getIntent(requireContext())) + } + userConcernBtn.setOnClickListener { ifLogin("个人主页-关注-[关注]") { - if (mUserHomeViewModel.userId == UserManager.getInstance().userId) { - MtaHelper.onEvent("个人主页详情", "个人主页详情", "编辑按钮") - requireContext().startActivity(UserInfoActivity.getIntent(requireContext())) + MtaHelper.onEvent("个人主页详情", "个人主页详情", "关注按钮") + if (personalData.me.isFollower) { + DialogUtils.showAlertDialog(requireContext(), "取消关注", "确定要取消关注 ${personalData.name} 吗?", + "确定取消", "暂不取消", DialogUtils.ConfirmListener { + mUserHomeViewModel.unFollow() + }, null) } else { - MtaHelper.onEvent("个人主页详情", "个人主页详情", "关注按钮") - if (personalData.me.isFollower) { - DialogUtils.showAlertDialog(requireContext(), "取消关注", "确定要取消关注 ${personalData.name} 吗?", - "确定取消", "暂不取消", DialogUtils.ConfirmListener { - mUserHomeViewModel.unFollow() - }, null) - } else { - mUserHomeViewModel.follow() - } + mUserHomeViewModel.follow() } } } @@ -352,4 +427,19 @@ class UserHomeFragment : NormalFragment() { } } + @OnClick(R.id.iv_back, R.id.iv_share) + fun onViewClicked(v: View) { + when(v.id) { + R.id.iv_back -> requireActivity().finish() + + R.id.iv_share -> ShareUtils.getInstance(requireContext()).showShareUserHomeWindows(requireActivity(), + mHomeBinding?.root, + "https://www.baidu.com", + mPersonalEntity.icon, + "【推荐】来自光环助手的${mPersonalEntity.name}" , + "好燃~ 玩过 $mPlayGameCount 款游戏\n给力~ 已领取 $mBadgeCount 枚徽章\n${mPersonalEntity.introduce}\n要好玩,上光环", + ShareUtils.ShareEntrance.userHome, + mPersonalEntity.id, null) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeViewModel.kt index 041fadec11..6a25f8bdd4 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeViewModel.kt @@ -28,6 +28,7 @@ class UserHomeViewModel(application: Application, var userId: String) : AndroidV var badges = MutableLiveData>() var availableBadge = MutableLiveData() var availableBadgeCount = MutableLiveData() + var playGamesCount = MutableLiveData() fun getUserInfo() { RetrofitManager.getInstance(getApplication()) @@ -77,6 +78,20 @@ class UserHomeViewModel(application: Application, var userId: String) : AndroidV }) } + @SuppressLint("CheckResult") + fun getUserPlayedGameCount() { + RetrofitManager.getInstance(getApplication()) + .api.getPlayedGamesCount(userId, Utils.getTime(getApplication())) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : BiResponse>() { + override fun onSuccess(data: retrofit2.Response) { + var countContent = data.headers().get("Total") + playGamesCount.postValue(countContent?.toInt() ?: 0) + } + }) + } + private fun followingCommand(isFollow: Boolean) { val observable = if (isFollow) { RetrofitManager.getInstance(getApplication()).api.postFollowing(userId) diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsActivity.kt b/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsActivity.kt new file mode 100644 index 0000000000..98d0e7ed8e --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsActivity.kt @@ -0,0 +1,26 @@ +package com.gh.gamecenter.personalhome.excellentcomments + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import com.gh.base.BaseActivity +import com.gh.common.util.EntranceUtils +import com.gh.gamecenter.NormalActivity + +class ExcellentCommentsActivity : NormalActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setNavigationTitle("优秀评论") + } + + companion object { + fun getIntent(context: Context, userId: String, entrance: String, path: String): Intent { + val bundle = Bundle() + bundle.putString(EntranceUtils.KEY_USER_ID, userId) + bundle.putString(EntranceUtils.KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path)) + return getTargetIntent(context, ExcellentCommentsActivity::class.java, ExcellentCommentsFragment::class.java, bundle) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsAdapter.kt new file mode 100644 index 0000000000..630ace0abb --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsAdapter.kt @@ -0,0 +1,124 @@ +package com.gh.gamecenter.personalhome.excellentcomments + +import android.content.Context +import android.util.SparseBooleanArray +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.constant.ItemViewType +import com.gh.common.util.* +import com.gh.gamecenter.R +import com.gh.gamecenter.adapter.viewholder.FooterViewHolder +import com.gh.gamecenter.adapter.viewholder.UserCommentHistoryItemViewHolder +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.databinding.ItemUserCommentHistoryBinding +import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity +import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity +import com.gh.gamecenter.personalhome.rating.MyRating +import kotlinx.android.synthetic.main.item_my_game_rating.view.* +import java.util.regex.Pattern + +class ExcellentCommentsAdapter(context: Context, val mListViewModel: ExcellentCommentsViewModel, val mEntrance: String) : + ListAdapter(context) { + + private var mExpandSparseBooleanArray = SparseBooleanArray() + + override fun getItemViewType(position: Int): Int { + return if (position == itemCount - 1) ItemViewType.ITEM_FOOTER else ItemViewType.ITEM_BODY + } + + override fun getItemCount(): Int { + return if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): androidx.recyclerview.widget.RecyclerView.ViewHolder { + val view: View + return when (viewType) { + ItemViewType.ITEM_FOOTER -> { + view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false) + FooterViewHolder(view) + } + else -> { + view = mLayoutInflater.inflate(R.layout.item_user_comment_history, parent, false) + UserCommentHistoryItemViewHolder(ItemUserCommentHistoryBinding.bind(view)) + } + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + when (holder) { + is UserCommentHistoryItemViewHolder -> { + var isChildLongClick = false + val rating = mEntityList[position] + holder.binding.entity = rating + + holder.binding.divider.visibility = if (position == 0) View.GONE else View.VISIBLE + + val maxDesLines = if (mExpandSparseBooleanArray.get(holder.adapterPosition)) Int.MAX_VALUE else 3 + holder.binding.tvComment.setExpandMaxLines(maxDesLines) + holder.binding.tvComment.setIsExpanded(Int.MAX_VALUE == maxDesLines) + + holder.binding.gameIcon.displayGameIcon(rating.game.getRawIconIfExisted(), rating.game.iconSubscript) + + val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(rating.content) + if (m.find()) { + val contents = TextHelper.getCommentLabelSpannableStringBuilder(rating.content, R.color.theme_font) + holder.binding.tvComment.setTextWithHighlightedTextWrappedInsideWrapper(text = contents, copyClickedText = true) + } else { + holder.binding.tvComment.setTextWithHighlightedTextWrappedInsideWrapper(text = rating.content, copyClickedText = true) + } + holder.itemView.tv_comment.setExpandCallback { + mExpandSparseBooleanArray.put(holder.adapterPosition, true) + } + +// holder.binding.vote.setOnClickListener { +// mContext.ifLogin(mEntrance) { +// if (!holder.binding.vote.isChecked) { +// mListViewModel.voteComment(rating.game.id, rating.id, callback = { +// val count = rating.vote + 1 +// holder.binding.vote.text = count.toString() +// holder.binding.vote.isChecked = true +// rating.vote = count +// rating.me.isVoted = true +// }) +// } else { +// mListViewModel.unVoteComment(rating.game.id, rating.id, callback = { +// val count = rating.vote - 1 +// holder.binding.vote.text = if (count == 0) "" else count.toString() +// holder.binding.vote.isChecked = false +// rating.vote = count +// rating.me.isVoted = false +// }) +// } +// } +// } + + holder.binding.apply { + gameInfo.setOnClickListener { + MtaHelper.onEvent("我的光环_新", "我的游戏评论", "游戏详情") + DirectUtils.directToGameDetail(mContext, rating.game.id, "我的游戏评论") + } + commentInfo.setOnClickListener { + if (isChildLongClick) { + isChildLongClick = false + return@setOnClickListener + } + MtaHelper.onEvent("我的光环_新", "我的游戏评论", "评论详情") + val intent = RatingReplyActivity.getIntent(mContext, rating.game.id, rating.id, false, "我的游戏评论", "") + + SyncDataBetweenPageHelper.startActivityForResult(mContext, intent, 100, position) + } + tvComment.setOnLongClickListener(View.OnLongClickListener { + isChildLongClick = true + rating.content.replace(RatingEditActivity.LABEL_REPLACE_REGEX.toRegex(), "").copyTextAndToast() + return@OnLongClickListener true + }) + } + } + is FooterViewHolder -> { + holder.initItemPadding() + holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsFragment.kt new file mode 100644 index 0000000000..01510652d4 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsFragment.kt @@ -0,0 +1,32 @@ +package com.gh.gamecenter.personalhome.excellentcomments + +import com.gh.common.util.EntranceUtils +import com.gh.common.util.dip2px +import com.gh.common.util.viewModelProvider +import com.gh.common.view.SpacingItemDecoration +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.manager.UserManager +import com.gh.gamecenter.personalhome.rating.MyRating +import com.halo.assistant.HaloApp + +open class ExcellentCommentsFragment : ListFragment() { + + protected var mAdapter: ExcellentCommentsAdapter? = null + protected lateinit var mViewModel: ExcellentCommentsViewModel + + + override fun provideListViewModel(): ExcellentCommentsViewModel { + val userId = arguments?.getString(EntranceUtils.KEY_USER_ID) ?: UserManager.getInstance().userId + mViewModel = viewModelProvider(ExcellentCommentsViewModel.Factory(HaloApp.getInstance().application, userId)) + return mViewModel + } + + override fun provideListAdapter(): ListAdapter { + return mAdapter + ?: ExcellentCommentsAdapter(requireContext(), mViewModel, mEntrance).apply { mAdapter = this } + } + + override fun getItemDecoration() = SpacingItemDecoration(onlyDecorateTheFirstItem = true, top = 8F.dip2px()) + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsViewModel.kt b/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsViewModel.kt new file mode 100644 index 0000000000..c82da062fd --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/excellentcomments/ExcellentCommentsViewModel.kt @@ -0,0 +1,38 @@ +package com.gh.gamecenter.personalhome.excellentcomments + +import android.app.Application +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.personalhome.rating.MyRating +import com.gh.gamecenter.retrofit.RetrofitManager +import io.reactivex.Observable +import io.reactivex.Single + +class ExcellentCommentsViewModel(application: Application, var userId: String) + : ListViewModel(application) { + + init { + setOverLimitSize(1) + } + + override fun provideDataObservable(page: Int): Observable>? { + return null + } + + override fun provideDataSingle(page: Int): Single> { + return RetrofitManager.getInstance(getApplication()).api.getMyRating(userId, page, "view:jingxuan") + } + + override fun mergeResultLiveData() { + mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) } + } + + class Factory(private val mApplication: Application, + private val mUserId: String) : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return ExcellentCommentsViewModel(mApplication, mUserId) as T + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/HorizontalExcellentCommentsAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/HorizontalExcellentCommentsAdapter.kt new file mode 100644 index 0000000000..d914f146ce --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/HorizontalExcellentCommentsAdapter.kt @@ -0,0 +1,66 @@ +package com.gh.gamecenter.personalhome.home + +import android.content.Context +import android.view.ViewGroup +import com.gh.common.util.* +import com.gh.gamecenter.R +import com.gh.gamecenter.adapter.viewholder.UserHomeAmwayItemViewHolder +import com.gh.gamecenter.databinding.UserHomeAmwayItemBinding +import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity +import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity +import com.gh.gamecenter.personalhome.rating.MyRating +import com.lightgame.adapter.BaseRecyclerAdapter +import java.util.regex.Pattern + +class HorizontalExcellentCommentsAdapter(context: Context, + var dataList: List) : BaseRecyclerAdapter(context) { + + var mMaxWidth = context.resources.displayMetrics.widthPixels + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserHomeAmwayItemViewHolder { + val view = mLayoutInflater.inflate(R.layout.user_home_amway_item, parent, false) + return UserHomeAmwayItemViewHolder(UserHomeAmwayItemBinding.bind(view)) + } + + override fun onBindViewHolder(holder: UserHomeAmwayItemViewHolder, position: Int) { + holder.binding.run { + data = dataList[position] + var rating = dataList[position] + + val padLeft = if (position == 0) { + 16F.dip2px() + } else 12F.dip2px() + holder.itemView.setPadding(padLeft, 0, 0, 12F.dip2px()) + +// all.visibility = if (position == itemCount - 1) { +// View.VISIBLE +// } else View.GONE + + holder.itemView.layoutParams?.width = if (position == itemCount - 1) { + mMaxWidth - 4F.dip2px() + } else mMaxWidth - 60F.dip2px() + + gameIcon.displayGameIcon(rating.game.getRawIconIfExisted(), rating.game.iconSubscript) + + val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(rating.content) + if (m.find()) { + val contents = TextHelper.getCommentLabelSpannableStringBuilder(rating.content, R.color.theme_font) + content.text = contents + } else { + content.text = rating.content + } + + commentBackground.setOnClickListener { + DirectUtils.directToGameDetail(mContext, rating.game.id, "个人主页-优秀评论") + } + + ratingBlock.setOnClickListener { + val intent = RatingReplyActivity.getIntent(mContext, rating.game.id, rating.id, false, "个人主页-优秀评论", "") + + SyncDataBetweenPageHelper.startActivityForResult(mContext, intent, 100, position) + } + } + } + + override fun getItemCount() = dataList.size +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryAdapter.kt new file mode 100644 index 0000000000..00b79cbb19 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryAdapter.kt @@ -0,0 +1,237 @@ +package com.gh.gamecenter.personalhome.home + +import android.content.Context +import android.graphics.Color +import android.util.Log +import android.util.SparseBooleanArray +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.constant.ItemViewType +import com.gh.common.util.* +import com.gh.common.view.BugFixedPopupWindow +import com.gh.common.view.FixLinearLayoutManager +import com.gh.gamecenter.R +import com.gh.gamecenter.adapter.viewholder.ExcellentCommentsHolder +import com.gh.gamecenter.adapter.viewholder.FooterViewHolder +import com.gh.gamecenter.adapter.viewholder.UserCommentHistoryItemViewHolder +import com.gh.gamecenter.adapter.viewholder.UserCommentTitleHolder +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.databinding.ItemUserCommentHistoryBinding +import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity +import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity +import com.gh.gamecenter.personalhome.excellentcomments.ExcellentCommentsActivity +import kotlinx.android.synthetic.main.item_my_game_rating.view.* +import java.util.regex.Pattern + +class UserCommentHistoryAdapter(context: Context, + val mEntrance: String, + val mListViewModel: UserCommentHistoryViewModel) : ListAdapter(context) { + + private var mExpandSparseBooleanArray = SparseBooleanArray() + private var mHasExcellent = false + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val view: View + return when (viewType) { + ItemViewType.ITEM_FOOTER -> { + view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false) + FooterViewHolder(view) + } + + TYPE_EXCELLENT -> { + mHasExcellent = true + view = mLayoutInflater.inflate(R.layout.item_excellent_comments, parent, false) + ExcellentCommentsHolder(view) + } + + TYPE_TITLE -> { + view = mLayoutInflater.inflate(R.layout.item_user_comment_title, parent, false) + UserCommentTitleHolder(view) + } + + TYPE_NORMAL -> { + view = mLayoutInflater.inflate(R.layout.item_user_comment_history, parent, false) + UserCommentHistoryItemViewHolder(ItemUserCommentHistoryBinding.bind(view)) + } + + else -> throw NullPointerException() + } + } + + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + when (holder) { + is ExcellentCommentsHolder -> { + val list = mEntityList[position].excellentComments!! + holder.run { + excellentCommentMore.run { + visibility = if (list.size > 10) View.VISIBLE else View.VISIBLE + setOnClickListener { + mContext.startActivity(ExcellentCommentsActivity.getIntent(mContext, mListViewModel.userId, mEntrance, "优秀评论-查看更多")) + } + } + + excellentCommentList.run { + layoutManager = FixLinearLayoutManager(context, RecyclerView.HORIZONTAL, false) + if (list.size > 10) + adapter = HorizontalExcellentCommentsAdapter(mContext, if (list.size > 10) list.subList(0, 10) else list) + onFlingListener = null +// LeftPagerSnapHelper(4F.dip2px()).attachToRecyclerView(this) + } + } + } + + is UserCommentTitleHolder -> { + holder.run { + title.setOnClickListener { showFilterWindow(title) } + } + } + + is UserCommentHistoryItemViewHolder -> { + var isChildLongClick = false + val rating = mEntityList[position].normalComment!! + holder.binding.entity = rating + + holder.binding.divider.visibility = if ((mHasExcellent && position == 2) || (!mHasExcellent && position == 1)) View.GONE else View.VISIBLE + + val maxDesLines = if (mExpandSparseBooleanArray.get(holder.adapterPosition)) Int.MAX_VALUE else 3 + holder.binding.tvComment.setExpandMaxLines(maxDesLines) + holder.binding.tvComment.setIsExpanded(Int.MAX_VALUE == maxDesLines) + + holder.binding.gameIcon.displayGameIcon(rating.game.getRawIconIfExisted(), rating.game.iconSubscript) + + val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(rating.content) + if (m.find()) { + val contents = TextHelper.getCommentLabelSpannableStringBuilder(rating.content, R.color.theme_font) + holder.binding.tvComment.setTextWithHighlightedTextWrappedInsideWrapper(text = contents, copyClickedText = true) + } else { + holder.binding.tvComment.setTextWithHighlightedTextWrappedInsideWrapper(text = rating.content, copyClickedText = true) + } + holder.itemView.tv_comment.setExpandCallback { + mExpandSparseBooleanArray.put(holder.adapterPosition, true) + } + + holder.binding.vote.setOnClickListener { + mContext.ifLogin(mEntrance) { + if (!holder.binding.vote.isChecked) { + mListViewModel.voteComment(rating.game.id, rating.id, callback = { + val count = rating.vote + 1 + holder.binding.vote.text = count.toString() + holder.binding.vote.isChecked = true + rating.vote = count + rating.me.isVoted = true + }) + } else { + mListViewModel.unVoteComment(rating.game.id, rating.id, callback = { + val count = rating.vote - 1 + holder.binding.vote.text = if (count == 0) "" else count.toString() + holder.binding.vote.isChecked = false + rating.vote = count + rating.me.isVoted = false + }) + } + } + } + + holder.binding.apply { + gameInfo.setOnClickListener { + MtaHelper.onEvent("我的光环_新", "我的游戏评论", "游戏详情") + DirectUtils.directToGameDetail(mContext, rating.game.id, "我的游戏评论") + } + commentInfo.setOnClickListener { + if (isChildLongClick) { + isChildLongClick = false + return@setOnClickListener + } + MtaHelper.onEvent("我的光环_新", "我的游戏评论", "评论详情") + val intent = RatingReplyActivity.getIntent(mContext, rating.game.id, rating.id, false, "我的游戏评论", "") + + SyncDataBetweenPageHelper.startActivityForResult(mContext, intent, 100, position) + } + tvComment.setOnLongClickListener(View.OnLongClickListener { + isChildLongClick = true + rating.content.replace(RatingEditActivity.LABEL_REPLACE_REGEX.toRegex(), "").copyTextAndToast() + return@OnLongClickListener true + }) + } + } + is FooterViewHolder -> { + holder.initItemPadding() + holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver, R.string.ask_loadover_hint) + } + } + } + + private fun showFilterWindow(view: TextView) { + val contentList = listOf("全部评论", "精彩评论", "安利墙") + + val inflater = LayoutInflater.from(mContext) + val layout = inflater.inflate(R.layout.layout_user_history_filter, null) + val popupWindow = BugFixedPopupWindow( + layout, + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + + val container = layout.findViewById(R.id.container) + for (text in contentList) { + val item = inflater.inflate(R.layout.item_user_history_filter, container, false) + + container.addView(item) + + val hintTv = item.findViewById(R.id.hint_text) + hintTv.text = text + +// if (mViewModel.type.getDisplayText() == text) { +// hintTv.setTextColor(Color.parseColor("#1383EB")) +// } + + item.setOnClickListener { + view.text = text + mListViewModel.changeType(UserCommentHistoryViewModel.TYPE.typeFromDisplayText(text)) + popupWindow.dismiss() + } + } + + popupWindow.setOnDismissListener { +// filterArrow.rotation = 0f + } + + popupWindow.isTouchable = true + popupWindow.isFocusable = true + +// filterArrow.rotation = 180f + popupWindow.showAutoOrientation(view, DisplayUtils.dip2px(16f)) + } + + override fun getItemViewType(position: Int): Int { + return if (position == itemCount - 1) { + ItemViewType.ITEM_FOOTER + } else { + val item = mEntityList[position] + when { + item.excellentComments != null -> TYPE_EXCELLENT + + item.title != null -> TYPE_TITLE + + else -> TYPE_NORMAL + } + } + } + + override fun getItemCount(): Int { + return if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT + } + + companion object { + private const val TYPE_EXCELLENT = 900 + + private const val TYPE_TITLE = 901 + + private const val TYPE_NORMAL = 902 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryFragment.kt new file mode 100644 index 0000000000..a520bf51df --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryFragment.kt @@ -0,0 +1,85 @@ +package com.gh.gamecenter.personalhome.home + +import android.os.Bundle +import android.view.View +import androidx.core.content.ContextCompat +import androidx.core.os.bundleOf +import com.gh.common.util.* +import com.gh.gamecenter.R +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.baselist.LoadStatus +import com.halo.assistant.HaloApp + +class UserCommentHistoryFragment : ListFragment() { + + private var mUserId: String = "" + + private var mAdapter: UserCommentHistoryAdapter? = null + private lateinit var mViewModel: UserCommentHistoryViewModel + + override fun getLayoutId(): Int { + return R.layout.fragment_user_comment_history + } + + override fun onCreate(savedInstanceState: Bundle?) { + arguments?.apply { + mUserId = getString(USER_ID, "") + } + super.onCreate(savedInstanceState) + + } + + override fun getItemDecoration() = null + + override fun provideListViewModel(): UserCommentHistoryViewModel { + mViewModel = viewModelProvider(UserCommentHistoryViewModel.Factory(HaloApp.getInstance().application, mUserId)) + + return mViewModel + } + + override fun provideListAdapter(): ListAdapter<*> { + if (mAdapter == null) { + mAdapter = UserCommentHistoryAdapter(requireContext(), mEntrance, mListViewModel) + } + return mAdapter!! + } + + override fun onLoadEmpty() { + + // RecyclerView 被隐藏的话会导致不能 AppBar 不能滑动 + mListRv.visibility = View.VISIBLE + + when (mViewModel.type) { + UserCommentHistoryViewModel.TYPE.ALL -> { + super.onLoadEmpty() + } + else -> { +// updateFilterHintText() + mAdapter?.loadChange(LoadStatus.INIT_OVER) + } + } +// mReuseNoData?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.background)) + } + + override fun onLoadError() { + super.onLoadError() + + mListRv.visibility = View.VISIBLE + mReuseNoConn?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.background)) + } + + companion object { + + const val USER_ID = "user_id" + + fun getInstance(userId: String): UserCommentHistoryFragment { + return UserCommentHistoryFragment().apply { + with(bundleOf( + UserHistoryFragment.USER_ID to userId + )) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryItemData.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryItemData.kt new file mode 100644 index 0000000000..298308a6d9 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryItemData.kt @@ -0,0 +1,7 @@ +package com.gh.gamecenter.personalhome.home + +import com.gh.gamecenter.personalhome.rating.MyRating + +data class UserCommentHistoryItemData(var excellentComments: List? = null, + var title: String? = null, + var normalComment: MyRating? = null) \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryViewModel.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryViewModel.kt new file mode 100644 index 0000000000..ba9b70d731 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryViewModel.kt @@ -0,0 +1,150 @@ +package com.gh.gamecenter.personalhome.home + +import android.app.Application +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.gh.common.util.ErrorHelper +import com.gh.common.util.UrlFilterUtils +import com.gh.common.util.toObject +import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.baselist.LoadType +import com.gh.gamecenter.entity.ErrorEntity +import com.gh.gamecenter.personalhome.rating.MyRating +import com.gh.gamecenter.retrofit.BiResponse +import com.gh.gamecenter.retrofit.Response +import com.gh.gamecenter.retrofit.RetrofitManager +import io.reactivex.Observable +import io.reactivex.Single +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import okhttp3.ResponseBody +import retrofit2.HttpException + +class UserCommentHistoryViewModel(application: Application, var userId: String) + : ListViewModel(application) { + + private val mApi = RetrofitManager.getInstance(getApplication()).api + + var type: TYPE = TYPE.ALL + + init { + setOverLimitSize(1) + } + + override fun provideDataObservable(page: Int): Observable>? { + return null + } + + override fun provideDataSingle(page: Int): Single> { + return mApi.getMyRating(userId, page, getFilter()) + } + + override fun mergeResultLiveData() { + mResultLiveData.addSource(mListLiveData) { list -> + if (type == TYPE.ALL && list.isEmpty()) return@addSource + + val itemDataList = arrayListOf() + + mApi.getExcellentComments(userId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : BiResponse>() { + override fun onSuccess(data: List) { + if (data.isNotEmpty()) itemDataList.add(UserCommentHistoryItemData(excellentComments = data)) + + itemDataList.add(UserCommentHistoryItemData(title = "")) + + list.forEach { + itemDataList.add(UserCommentHistoryItemData(normalComment = it)) + } + + mResultLiveData.postValue(itemDataList) + } + }) + } + } + + + fun voteComment(gameId: String, commentId: String, callback: () -> Unit) { + mApi.voteGameComment(gameId, commentId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: ResponseBody?) { + callback.invoke() + } + + override fun onFailure(e: HttpException?) { + val string = e?.response()?.errorBody()?.string() + val errorEntity = string?.toObject() + if (errorEntity?.code == 403008) { + onResponse(null) + return + } + ErrorHelper.handleError(getApplication(), string) + } + }) + } + + fun unVoteComment(gameId: String, commentId: String, callback: () -> Unit) { + mApi.unvoteGameComment(gameId, commentId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: ResponseBody?) { + super.onResponse(response) + callback.invoke() + } + + override fun onFailure(e: HttpException?) { + val string = e?.response()?.errorBody()?.string() + ErrorHelper.handleError(getApplication(), string) + } + }) + } + + + fun changeType(type: TYPE) { + if (this.type != type) { + this.type = type + load(LoadType.REFRESH) + } + } + + private fun getFilter(): String { + return UrlFilterUtils.getFilterQuery( + "view", "halo", + "type", type.value) + + } + + enum class TYPE(val value: String) { + ALL("all"), + JINGXUAN("jingxuan"), + ANLIWALL("anliwall"); + + fun getDisplayText() = when (this) { + ALL -> "全部评论" + JINGXUAN -> "精彩评论" + ANLIWALL -> "安利墙" + } + + companion object { + fun typeFromDisplayText(text: String): TYPE { + return values().find { it.getDisplayText() == text } ?: ALL + } + + val TYPE_LIST = arrayListOf().apply { + TYPE.values().iterator().forEach { add(it.getDisplayText()) } + } + } + } + + class Factory(private val mApplication: Application, + private val mUserId: String) : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return UserCommentHistoryViewModel(mApplication, mUserId) as T + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/rating/MyRating.kt b/app/src/main/java/com/gh/gamecenter/personalhome/rating/MyRating.kt index 1a4a4d5845..ce2e182be6 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/rating/MyRating.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/rating/MyRating.kt @@ -19,6 +19,10 @@ data class MyRating(@SerializedName("_id") var me: MeEntity = MeEntity(), val active: Boolean = true, var audit: Boolean = false, + @SerializedName("is_jingxuan") + val excellent: Boolean = false, + @SerializedName("anliwall") + val amway: Boolean = false, val game: PersonalHistoryEntity.Game = PersonalHistoryEntity.Game()) { fun transformHistoryEntity(): PersonalHistoryEntity { diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index de8cf0a296..92674258e1 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -1885,11 +1885,17 @@ public interface ApiService { Single> getAllTheGameReservations(@Path("user_id") String userId, @Query("timestamp") long timestamp); /** - * 个人主页-我的评分 + * 获取某用户的游戏评分列表(userId为本人则为个人主页-我的评分) */ @GET("users/{user_id}/games/comments") Single> getMyRating(@Path("user_id") String userId, @Query("page") int page, @Query("filter") String filter); + /** + * 我的光环-用户的优秀评论列表 + */ + @GET("users/{user_id}/games/comments?page=1&filter=view:jingxuan") + Single> getExcellentComments(@Path("user_id") String userId); + /** * 游戏评分-修改 */ @@ -2188,6 +2194,12 @@ public interface ApiService { @DELETE("users/{user_id}/played_games/{game_id}") Single deletePlayedGame(@Path("user_id") String userId, @Path("game_id") String gameId); + /** + * 获取玩过的游戏总数 + */ + @GET("users/{user_id}/played_games") + Single> getPlayedGamesCount(@Path("user_id") String userId, @Query("timestamp") long timestamp); + /** * 获取用户成功安装应用记录(用于玩过的游戏) */ diff --git a/app/src/main/res/drawable-xxhdpi/ic_badge_default.png b/app/src/main/res/drawable-xxhdpi/ic_badge_default.png new file mode 100644 index 0000000000..2c96a872ab Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_badge_default.png differ diff --git a/app/src/main/res/drawable-xxhdpi/share_qq.png b/app/src/main/res/drawable-xxhdpi/share_qq.png new file mode 100644 index 0000000000..d063a5561d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/share_qq.png differ diff --git a/app/src/main/res/drawable-xxhdpi/share_qq_zone.png b/app/src/main/res/drawable-xxhdpi/share_qq_zone.png new file mode 100644 index 0000000000..da5323b6e2 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/share_qq_zone.png differ diff --git a/app/src/main/res/drawable-xxhdpi/share_wechat_moments.png b/app/src/main/res/drawable-xxhdpi/share_wechat_moments.png new file mode 100644 index 0000000000..d6dbbc9308 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/share_wechat_moments.png differ diff --git a/app/src/main/res/drawable-xxhdpi/share_weibo.png b/app/src/main/res/drawable-xxhdpi/share_weibo.png new file mode 100644 index 0000000000..8ec0d233a6 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/share_weibo.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_badge_default.png b/app/src/main/res/drawable-xxxhdpi/ic_badge_default.png new file mode 100644 index 0000000000..e426447b71 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_badge_default.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/share_qq.png b/app/src/main/res/drawable-xxxhdpi/share_qq.png new file mode 100644 index 0000000000..427b52eb9c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/share_qq.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/share_qq_zone.png b/app/src/main/res/drawable-xxxhdpi/share_qq_zone.png new file mode 100644 index 0000000000..0be51f1721 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/share_qq_zone.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/share_wechat_moments.png b/app/src/main/res/drawable-xxxhdpi/share_wechat_moments.png new file mode 100644 index 0000000000..bfa91ed144 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/share_wechat_moments.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/share_weibo.png b/app/src/main/res/drawable-xxxhdpi/share_weibo.png new file mode 100644 index 0000000000..63ab8d76da Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/share_weibo.png differ diff --git a/app/src/main/res/drawable/bg_amway_tag.xml b/app/src/main/res/drawable/bg_amway_tag.xml new file mode 100644 index 0000000000..83327960f1 --- /dev/null +++ b/app/src/main/res/drawable/bg_amway_tag.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_comment_tag.xml b/app/src/main/res/drawable/bg_comment_tag.xml new file mode 100644 index 0000000000..171eb7c2c1 --- /dev/null +++ b/app/src/main/res/drawable/bg_comment_tag.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_follower_or_fans_btn.xml b/app/src/main/res/drawable/bg_follower_or_fans_btn.xml new file mode 100644 index 0000000000..abea68584e --- /dev/null +++ b/app/src/main/res/drawable/bg_follower_or_fans_btn.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_recent_visit.xml b/app/src/main/res/drawable/bg_recent_visit.xml new file mode 100644 index 0000000000..f132223805 --- /dev/null +++ b/app/src/main/res/drawable/bg_recent_visit.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_save_pic.xml b/app/src/main/res/drawable/bg_save_pic.xml new file mode 100644 index 0000000000..fd954fa75f --- /dev/null +++ b/app/src/main/res/drawable/bg_save_pic.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_user_home_normal_btn.xml b/app/src/main/res/drawable/bg_user_home_normal_btn.xml new file mode 100644 index 0000000000..7761ac0419 --- /dev/null +++ b/app/src/main/res/drawable/bg_user_home_normal_btn.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_viewimage.xml b/app/src/main/res/layout/activity_viewimage.xml index f052299d6b..7f9eb1a2c8 100644 --- a/app/src/main/res/layout/activity_viewimage.xml +++ b/app/src/main/res/layout/activity_viewimage.xml @@ -56,6 +56,19 @@ android:visibility="gone" tools:text="查看原图(1.8M)" tools:visibility="visible" /> - + + \ No newline at end of file diff --git a/app/src/main/res/layout/followers_or_fans_item.xml b/app/src/main/res/layout/followers_or_fans_item.xml index 1fd9c534c3..1493133006 100644 --- a/app/src/main/res/layout/followers_or_fans_item.xml +++ b/app/src/main/res/layout/followers_or_fans_item.xml @@ -1,25 +1,25 @@ - + - + + + + + name = "entity" + type = "com.gh.gamecenter.entity.FollowersOrFansEntity" /> + - - - - + + + + android:maxWidth="220dp" + android:layout_marginTop="5dp" + android:layout_marginLeft="8dp" + android:includeFontPadding="false" + android:textColor="@color/text_999999" + android:textSize="11sp" + android:text='@{TextUtils.isEmpty(entity.introduce)?"这是一个很神秘的崽~":entity.introduce}' + tools:text="这是一个很神秘的崽~这是一个很神秘的崽~这是一个很神秘的崽~这是一个很神秘的崽~" + app:layout_constraintTop_toBottomOf="@+id/user_name" + app:layout_constraintLeft_toRightOf="@+id/user_icon" + app:layout_constraintBottom_toBottomOf="@+id/user_icon" /> + visibleGone="@{entity.count.answer > 0 && entity.count.vote > 0}" + android:id = "@+id/count_rl" + android:layout_width = "wrap_content" + android:layout_height = "wrap_content" + android:layout_marginLeft = "8dp" + android:layout_marginTop = "12dp" + app:layout_constraintLeft_toRightOf = "@id/user_icon" + app:layout_constraintTop_toBottomOf = "@id/user_introduce" + app:layout_constraintBottom_toBottomOf = "parent"> + visibleGone="@{entity.count.answer > 0}" + android:id = "@+id/answer_count" + android:layout_width = "wrap_content" + android:layout_height = "wrap_content" + android:layout_marginRight = "11dp" + tools:text="1回答" + android:text = "@{NumberUtils.transSimpleCount(entity.count.answer) + `回答`}" + android:textColor = "@color/text_666666" + android:textSize = "11sp" /> - + visibleGone="@{entity.count.vote > 0}" + android:id = "@+id/vote_count" + android:layout_width = "wrap_content" + android:layout_height = "wrap_content" + android:layout_toRightOf = "@id/answer_count" + tools:text = "1赞同" + android:text = "@{NumberUtils.transSimpleCount(entity.count.vote) + `赞同`}" + android:textColor = "@color/text_666666" + android:textSize = "11sp" /> + + app:layout_constraintTop_toTopOf = "parent" + app:layout_constraintBottom_toBottomOf = "parent" + app:layout_constraintRight_toRightOf = "parent" + tools:text = "关注" /> - - + + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index bfb3700f37..eba718061a 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -46,28 +46,35 @@ + android:background="@color/lite_blue"> - - - + app:layout_constraintTop_toTopOf="parent"> + + + + + + @@ -115,13 +124,14 @@ visibleGone="@{TextUtils.isEmpty(entity.introduce)?false:true}" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="11dp" android:lineSpacingMultiplier="1.2" android:paddingLeft="20dp" android:paddingRight="20dp" android:text="@{entity.introduce}" android:textColor="@color/title" android:textSize="15sp" - app:layout_constraintTop_toBottomOf="@id/user_icon" /> + app:layout_constraintTop_toBottomOf="@id/user_icon_container" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_personal.xml b/app/src/main/res/layout/fragment_personal.xml index 61f3cfb0ed..600c52fe81 100644 --- a/app/src/main/res/layout/fragment_personal.xml +++ b/app/src/main/res/layout/fragment_personal.xml @@ -3,21 +3,21 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/list_refresh" + android:fitsSystemWindows="true" android:layout_width="match_parent" - android:layout_height="match_parent" - android:fitsSystemWindows="true"> - + android:layout_height="match_parent"> @@ -32,41 +32,53 @@ + android:layout_height="184dp"> + + + android:layout_width="70dp" + android:layout_height="70dp" + android:gravity="center" + app:avatar_width="70dp" /> - + android:layout_alignParentBottom="true" /> @@ -74,25 +86,26 @@ android:id="@+id/personal_login" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginLeft="12dp" android:text="立即登录" android:textColor="@color/white" android:textSize="18sp" android:textStyle="bold" - android:layout_marginLeft="90dp" app:layout_constraintBottom_toBottomOf="@+id/personal_user_icon_container" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toEndOf="@+id/personal_user_icon_container" app:layout_constraintTop_toTopOf="@+id/personal_user_icon_container" /> @@ -118,12 +130,12 @@ android:id="@+id/personal_badge_tv" android:layout_width="58dp" android:layout_height="14dp" - android:layout_centerVertical="true" android:layout_marginLeft="4dp" - android:background="@drawable/bg_personal_badge" - android:gravity="center_vertical|right" - android:includeFontPadding="false" android:paddingRight="8dp" + android:layout_centerVertical="true" + android:gravity="center_vertical|right" + android:background="@drawable/bg_personal_badge" + android:includeFontPadding="false" android:text="领取徽章" android:textColor="@color/white" android:textSize="9sp" /> @@ -132,7 +144,7 @@ android:id="@+id/personal_badge_icon" android:layout_width="16dp" android:layout_height="16dp" - app:placeholderImage="@drawable/ic_personal_badge" /> + app:placeholderImage="@drawable/ic_badge_default" /> + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_excellent_comments.xml b/app/src/main/res/layout/item_excellent_comments.xml new file mode 100644 index 0000000000..e6f2260c5a --- /dev/null +++ b/app/src/main/res/layout/item_excellent_comments.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_user_comment_history.xml b/app/src/main/res/layout/item_user_comment_history.xml new file mode 100644 index 0000000000..098bd11910 --- /dev/null +++ b/app/src/main/res/layout/item_user_comment_history.xml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_user_comment_title.xml b/app/src/main/res/layout/item_user_comment_title.xml new file mode 100644 index 0000000000..4c05c2a14b --- /dev/null +++ b/app/src/main/res/layout/item_user_comment_title.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/popup_share_dialog.xml b/app/src/main/res/layout/popup_share_dialog.xml new file mode 100644 index 0000000000..1cd9bc6bb3 --- /dev/null +++ b/app/src/main/res/layout/popup_share_dialog.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/user_home_amway_item.xml b/app/src/main/res/layout/user_home_amway_item.xml new file mode 100644 index 0000000000..6455e4411e --- /dev/null +++ b/app/src/main/res/layout/user_home_amway_item.xml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index da7a295767..a5db181a41 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -85,6 +85,7 @@ #66000000 #80000000 + #33FFFFFF #99FFFFFF #80FFFFFF #E6FFFFFF @@ -111,6 +112,7 @@ #e5e5e5 #ECF6FF #EDEDED + #F2F2F2 #80000000 #404040 #ededed @@ -198,5 +200,7 @@ #28282E #3796FF #213964 + #06CEA8 + #FFA142 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 99352fd78e..ac543ef691 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -726,6 +726,24 @@ 领取徽章 申请领取 + 最近来访 + 今日来访 + 关注 + 粉丝 + 赞同 + 编辑 + 更换背景 + 安利墙 + 精彩评论 + 分享到 + 微信好友 + 朋友圈 + QQ好友 + QQ空间 + 微博 + 优秀评论 + 查看更多 +