[Modify]我的标签功能开发

This commit is contained in:
wushaocheng
2023-02-17 19:53:16 +08:00
parent 21f48fa1bc
commit 0428c74975
24 changed files with 379 additions and 39 deletions

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_user_label_select" android:state_selected="true" />
<item android:drawable="@drawable/bg_user_label" android:state_selected="false" />
</selector>

View File

@@ -2,12 +2,17 @@ package com.yizhuan.erban.ui.user.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent
import com.netease.nim.uikit.StatusBarUtil
import com.netease.nim.uikit.common.util.sys.ScreenUtil
import com.yizhuan.erban.R
@@ -15,11 +20,24 @@ import com.yizhuan.erban.base.BaseViewBindingActivity
import com.yizhuan.erban.base.TitleBar
import com.yizhuan.erban.databinding.ActivityEditUserTagBinding
import com.yizhuan.erban.ui.user.adapter.CommonWrapIndicatorAdapter
import com.yizhuan.erban.ui.user.fragment.MyTagFragment
import com.yizhuan.erban.ui.user.adapter.MyUserLabelAdapter
import com.yizhuan.erban.ui.user.event.LabelEvent
import com.yizhuan.erban.ui.user.event.UserLabelEvent
import com.yizhuan.erban.ui.user.fragment.LabelFragment
import com.yizhuan.erban.ui.widget.magicindicator.ViewPagerHelper
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator
import com.yizhuan.xchat_android_core.user.UserModel
import com.yizhuan.xchat_android_core.user.bean.UserLabelInfo
import com.yizhuan.xchat_android_library.common.entity.CommonTabEntity
import com.yizhuan.xchat_android_library.utils.ResUtil
import com.yizhuan.xchat_android_library.utils.StringUtils
import io.reactivex.SingleObserver
import io.reactivex.disposables.Disposable
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.Serializable
/**
* author: wushaocheng
@@ -45,7 +63,11 @@ class EditUserTagActivity : BaseViewBindingActivity<ActivityEditUserTagBinding>(
private val mTitles = ArrayList<CommonTabEntity>()
private val mMyLabelAdapter by lazy { MyUserLabelAdapter() }
override fun init() {
EventBus.getDefault().register(this)
initTitleBar(
getString(R.string.my_tag),
object : TitleBar.TextAction(
@@ -53,26 +75,70 @@ class EditUserTagActivity : BaseViewBindingActivity<ActivityEditUserTagBinding>(
ContextCompat.getColor(this, R.color.color_white)
) {
override fun performAction(view: View) {
val list = mMyLabelAdapter.data.joinToString(",")
dialogManager.showProgressDialog(
this@EditUserTagActivity,
ResUtil.getString(R.string.ui_user_userinfomodifyactivity_02)
)
UserModel.get().saveLabel(list).subscribe(object : SingleObserver<String> {
override fun onSubscribe(d: Disposable) {
mCompositeDisposable.add(d)
}
override fun onSuccess(s: String) {
dialogManager.dismissDialog()
toast(getString(R.string.update_success))
}
override fun onError(e: Throwable) {
dialogManager.dismissDialog()
toast(e.message)
}
})
}
})
userLabelInfo = intent.getSerializableExtra(USER_LABEL) as UserLabelInfo?
initTop()
initTabTitle()
initViewPager()
}
private fun initTop() {
val flexBoxLayoutManager = FlexboxLayoutManager(context)
flexBoxLayoutManager.flexDirection = FlexDirection.ROW//主轴为水平方向,起点在左端
flexBoxLayoutManager.flexWrap = FlexWrap.WRAP//按正常方向换行
flexBoxLayoutManager.justifyContent = JustifyContent.FLEX_START//交叉轴的起点对齐
binding.mRecyclerView.layoutManager = flexBoxLayoutManager
binding.mRecyclerView.adapter = mMyLabelAdapter
mMyLabelAdapter.setOnItemChildClickListener { _, _, position ->
EventBus.getDefault().post(LabelEvent(mMyLabelAdapter.data[position]))
mMyLabelAdapter.remove(position)
}
userLabelInfo?.meLabels?.let {
if (it.isNotEmpty()) {
mMyLabelAdapter.setNewData(it)
} else {
binding.group.visibility = View.GONE
}
}
}
private fun initTabTitle() {
mTitles.add(CommonTabEntity(MyTagFragment::class.java, "在做"))
mTitles.add(CommonTabEntity(MyTagFragment::class.java, "兴趣"))
mTitles.add(CommonTabEntity(MyTagFragment::class.java, "经历"))
mTitles.add(CommonTabEntity(MyTagFragment::class.java, "性格"))
mTitles.add(CommonTabEntity(MyTagFragment::class.java, "阅读"))
mTitles.add(CommonTabEntity(MyTagFragment::class.java, "音乐"))
val tabList = userLabelInfo?.groups
tabList?.let {
it.forEach { tab ->
mTitles.add(CommonTabEntity(LabelFragment::class.java, tab))
}
}
}
private fun initViewPager() {
if (mTitles.size == 0) return
val commonNavigator = CommonNavigator(context)
commonNavigator.setTitleWrapContent(false)
commonNavigator.titleMargin = ScreenUtil.dip2px(2.0F)
@@ -86,7 +152,13 @@ class EditUserTagActivity : BaseViewBindingActivity<ActivityEditUserTagBinding>(
object : FragmentStateAdapter(supportFragmentManager, lifecycle) {
override fun createFragment(position: Int): Fragment {
val tabEntity = mTitles[position]
return tabEntity.frgClazz.newInstance()
val newInstance = tabEntity.frgClazz.newInstance()
val bundle = Bundle()
val labelList =
userLabelInfo?.labels?.let { label -> label.filter { it.group == mTitles[position].title } }
bundle.putSerializable(LabelFragment.USER_TAG, labelList as Serializable?)
newInstance.arguments = bundle
return newInstance
}
override fun getItemCount(): Int {
@@ -101,6 +173,21 @@ class EditUserTagActivity : BaseViewBindingActivity<ActivityEditUserTagBinding>(
binding.mViewPager.currentItem = position
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onUserLabelEvent(event: UserLabelEvent) {
val data = mMyLabelAdapter.data
if (data.contains(event.label)) {
val pos = data.indexOf(event.label)
mMyLabelAdapter.remove(pos)
} else {
if (data.size == 20) {
toast(getString(R.string.max_to_add_label))
} else {
mMyLabelAdapter.addData(event.label)
}
}
}
override fun needSteepStateBar(): Boolean {
return true
}
@@ -111,4 +198,10 @@ class EditUserTagActivity : BaseViewBindingActivity<ActivityEditUserTagBinding>(
StatusBarUtil.StatusBarLightMode(this)
}
override fun onDestroy() {
super.onDestroy()
dialogManager.dismissDialog()
EventBus.getDefault().unregister(this)
}
}

View File

@@ -279,6 +279,7 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
}
override fun onSuccess(userLabelInfo: UserLabelInfo) {
dialogManager.dismissDialog()
EditUserTagActivity.start(this@UserInfoModifyActivity, userLabelInfo)
}
@@ -595,6 +596,7 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
override fun onDestroy() {
super.onDestroy()
dialogManager.dismissDialog()
mJob?.cancel()
}

View File

@@ -0,0 +1,21 @@
package com.yizhuan.erban.ui.user.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R
import com.yizhuan.xchat_android_core.user.bean.UserLabelItemInfo
/**
* author: wushaocheng
* Created by wushaocheng on 2023/2/16.
* desc: 用户标签
*/
class MyUserLabelAdapter :
BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_my_user_label) {
override fun convert(helper: BaseViewHolder, item: String) {
helper.setText(R.id.tv_label, item)
helper.addOnClickListener(R.id.iv_close)
}
}

View File

@@ -0,0 +1,44 @@
package com.yizhuan.erban.ui.user.adapter
import androidx.appcompat.widget.AppCompatTextView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R
import com.yizhuan.erban.ui.user.event.UserLabelEvent
import com.yizhuan.xchat_android_core.user.bean.UserLabelItemInfo
import org.greenrobot.eventbus.EventBus
/**
* author: wushaocheng
* Created by wushaocheng on 2023/2/16.
* desc: 用户标签
*/
class UserLabelAdapter :
BaseQuickAdapter<UserLabelItemInfo, BaseViewHolder>(R.layout.item_user_label) {
//用来记录已经勾选的位置(set集合是为了防止放入重复数据)
var mutilSelectedList = mutableSetOf<Int>()
override fun convert(helper: BaseViewHolder, item: UserLabelItemInfo) {
helper.setText(R.id.tv_user_tag, item.label)
val tvLabel = helper.getView<AppCompatTextView>(R.id.tv_user_tag)
if (item.picked) {
mutilSelectedList.add(helper.layoutPosition)
}else{
mutilSelectedList.remove(helper.layoutPosition)
}
tvLabel.isSelected = item.picked
helper.itemView.setOnClickListener {
if (mutilSelectedList.contains(helper.layoutPosition)) {
mutilSelectedList.remove(helper.layoutPosition)
tvLabel.isSelected = false
EventBus.getDefault().post(UserLabelEvent(item.label))
} else {
mutilSelectedList.add(helper.layoutPosition)
tvLabel.isSelected = true
EventBus.getDefault().post(UserLabelEvent(item.label))
}
}
}
}

View File

@@ -3,16 +3,18 @@ package com.yizhuan.erban.ui.user.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R
import com.yizhuan.xchat_android_core.user.bean.UserLabelItemInfo
/**
* 用户标签
* author: wushaocheng
* Created by wushaocheng on 2023/2/16.
* desc: 用户标签
*/
class UserTagAdapter :
BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_user_tag) {
BaseQuickAdapter<UserLabelItemInfo, BaseViewHolder>(R.layout.item_user_tag) {
override fun convert(helper: BaseViewHolder, item: String) {
helper.setText(R.id.tv_user_tag, item)
override fun convert(helper: BaseViewHolder, item: UserLabelItemInfo) {
helper.setText(R.id.tv_user_tag, item.label)
}
}

View File

@@ -0,0 +1,8 @@
package com.yizhuan.erban.ui.user.event
import lombok.AllArgsConstructor
import lombok.Data
@AllArgsConstructor
@Data
class LabelEvent(val label: String = "")

View File

@@ -0,0 +1,8 @@
package com.yizhuan.erban.ui.user.event
import lombok.AllArgsConstructor
import lombok.Data
@AllArgsConstructor
@Data
class UserLabelEvent(val label: String = "")

View File

@@ -0,0 +1,62 @@
package com.yizhuan.erban.ui.user.fragment
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent
import com.yizhuan.erban.base.BaseViewBindingFragment
import com.yizhuan.erban.databinding.FragmentMyTagBinding
import com.yizhuan.erban.ui.user.adapter.UserLabelAdapter
import com.yizhuan.erban.ui.user.event.LabelEvent
import com.yizhuan.erban.ui.user.event.UserLabelEvent
import com.yizhuan.xchat_android_core.user.bean.UserLabelItemInfo
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
/**
* author: wushaocheng
* time: 2022/2/16
* desc: 我的标签
*/
class LabelFragment : BaseViewBindingFragment<FragmentMyTagBinding>() {
companion object {
const val USER_TAG = "user_tag"
}
private var labelList: List<UserLabelItemInfo>? = null
private val mAdapter by lazy { UserLabelAdapter() }
override fun init() {
EventBus.getDefault().register(this)
labelList = arguments?.getSerializable(USER_TAG) as? ArrayList<UserLabelItemInfo>?
val flexBoxLayoutManager = FlexboxLayoutManager(context)
flexBoxLayoutManager.flexDirection = FlexDirection.ROW//主轴为水平方向,起点在左端
flexBoxLayoutManager.flexWrap = FlexWrap.WRAP//按正常方向换行
flexBoxLayoutManager.justifyContent = JustifyContent.FLEX_START//交叉轴的起点对齐
binding.mRecyclerView.layoutManager = flexBoxLayoutManager
binding.mRecyclerView.adapter = mAdapter
mAdapter.setNewData(labelList)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onLabelEvent(event: LabelEvent) {
val list = mAdapter.data.map { it.label }
if(list.contains(event.label)){
val pos = list.indexOf(event.label)
val bean = mAdapter.data[pos]
bean.picked = false
mAdapter.notifyItemChanged(pos)
}
}
override fun onDestroyView() {
super.onDestroyView()
EventBus.getDefault().unregister(this)
}
}

View File

@@ -1,17 +0,0 @@
package com.yizhuan.erban.ui.user.fragment
import com.yizhuan.erban.base.BaseViewBindingFragment
import com.yizhuan.erban.databinding.FragmentUserinfoDynamicBinding
/**
* author: wushaocheng
* time: 2022/2/16
* desc: 我的标签
*/
class MyTagFragment : BaseViewBindingFragment<FragmentUserinfoDynamicBinding>() {
override fun init() {
}
}

View File

@@ -31,7 +31,6 @@ class UserInfoViewModel : ViewModel() {
private val _hallData = MutableLiveData<ClanAndHallInfo>()
val hallData: LiveData<ClanAndHallInfo> = _hallData
private val disposable: CompositeDisposable by lazy {
CompositeDisposable()
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_18"/>
<solid android:color="@color/color_FFFFFF"/>
</shape>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_18"/>
<solid android:color="@color/color_F7F7F7"/>
</shape>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="180"
android:endColor="#EEDCFF"
android:startColor="#CCF8F9"
android:type="linear"
android:useLevel="true" />
<corners android:radius="@dimen/dp_18" />
</shape>

View File

@@ -36,6 +36,7 @@
app:layout_constraintTop_toBottomOf="@+id/title_bar" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_20"
@@ -46,6 +47,20 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_tag_empty" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="iv_tag_empty,tv_tip" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mRecyclerView"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0"
android:layout_marginTop="@dimen/dp_15"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintBottom_toBottomOf="@+id/view_bg"/>
<com.yizhuan.erban.ui.widget.magicindicator.MagicIndicator
android:id="@+id/magic_indicator"
android:layout_width="match_parent"

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_ffffff_18"
android:gravity="center"
android:layout_marginStart="@dimen/dp_15"
android:layout_marginBottom="@dimen/dp_15"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="@dimen/dp_16"
android:paddingTop="@dimen/dp_8"
android:paddingEnd="@dimen/dp_2"
android:paddingBottom="@dimen/dp_8"
android:textColor="@color/color_1F1A4E"
android:textSize="@dimen/sp_13"
tools:text="自由人" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_12"
android:src="@drawable/ic_tag_close_my" />
</LinearLayout>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tv_user_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_14"
android:layout_marginTop="@dimen/dp_7"
android:layout_marginBottom="@dimen/dp_7"
android:paddingStart="@dimen/dp_16"
android:paddingTop="@dimen/dp_8"
android:paddingEnd="@dimen/dp_16"
android:paddingBottom="@dimen/dp_8"
android:textColor="@color/color_1F1B4F"
android:textSize="@dimen/sp_13"
android:background="@drawable/selector_user_label"
tools:text="上班族" />

View File

@@ -646,5 +646,6 @@
<color name="color_ECE4FF">#ECE4FF</color>
<color name="color_D8D8D8">#D8D8D8</color>
<color name="color_F3F5F9">#F3F5F9</color>
<color name="color_1F1B4F">#1F1B4F</color>
</resources>

View File

@@ -5072,5 +5072,6 @@
<string name="setting_personal_tags_will_be_more_popular">設置個人標簽將更受歡迎~</string>
<string name="gold_exchange_permission_of_the_user_has_been_disabled">已關閉該用戶的金幣兌換權限~</string>
<string name="gold_exchange_permission_of_the_user_has_been_enabled">已開啟該用戶的金幣兌換權限~</string>
<string name="max_to_add_label">最多只能添加20個標簽哦~</string>
</resources>

View File

@@ -237,4 +237,9 @@ public interface IUserModel extends IModel {
*/
Single<UserLabelInfo> getUserLabelInfo();
/**
* 保存标签
*/
Single<String> saveLabel(String label);
}

View File

@@ -309,11 +309,10 @@ public final class UserModel extends BaseModel implements IUserModel {
return api.getUserInfoDetail(String.valueOf(uid))
.compose(RxHelper.handleSchedulers())
.flatMap(userDetailInfo -> {
UserDetailInfo userInfo = userDetailInfo;
if (null == userInfo) {
if (null == userDetailInfo) {
return Single.error(new Exception(ResUtil.getString(R.string.xchat_android_core_user_usermodel_06)));
}
return Single.just(userInfo);
return Single.just(userDetailInfo);
});
}
@@ -828,6 +827,13 @@ public final class UserModel extends BaseModel implements IUserModel {
.compose(RxHelper.handleSchedulers());
}
@Override
public Single<String> saveLabel(String label) {
return api.saveLabel(label)
.compose(RxHelper.handleBeanData())
.compose(RxHelper.handleSchedulers());
}
private interface Api {
/**
* 获取某个用户的用户信息
@@ -1080,11 +1086,15 @@ public final class UserModel extends BaseModel implements IUserModel {
/**
* 编辑标签
*
* @return -
*/
@GET("/label/edit")
Single<ServiceResult<UserLabelInfo>> getUserLabelInfo();
/**
* 保存标签
*/
@POST("/label/save")
Single<ServiceResult<String>> saveLabel(@Query("labels") String labels);
}
}

View File

@@ -5,7 +5,8 @@ import java.io.Serializable
@Data
data class UserLabelInfo(
val config: List<UserLabelItemInfo> ?= null,
val groups: List<String>? = null,
val labels: List<UserLabelItemInfo>? = null,
val meLabels: List<String>? = null
) : Serializable

View File

@@ -5,8 +5,9 @@ import java.io.Serializable
@Data
data class UserLabelItemInfo(
val group: String = "",
val label: String = "",
val picked: Boolean = false
var picked: Boolean = false
) : Serializable