소스 검색

feat: 一些交互改动

DoggyZhang 3 달 전
부모
커밋
862104f685
97개의 변경된 파일2950개의 추가작업 그리고 722개의 파일을 삭제
  1. 3 3
      app/build.gradle
  2. 8 15
      app/src/main/java/com/adealink/weparty/commonui/widget/wheel/WheelDatePickerDialog.kt
  3. 1 1
      app/src/main/java/com/adealink/weparty/commonui/widget/wheel/WheelView.java
  4. 32 5
      app/src/main/java/com/adealink/weparty/module/playmate/widget/SoundView.kt
  5. 22 2
      app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData.kt
  6. 1 1
      app/src/main/java/com/adealink/weparty/util/PageHandler.kt
  7. 0 0
      app/src/main/res/drawable-xhdpi/common_add_picture_ic.png
  8. BIN
      app/src/main/res/drawable-xhdpi/common_female_ic.png
  9. BIN
      app/src/main/res/drawable-xhdpi/common_male_ic.png
  10. 0 0
      app/src/main/res/drawable-xhdpi/common_remove_picture_ic.png
  11. BIN
      app/src/main/res/drawable-xhdpi/common_sound_wave_ic.png
  12. 6 0
      app/src/main/res/drawable/common_date_picker_highlight_bg.xml
  13. 9 1
      app/src/main/res/layout/dialog_wheel_date_picker.xml
  14. 21 3
      app/src/main/res/layout/layout_sound_view.xml
  15. 124 119
      app/src/main/res/values/attrs.xml
  16. 1 0
      app/src/main/res/values/strings.xml
  17. 1 1
      module/playmate/src/main/java/com/adealink/weparty/playmate/comment/viewmodel/CommentViewModel.kt
  18. 68 24
      module/playmate/src/main/java/com/adealink/weparty/playmate/detail/comp/PlaymateToolBarViewComp.kt
  19. 6 0
      module/playmate/src/main/java/com/adealink/weparty/playmate/list/PlaymateListFragment.kt
  20. 1 1
      module/playmate/src/main/java/com/adealink/weparty/playmate/list/viewmodel/GuestPlaymateListViewModel.kt
  21. 1 1
      module/playmate/src/main/java/com/adealink/weparty/playmate/list/viewmodel/PlaymateListViewModel.kt
  22. BIN
      module/playmate/src/main/res/drawable-xhdpi/playmate_follow_ic.png
  23. BIN
      module/playmate/src/main/res/drawable-xhdpi/playmate_followed_ic.png
  24. BIN
      module/playmate/src/main/res/drawable-xhdpi/playmate_home_ic.png
  25. BIN
      module/playmate/src/main/res/drawable-xhdpi/playmate_more_ic.png
  26. 1 1
      module/playmate/src/main/res/layout/activity_playmate_detail.xml
  27. 45 6
      module/playmate/src/main/res/layout/layout_playmate_detail_top_bar.xml
  28. 9 1
      module/profile/src/main/java/com/adealink/weparty/profile/comp/ProfileHeaderComp.kt
  29. 130 63
      module/profile/src/main/java/com/adealink/weparty/profile/comp/ProfileToolBarViewComp.kt
  30. 14 7
      module/profile/src/main/java/com/adealink/weparty/profile/datasource/remote/FollowHttpService.kt
  31. 13 0
      module/profile/src/main/java/com/adealink/weparty/profile/datasource/remote/SearchHttpService.kt
  32. 30 73
      module/profile/src/main/java/com/adealink/weparty/profile/edit/EditProfileActivity.kt
  33. 43 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/adapter/AddPhotoItemViewBinder.kt
  34. 43 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/adapter/PhotoItemViewBinder.kt
  35. 0 77
      module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditAvatarViewComponent.kt
  36. 117 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditPersonComp.kt
  37. 127 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditPhotoWallComp.kt
  38. 37 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditTalentComp.kt
  39. 81 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/PhotoWallItemTouchHelperCallback.kt
  40. 41 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/data/EditData.kt
  41. 71 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditGenderDialog.kt
  42. 13 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditInterestDialog.kt
  43. 37 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditIntroDialog.kt
  44. 40 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditNickNameDialog.kt
  45. 71 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditTalentVoiceDialog.kt
  46. 4 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/SubmitVoiceFragment.kt
  47. 34 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/VoiceFragment.kt
  48. 19 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/viewmodel/EditVoiceViewModel.kt
  49. 81 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/viewmodel/EditProfileViewModel.kt
  50. 2 3
      module/profile/src/main/java/com/adealink/weparty/profile/me/MeFragment.kt
  51. 2 2
      module/profile/src/main/java/com/adealink/weparty/profile/relation/RelationShipActivity.kt
  52. 9 3
      module/profile/src/main/java/com/adealink/weparty/profile/relation/data/RelationShipData.kt
  53. 69 0
      module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/FollowViewModel.kt
  54. 0 43
      module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/RelationShipViewModel.kt
  55. 2 2
      module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/fans/FansFragment.kt
  56. 2 2
      module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/follow/FollowFragment.kt
  57. 39 7
      module/profile/src/main/java/com/adealink/weparty/profile/search/SearchActivity.kt
  58. 30 12
      module/profile/src/main/java/com/adealink/weparty/profile/search/adapter/SearchItemViewBinder.kt
  59. 38 7
      module/profile/src/main/java/com/adealink/weparty/profile/search/data/SearchData.kt
  60. 52 58
      module/profile/src/main/java/com/adealink/weparty/profile/search/viewmodel/SearchViewModel.kt
  61. 7 3
      module/profile/src/main/java/com/adealink/weparty/profile/viewmodel/ProfileViewModelFactory.kt
  62. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_add_photo_ic.png
  63. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_edit_ic.png
  64. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_edit_talent_voice_preview_ic.png
  65. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_edit_talent_voice_re_record_ic.png
  66. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_edit_talent_voice_record_ic.png
  67. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_edit_talent_voice_stop_ic.png
  68. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_me_edit_ic.png
  69. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_more_ic.png
  70. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_share_ic.png
  71. 6 0
      module/profile/src/main/res/drawable/profile_add_photo_bg.xml
  72. 6 0
      module/profile/src/main/res/drawable/profile_edit_button_bg.xml
  73. 2 6
      module/profile/src/main/res/drawable/profile_edit_gender_bg.xml
  74. 9 0
      module/profile/src/main/res/drawable/profile_edit_gender_selected_bg.xml
  75. 0 5
      module/profile/src/main/res/drawable/profile_follow_btn_bg_sel.xml
  76. 5 0
      module/profile/src/main/res/drawable/profile_top_bar_button_bg.xml
  77. 52 145
      module/profile/src/main/res/layout/activity_edit_profile.xml
  78. 1 1
      module/profile/src/main/res/layout/activity_user_profile.xml
  79. 65 0
      module/profile/src/main/res/layout/dialog_edit_birthday.xml
  80. 114 0
      module/profile/src/main/res/layout/dialog_edit_gender.xml
  81. 65 0
      module/profile/src/main/res/layout/dialog_edit_interest.xml
  82. 65 0
      module/profile/src/main/res/layout/dialog_edit_intro.xml
  83. 67 0
      module/profile/src/main/res/layout/dialog_edit_nickname.xml
  84. 30 0
      module/profile/src/main/res/layout/dialog_edit_talent_voice.xml
  85. 30 0
      module/profile/src/main/res/layout/fragment_edit_talent_voice.xml
  86. 157 0
      module/profile/src/main/res/layout/fragment_edit_talent_voice_submit.xml
  87. 48 0
      module/profile/src/main/res/layout/item_edit_profile_add_photo.xml
  88. 31 0
      module/profile/src/main/res/layout/item_edit_profile_photo.xml
  89. 287 0
      module/profile/src/main/res/layout/layout_edit_profile_person_info.xml
  90. 77 0
      module/profile/src/main/res/layout/layout_edit_profile_person_talent.xml
  91. 47 0
      module/profile/src/main/res/layout/layout_edit_profile_photo_wall.xml
  92. 2 2
      module/profile/src/main/res/layout/layout_profile_search_item.xml
  93. 94 9
      module/profile/src/main/res/layout/layout_user_profile_topbar.xml
  94. 30 0
      module/profile/src/main/res/values/strings.xml
  95. 0 5
      module/setting/src/main/java/com/adealink/weparty/setting/helpcenter/HelpCenterActivity.kt
  96. 1 1
      module/setting/src/main/res/layout/item_setting_help_add_picture.xml
  97. 1 1
      module/setting/src/main/res/layout/item_setting_help_picture.xml

+ 3 - 3
app/build.gradle

@@ -479,9 +479,9 @@ dependencies {
 
     implementation(libs.rangeseekbar)
 
-    implementation project(":tuicore")
-    implementation project(":timcommon")
-    implementation project(":tuichat")
+    api project(":tuicore")
+    api project(":timcommon")
+    api project(":tuichat")
     implementation project(":tuicontact")
     implementation project(":tuiconversation")
     implementation project(":tuisearch")

+ 8 - 15
app/src/main/java/com/adealink/weparty/commonui/widget/wheel/WheelDatePickerDialog.kt

@@ -2,29 +2,22 @@ package com.adealink.weparty.commonui.widget.wheel
 
 import android.os.Bundle
 import com.adealink.frame.aab.util.getCompatString
-import com.adealink.weparty.commonui.MIN_YEAR
-import com.adealink.weparty.R
-import com.adealink.frame.util.onClick
-import com.adealink.weparty.commonui.dialogfragment.data.DatePickerType
-import com.adealink.weparty.commonui.ext.show
-import com.adealink.weparty.commonui.widget.BottomDialogFragment
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.util.getBirthStr
+import com.adealink.frame.util.onClick
 import com.adealink.frame.util.timeToYMDHM
+import com.adealink.weparty.R
+import com.adealink.weparty.commonui.MIN_YEAR
+import com.adealink.weparty.commonui.dialogfragment.data.DatePickerType
 import com.adealink.weparty.commonui.dialogfragment.data.Month
+import com.adealink.weparty.commonui.ext.show
+import com.adealink.weparty.commonui.widget.BottomDialogFragment
 import com.adealink.weparty.databinding.DialogWheelDatePickerBinding
-import java.util.*
-import kotlin.collections.getOrNull
-import kotlin.collections.indexOfFirst
-import kotlin.collections.map
-import kotlin.jvm.java
-import kotlin.let
-import kotlin.ranges.until
-import kotlin.text.toInt
+import java.util.Calendar
+import java.util.Date
 
 /**
  * 日期选择控件;
- * Created by xuefu_du on 2021/6/23.
  */
 class WheelDatePickerDialog : BottomDialogFragment(R.layout.dialog_wheel_date_picker) {
 

+ 1 - 1
app/src/main/java/com/adealink/weparty/commonui/widget/wheel/WheelView.java

@@ -169,7 +169,7 @@ public class WheelView extends View {
     protected void onDraw(Canvas canvas) {
         drawHighlight(canvas);
         drawItems(canvas);
-        drawDivider(canvas);
+//        drawDivider(canvas);
     }
 
     private void drawItems(Canvas canvas) {

+ 32 - 5
app/src/main/java/com/adealink/weparty/module/playmate/widget/SoundView.kt

@@ -13,6 +13,7 @@ import android.view.animation.LinearInterpolator
 import android.view.animation.RotateAnimation
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.content.withStyledAttributes
+import androidx.core.view.updateLayoutParams
 import com.adealink.frame.base.IError
 import com.adealink.frame.download.listener.TaskListener
 import com.adealink.frame.download.task.Task
@@ -24,6 +25,8 @@ import com.adealink.frame.util.onClick
 import com.adealink.frame.util.runOnUiThread
 import com.adealink.weparty.App
 import com.adealink.weparty.R
+import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.databinding.LayoutSoundViewBinding
 import com.adealink.weparty.storage.file.FilePath.audioPath
 import com.adealink.weparty.util.getFilePathBy
@@ -37,10 +40,12 @@ class SoundView @JvmOverloads constructor(
 
     companion object {
         const val TAG = "SoundView"
-
         const val MSG_UPDATE_DURATION = 1
-
         const val MSG_UPDATE_PLAY_DURATION = 2
+
+
+        const val TEXT_GRAVITY_START = 0
+        const val TEXT_GRAVITY_END = 1
     }
 
     data class LoadSoundTask(
@@ -50,6 +55,7 @@ class SoundView @JvmOverloads constructor(
     private val binding = LayoutSoundViewBinding.inflate(LayoutInflater.from(context), this)
 
     private var durationTextSize = 12f
+    private var showWave: Boolean = false
 
     private var soundUrl: String? = null
     private var soundPath: String? = null
@@ -91,9 +97,7 @@ class SoundView @JvmOverloads constructor(
     }
 
     private fun initAttr(context: Context, attrs: AttributeSet? = null) {
-        if (isInEditMode) {
-            return
-        }
+        var textGravity: Int = TEXT_GRAVITY_START
         context.withStyledAttributes(
             attrs,
             R.styleable.SoundView
@@ -102,9 +106,32 @@ class SoundView @JvmOverloads constructor(
                 R.styleable.SoundView_sound_duration_text_size,
                 12f
             )
+            textGravity = getInt(
+                R.styleable.SoundView_sound_duration_text_gravity,
+                TEXT_GRAVITY_START
+            )
+            showWave = getBoolean(
+                R.styleable.SoundView_sound_show_wave,
+                false
+            )
         }
 
         binding.tvDuration.textSize = durationTextSize
+        if (showWave) {
+            binding.ivWave.show()
+        } else {
+            binding.ivWave.gone()
+        }
+
+        if (textGravity == TEXT_GRAVITY_START) {
+            binding.tvDuration.updateLayoutParams<LayoutParams> {
+                height = LayoutParams.WRAP_CONTENT
+            }
+        } else {
+            binding.tvDuration.updateLayoutParams<LayoutParams> {
+                height = 0
+            }
+        }
     }
 
     fun setSoundUrl(url: String?) {

+ 22 - 2
app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData.kt

@@ -1,6 +1,8 @@
 package com.adealink.weparty.module.profile.data
 
 import android.os.Parcelable
+import com.adealink.frame.aab.util.getCompatString
+import com.adealink.weparty.R
 import com.google.gson.annotations.GsonNullable
 import com.google.gson.annotations.Must
 import com.google.gson.annotations.SerializedName
@@ -11,6 +13,22 @@ enum class Gender(val gender: Int) {
     FEMALE(2), //女性
     MALE(1); //男性
 
+    fun getDesc(): String {
+        return when (this) {
+            UNKNOWN -> {
+                getCompatString(R.string.common_unknown)
+            }
+
+            MALE -> {
+                getCompatString(R.string.common_male)
+            }
+
+            FEMALE -> {
+                getCompatString(R.string.common_female)
+            }
+        }
+    }
+
     companion object {
 
         fun map(gender: Int?): Gender {
@@ -43,14 +61,16 @@ data class UserInfo(
     @GsonNullable
     @SerializedName("age") var age: Int? = null,
     @GsonNullable
-    @SerializedName("area") var area: String? = null,
+    @SerializedName("birthdayAt") var birthday: Long? = null,
     @GsonNullable
-    @SerializedName("cover") var cover: String? = null,
+    @SerializedName("area") var area: String? = null,
     @GsonNullable
     @SerializedName("gender") var gender: Int? = null,
     @GsonNullable
     @SerializedName("intro") var intro: String? = null, //用户简介
     @GsonNullable
+    @SerializedName("interest") var interest: List<String>? = null, //用户简介
+    @GsonNullable
     @SerializedName("photos") var photos: List<String>? = null, //照片
 
 

+ 1 - 1
app/src/main/java/com/adealink/weparty/util/PageHandler.kt

@@ -1,6 +1,6 @@
 package com.adealink.weparty.util
 
-class PageHandler(private val initialPage: String = "", val pageSize: Int = 10) {
+class PageHandler(private val initialPage: String = "", val pageSize: Int = 20) {
 
     var currentPage: String? = initialPage
         private set

+ 0 - 0
module/setting/src/main/res/drawable-xhdpi/setting_add_picture_ic.png → app/src/main/res/drawable-xhdpi/common_add_picture_ic.png


BIN
app/src/main/res/drawable-xhdpi/common_female_ic.png


BIN
app/src/main/res/drawable-xhdpi/common_male_ic.png


+ 0 - 0
module/setting/src/main/res/drawable-xhdpi/setting_help_remove_picture_ic.png → app/src/main/res/drawable-xhdpi/common_remove_picture_ic.png


BIN
app/src/main/res/drawable-xhdpi/common_sound_wave_ic.png


+ 6 - 0
app/src/main/res/drawable/common_date_picker_highlight_bg.xml

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

+ 9 - 1
app/src/main/res/layout/dialog_wheel_date_picker.xml

@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/common_bottom_dialog_bg"
@@ -22,6 +21,15 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
+    <View
+        android:layout_width="0dp"
+        android:layout_height="40dp"
+        android:background="@drawable/common_date_picker_highlight_bg"
+        app:layout_constraintBottom_toBottomOf="@id/bottom_barrier"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title" />
+
     <com.adealink.weparty.commonui.widget.wheel.Wheel3DView
         android:id="@+id/wheel_day"
         android:layout_width="0dp"

+ 21 - 3
app/src/main/res/layout/layout_sound_view.xml

@@ -15,26 +15,44 @@
         android:layout_marginStart="3dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintDimensionRatio="1:1"
-        app:layout_constraintEnd_toStartOf="@id/tv_price"
         app:layout_constraintHeight_percent="0.84"
-        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintHorizontal_bias="0"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/common_playmate_sound_pause_ic" />
 
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_wave"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginStart="6dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintDimensionRatio="185:110"
+        app:layout_constraintEnd_toStartOf="@id/tv_duration"
+        app:layout_constraintHeight_percent="0.35"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
+        app:layout_constraintStart_toEndOf="@id/btn_play"
+        app:layout_constraintTop_toTopOf="parent"
+        app:srcCompat="@drawable/common_sound_wave_ic"
+        tools:visibility="gone" />
+
     <androidx.appcompat.widget.AppCompatTextView
         android:id="@+id/tv_duration"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginStart="6dp"
         android:layout_marginEnd="12dp"
+        android:gravity="end"
         android:includeFontPadding="false"
         android:textColor="@color/white"
         android:textSize="12sp"
         app:fontFamily="@font/poppins_semibold"
+        app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@id/btn_play"
+        app:layout_constraintStart_toEndOf="@id/iv_wave"
         app:layout_constraintTop_toTopOf="parent"
         tools:text="1000" />
 

+ 124 - 119
app/src/main/res/values/attrs.xml

@@ -16,9 +16,9 @@
         <enum name="wrap_content" value="0" />
         <enum name="match_parent" value="1" />
     </attr>
-    <attr name="normal_text_size" format="dimension"/>
-    <attr name="selected_text_size" format="dimension"/>
-    <attr name="fixed_tab_scrollable_mode" format="boolean"/>
+    <attr name="normal_text_size" format="dimension" />
+    <attr name="selected_text_size" format="dimension" />
+    <attr name="fixed_tab_scrollable_mode" format="boolean" />
 
     <!-- 是否是强按钮(绿色)-->
     <attr name="item_margin" format="dimension" />
@@ -42,8 +42,8 @@
     <attr name="item_text_color" format="color" />
     <attr name="title_color" format="reference|color" />
     <attr name="bar_background" format="reference|color" />
-    <attr name="item_text_size" format="dimension"/>
-    <attr name="item_min_width" format="dimension"/>
+    <attr name="item_text_size" format="dimension" />
+    <attr name="item_min_width" format="dimension" />
     <attr name="shadowDx" format="float" />
     <attr name="shadowDy" format="float" />
     <attr name="shadowRadius" format="float" />
@@ -105,7 +105,7 @@
         <attr name="selected_text_size" />
         <attr name="indicator_color" format="color" />
         <attr name="indicator_drawable" format="reference" />
-        <attr name="indicator_width_mode" format="enum" >
+        <attr name="indicator_width_mode" format="enum">
             <enum name="match_parent" value="0" />
             <enum name="wrap_text" value="1" />
             <enum name="fixed" value="2" />
@@ -122,59 +122,59 @@
     </declare-styleable>
 
     <declare-styleable name="WheelView">
-        <attr name="wheelCyclic" format="boolean"/>
-        <attr name="wheelEntries" format="reference"/>
-        <attr name="wheelItemCount" format="integer"/>
-        <attr name="wheelItemWidth" format="dimension"/>
-        <attr name="wheelItemHeight" format="dimension"/>
-        <attr name="wheelTextSize" format="dimension"/>
-        <attr name="wheelTextColor" format="color"/>
-        <attr name="wheelSelectedTextColor" format="color"/>
-        <attr name="wheelDividerColor" format="color"/>
-        <attr name="wheelHighlightColor" format="color"/>
+        <attr name="wheelCyclic" format="boolean" />
+        <attr name="wheelEntries" format="reference" />
+        <attr name="wheelItemCount" format="integer" />
+        <attr name="wheelItemWidth" format="dimension" />
+        <attr name="wheelItemHeight" format="dimension" />
+        <attr name="wheelTextSize" format="dimension" />
+        <attr name="wheelTextColor" format="color" />
+        <attr name="wheelSelectedTextColor" format="color" />
+        <attr name="wheelDividerColor" format="color" />
+        <attr name="wheelHighlightColor" format="color" />
     </declare-styleable>
 
     <declare-styleable name="Wheel3DView">
         <attr name="wheelToward" format="enum">
-            <enum name="none" value="0"/>
-            <enum name="left" value="-1"/>
-            <enum name="right" value="1"/>
+            <enum name="none" value="0" />
+            <enum name="left" value="-1" />
+            <enum name="right" value="1" />
         </attr>
     </declare-styleable>
 
     <declare-styleable name="CircleProgressBar">
-        <attr name="line_count" format="integer"/>
-        <attr name="draw_progress_text" format="boolean"/>
-        <attr name="line_width" format="dimension|reference"/>
-        <attr name="background_color" format="color|reference"/>
-        <attr name="progress_start_color" format="color|reference"/>
-        <attr name="progress_end_color" format="color|reference"/>
-        <attr name="c_progress_text_color" format="color|reference"/>
-        <attr name="c_progress_text_size" format="dimension|reference"/>
-        <attr name="progress_stroke_width" format="dimension|reference"/>
-        <attr name="progress_background_color" format="color|reference"/>
-        <attr name="progress_text_format_pattern" format="string|reference"/>
-        <attr name="drawBackgroundOutsideProgress" format="boolean|reference"/>
-        <attr name="p_text_size" format="dimension|reference"/>
-        <attr name="p_text_color" format="color|reference"/>
-        <attr name="progress_start_degree" format="integer|reference"/>
+        <attr name="line_count" format="integer" />
+        <attr name="draw_progress_text" format="boolean" />
+        <attr name="line_width" format="dimension|reference" />
+        <attr name="background_color" format="color|reference" />
+        <attr name="progress_start_color" format="color|reference" />
+        <attr name="progress_end_color" format="color|reference" />
+        <attr name="c_progress_text_color" format="color|reference" />
+        <attr name="c_progress_text_size" format="dimension|reference" />
+        <attr name="progress_stroke_width" format="dimension|reference" />
+        <attr name="progress_background_color" format="color|reference" />
+        <attr name="progress_text_format_pattern" format="string|reference" />
+        <attr name="drawBackgroundOutsideProgress" format="boolean|reference" />
+        <attr name="p_text_size" format="dimension|reference" />
+        <attr name="p_text_color" format="color|reference" />
+        <attr name="progress_start_degree" format="integer|reference" />
 
         <attr name="style">
-            <enum name="line" value="0"/>
-            <enum name="solid" value="1"/>
-            <enum name="solid_line" value="2"/>
+            <enum name="line" value="0" />
+            <enum name="solid" value="1" />
+            <enum name="solid_line" value="2" />
         </attr>
 
         <attr name="progress_shader">
-            <enum name="linear" value="0"/>
-            <enum name="radial" value="1"/>
-            <enum name="sweep" value="2"/>
+            <enum name="linear" value="0" />
+            <enum name="radial" value="1" />
+            <enum name="sweep" value="2" />
         </attr>
 
         <attr name="progress_stroke_cap">
-            <enum name="butt" value="0"/>
-            <enum name="round" value="1"/>
-            <enum name="square" value="2"/>
+            <enum name="butt" value="0" />
+            <enum name="round" value="1" />
+            <enum name="square" value="2" />
         </attr>
     </declare-styleable>
 
@@ -200,22 +200,22 @@
         <attr name="banner_infinite_loop" format="boolean" />
 
         <!--RoundLinesIndicator、RectangleIndicator-->
-        <attr name="banner_indicator_height" format="dimension"/>
-        <attr name="banner_indicator_radius" format="dimension"/>
+        <attr name="banner_indicator_height" format="dimension" />
+        <attr name="banner_indicator_radius" format="dimension" />
 
         <!-- 以下为公用属性 -->
-        <attr name="banner_indicator_selected_width" format="dimension"/>
+        <attr name="banner_indicator_selected_width" format="dimension" />
         <!--CircleIndicator-->
-        <attr name="banner_indicator_normal_width" format="dimension"/>
-        <attr name="banner_indicator_space" format="dimension"/>
+        <attr name="banner_indicator_normal_width" format="dimension" />
+        <attr name="banner_indicator_space" format="dimension" />
 
-        <attr name="banner_indicator_normal_color" format="reference|color"/>
-        <attr name="banner_indicator_selected_color" format="reference|color"/>
-        <attr name="banner_indicator_margin" format="dimension"/>
-        <attr name="banner_indicator_marginLeft" format="dimension"/>
-        <attr name="banner_indicator_marginTop" format="dimension"/>
-        <attr name="banner_indicator_marginRight" format="dimension"/>
-        <attr name="banner_indicator_marginBottom" format="dimension"/>
+        <attr name="banner_indicator_normal_color" format="reference|color" />
+        <attr name="banner_indicator_selected_color" format="reference|color" />
+        <attr name="banner_indicator_margin" format="dimension" />
+        <attr name="banner_indicator_marginLeft" format="dimension" />
+        <attr name="banner_indicator_marginTop" format="dimension" />
+        <attr name="banner_indicator_marginRight" format="dimension" />
+        <attr name="banner_indicator_marginBottom" format="dimension" />
 
         <attr name="banner_indicator_gravity" format="enum">
             <enum name="left" value="0" />
@@ -228,21 +228,21 @@
             <enum name="vertical" value="1" />
         </attr>
 
-        <attr name="banner_radius" format="dimension"/>
+        <attr name="banner_radius" format="dimension" />
 
         <!--设置需要圆角的方向,不设置默认全部设置-->
-        <attr name="banner_round_top_left" format="boolean"/>
-        <attr name="banner_round_top_right" format="boolean"/>
-        <attr name="banner_round_bottom_left" format="boolean"/>
-        <attr name="banner_round_bottom_right" format="boolean"/>
+        <attr name="banner_round_top_left" format="boolean" />
+        <attr name="banner_round_top_right" format="boolean" />
+        <attr name="banner_round_bottom_left" format="boolean" />
+        <attr name="banner_round_bottom_right" format="boolean" />
 
         <attr name="banner_disallow_parent_intercept" format="boolean" />
 
     </declare-styleable>
 
     <declare-styleable name="DrawableIndicator">
-        <attr name="normal_drawable" format="reference"/>
-        <attr name="selected_drawable" format="reference"/>
+        <attr name="normal_drawable" format="reference" />
+        <attr name="selected_drawable" format="reference" />
     </declare-styleable>
 
     <declare-styleable name="PinField">
@@ -256,11 +256,11 @@
         <attr name="isCursorEnabled" format="boolean" />
         <!--Single Field Mode is deprecated use highlight type to define how to highlight the fields-->
         <attr name="highlightSingleFieldMode" format="boolean" />
-        <attr name="highlightType" format="enum" >
-            <enum name="allFields" value="0"/>
-            <enum name="currentField" value="1"/>
-            <enum name="completedFields" value="2"/>
-            <enum name="noFields" value="3"/>
+        <attr name="highlightType" format="enum">
+            <enum name="allFields" value="0" />
+            <enum name="currentField" value="1" />
+            <enum name="completedFields" value="2" />
+            <enum name="noFields" value="3" />
         </attr>
         <attr name="fieldBgColor" format="color" />
     </declare-styleable>
@@ -329,16 +329,16 @@
 
     <!--圆角约束布局-->
     <declare-styleable name="RoundCornerConstraintLayout">
-        <attr name="constraint_layout_clip_background" format="boolean"/>
-        <attr name="constraint_layout_round_corner" format="dimension"/>
-        <attr name="constraint_layout_round_corner_top_left" format="dimension"/>
-        <attr name="constraint_layout_round_corner_top_right" format="dimension"/>
-        <attr name="constraint_layout_round_corner_bottom_left" format="dimension"/>
-        <attr name="constraint_layout_round_corner_bottom_right" format="dimension"/>
+        <attr name="constraint_layout_clip_background" format="boolean" />
+        <attr name="constraint_layout_round_corner" format="dimension" />
+        <attr name="constraint_layout_round_corner_top_left" format="dimension" />
+        <attr name="constraint_layout_round_corner_top_right" format="dimension" />
+        <attr name="constraint_layout_round_corner_bottom_left" format="dimension" />
+        <attr name="constraint_layout_round_corner_bottom_right" format="dimension" />
     </declare-styleable>
 
     <declare-styleable name="AutoMarqueeTextView">
-        <attr name="delayMarqueeTime" format="integer"/>
+        <attr name="delayMarqueeTime" format="integer" />
     </declare-styleable>
 
     <declare-styleable name="SinWaveProgressBar">
@@ -351,11 +351,11 @@
 
     <attr name="stroke_width" format="dimension" />
     <attr name="font_weight" format="enum">
-        <enum name="regular" value="400"/>
-        <enum name="medium" value="500"/>
-        <enum name="semiBold" value="600"/>
-        <enum name="bold" value="700"/>
-        <enum name="extraBold" value="800"/>
+        <enum name="regular" value="400" />
+        <enum name="medium" value="500" />
+        <enum name="semiBold" value="600" />
+        <enum name="bold" value="700" />
+        <enum name="extraBold" value="800" />
     </attr>
 
     <attr name="strokeColor" format="color" />
@@ -408,7 +408,7 @@
         <attr name="stroke_colors" format="string" />
         <attr name="stroke_position" format="string" />
 
-        <attr name="gradient_orientation" format="enum" >
+        <attr name="gradient_orientation" format="enum">
             <enum name="vertical" value="0" />
             <enum name="horizontal" value="1" />
         </attr>
@@ -524,48 +524,48 @@
     </declare-styleable>
 
     <declare-styleable name="BubbleSeekBar">
-        <attr name="bsb_min" format="float|reference"/> <!--min < max, default: 0.0f-->
-        <attr name="bsb_max" format="float|reference"/> <!--min < max, default: 100.0f-->
-        <attr name="bsb_progress" format="float|reference"/> <!--real time progress value, default: min-->
-        <attr name="bsb_is_float_type" format="boolean"/> <!--support for float type-->
-        <attr name="bsb_track_size" format="dimension|reference"/> <!--height of right-track(on the right of thumb), default: 2dp-->
+        <attr name="bsb_min" format="float|reference" /> <!--min < max, default: 0.0f-->
+        <attr name="bsb_max" format="float|reference" /> <!--min < max, default: 100.0f-->
+        <attr name="bsb_progress" format="float|reference" /> <!--real time progress value, default: min-->
+        <attr name="bsb_is_float_type" format="boolean" /> <!--support for float type-->
+        <attr name="bsb_track_size" format="dimension|reference" /> <!--height of right-track(on the right of thumb), default: 2dp-->
         <!--height of left-track(on the left of thumb), default: 2dp higher than right-track's height-->
-        <attr name="bsb_second_track_size" format="dimension|reference"/>
-        <attr name="bsb_thumb_radius" format="dimension|reference"/> <!--radius of thumb, default: 2dp higher than left-track's height-->
+        <attr name="bsb_second_track_size" format="dimension|reference" />
+        <attr name="bsb_thumb_radius" format="dimension|reference" /> <!--radius of thumb, default: 2dp higher than left-track's height-->
         <!--radius of thumb when be dragging, default: 2 times of left-track's height-->
-        <attr name="bsb_thumb_radius_on_dragging" format="dimension|reference"/>
-        <attr name="bsb_track_color" format="color|reference"/> <!--color of right-track, default: R.color.colorPrimary-->
-        <attr name="bsb_second_track_color" format="color|reference"/> <!--color of left-track, default: R.color.colorAccent-->
-        <attr name="bsb_thumb_color" format="color|reference"/> <!--color of thumb, default: same as left-track's color-->
-        <attr name="bsb_section_count" format="integer|reference"/> <!--shares of whole progress(max - min), default: 10-->
-        <attr name="bsb_show_section_mark" format="boolean"/> <!--show demarcation points or not, default: false-->
-        <attr name="bsb_auto_adjust_section_mark" format="boolean"/> <!--auto scroll to the nearest section_mark or not, default: false-->
-        <attr name="bsb_show_section_text" format="boolean"/> <!--show section-text or not, default: false-->
-        <attr name="bsb_section_text_size" format="dimension|reference"/> <!--text size of section-text, default: 14sp-->
-        <attr name="bsb_section_text_color" format="color|reference"/> <!--text color of section-text, default: same as right-track's color-->
+        <attr name="bsb_thumb_radius_on_dragging" format="dimension|reference" />
+        <attr name="bsb_track_color" format="color|reference" /> <!--color of right-track, default: R.color.colorPrimary-->
+        <attr name="bsb_second_track_color" format="color|reference" /> <!--color of left-track, default: R.color.colorAccent-->
+        <attr name="bsb_thumb_color" format="color|reference" /> <!--color of thumb, default: same as left-track's color-->
+        <attr name="bsb_section_count" format="integer|reference" /> <!--shares of whole progress(max - min), default: 10-->
+        <attr name="bsb_show_section_mark" format="boolean" /> <!--show demarcation points or not, default: false-->
+        <attr name="bsb_auto_adjust_section_mark" format="boolean" /> <!--auto scroll to the nearest section_mark or not, default: false-->
+        <attr name="bsb_show_section_text" format="boolean" /> <!--show section-text or not, default: false-->
+        <attr name="bsb_section_text_size" format="dimension|reference" /> <!--text size of section-text, default: 14sp-->
+        <attr name="bsb_section_text_color" format="color|reference" /> <!--text color of section-text, default: same as right-track's color-->
         <!--text position of section-text relative to track, sides, bottom_sides, below_section_mark, default: sides-->
         <attr name="bsb_section_text_position">
-            <enum name="sides" value="0"/>
-            <enum name="bottom_sides" value="1"/>
-            <enum name="below_section_mark" value="2"/>
+            <enum name="sides" value="0" />
+            <enum name="bottom_sides" value="1" />
+            <enum name="below_section_mark" value="2" />
         </attr>
-        <attr name="bsb_section_text_interval" format="integer"/> <!--the interval of two section-text, default: 1-->
-        <attr name="bsb_show_thumb_text" format="boolean"/> <!--show real time progress-text under thumb or not, default: false-->
-        <attr name="bsb_thumb_text_size" format="dimension|reference"/> <!--text size of progress-text, default: 14sp-->
-        <attr name="bsb_thumb_text_color" format="color|reference"/> <!--text color of progress-text, default: same as left-track's color-->
-        <attr name="bsb_show_progress_in_float" format="boolean"/> <!--show bubble-progress in float or not, default: false-->
-        <attr name="bsb_touch_to_seek" format="boolean"/> <!--touch anywhere on track to quickly seek, default: false-->
-        <attr name="bsb_seek_step_section" format="boolean"/> <!--seek one step by one section, the progress is discrete, default: false-->
-        <attr name="bsb_seek_by_section" format="boolean"/> <!--seek by section, the progress may not be linear, default: false-->
-        <attr name="bsb_bubble_color" format="color|reference"/> <!--color of bubble, default: same as left-track's color-->
-        <attr name="bsb_bubble_text_size" format="dimension|reference"/> <!--text size of bubble-progress, default: 14sp-->
-        <attr name="bsb_bubble_text_color" format="color|reference"/> <!--text color of bubble-progress, default: #ffffffff-->
-        <attr name="bsb_anim_duration" format="integer"/> <!--duration of animation, default: 200ms-->
-        <attr name="bsb_always_show_bubble" format="boolean"/> <!--bubble shows all time, default: false-->
-        <attr name="bsb_always_show_bubble_delay" format="integer"/> <!--the delay duration before bubble shows all the time, default: 200ms-->
-        <attr name="bsb_hide_bubble" format="boolean"/> <!--hide bubble, default: false-->
-        <attr name="bsb_rtl" format="boolean"/> <!--right to left, default: false-->
-        <attr name="android:enabled"/>
+        <attr name="bsb_section_text_interval" format="integer" /> <!--the interval of two section-text, default: 1-->
+        <attr name="bsb_show_thumb_text" format="boolean" /> <!--show real time progress-text under thumb or not, default: false-->
+        <attr name="bsb_thumb_text_size" format="dimension|reference" /> <!--text size of progress-text, default: 14sp-->
+        <attr name="bsb_thumb_text_color" format="color|reference" /> <!--text color of progress-text, default: same as left-track's color-->
+        <attr name="bsb_show_progress_in_float" format="boolean" /> <!--show bubble-progress in float or not, default: false-->
+        <attr name="bsb_touch_to_seek" format="boolean" /> <!--touch anywhere on track to quickly seek, default: false-->
+        <attr name="bsb_seek_step_section" format="boolean" /> <!--seek one step by one section, the progress is discrete, default: false-->
+        <attr name="bsb_seek_by_section" format="boolean" /> <!--seek by section, the progress may not be linear, default: false-->
+        <attr name="bsb_bubble_color" format="color|reference" /> <!--color of bubble, default: same as left-track's color-->
+        <attr name="bsb_bubble_text_size" format="dimension|reference" /> <!--text size of bubble-progress, default: 14sp-->
+        <attr name="bsb_bubble_text_color" format="color|reference" /> <!--text color of bubble-progress, default: #ffffffff-->
+        <attr name="bsb_anim_duration" format="integer" /> <!--duration of animation, default: 200ms-->
+        <attr name="bsb_always_show_bubble" format="boolean" /> <!--bubble shows all time, default: false-->
+        <attr name="bsb_always_show_bubble_delay" format="integer" /> <!--the delay duration before bubble shows all the time, default: 200ms-->
+        <attr name="bsb_hide_bubble" format="boolean" /> <!--hide bubble, default: false-->
+        <attr name="bsb_rtl" format="boolean" /> <!--right to left, default: false-->
+        <attr name="android:enabled" />
     </declare-styleable>
 
     <declare-styleable name="CircleProgressButtonView">
@@ -577,7 +577,7 @@
 
     <declare-styleable name="RoundShadowLayout">
         <attr name="shadow_color" />
-        <attr name="shadow_radius"/>
+        <attr name="shadow_radius" />
         <attr name="round_radius" format="dimension" />
     </declare-styleable>
 
@@ -601,6 +601,11 @@
 
     <declare-styleable name="SoundView">
         <attr name="sound_duration_text_size" format="dimension" />
+        <attr name="sound_duration_text_gravity">
+            <enum name="start" value="0" />
+            <enum name="end" value="1" />
+        </attr>
+        <attr name="sound_show_wave" format="boolean" />
     </declare-styleable>
 
     <declare-styleable name="SoundWaveView">
@@ -611,6 +616,6 @@
     </declare-styleable>
 
     <declare-styleable name="BlurView">
-        <attr name="blurOverlayColor" format="color"/>
+        <attr name="blurOverlayColor" format="color" />
     </declare-styleable>
 </resources>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -70,6 +70,7 @@
     <string name="common_edit">Edit</string>
     <string name="common_function_block">Your account has %1$s category, this function will be back to normal use within %2$s</string>
     <string name="common_tags">Tags</string>
+    <string name="common_unknown">Unknown</string>
     <string name="common_female">Female</string>
     <string name="common_male">Male</string>
     <string name="common_retry">Retry</string>

+ 1 - 1
module/playmate/src/main/java/com/adealink/weparty/playmate/comment/viewmodel/CommentViewModel.kt

@@ -25,7 +25,7 @@ class CommentViewModel : BaseViewModel() {
     val labelList = mutableListOf<PlaymateCommentLabel>()
     val commentList = mutableListOf<PlaymateCommentData>()
     val commentListLD = MutableLiveData<Rlt<List<BasePlaymateDetailItem>>>()
-    private val pageHandler = PageHandler(pageSize = 20)
+    private val pageHandler = PageHandler()
 
     private var uid: String? = null
     private var categoryCode: String? = null

+ 68 - 24
module/playmate/src/main/java/com/adealink/weparty/playmate/detail/comp/PlaymateToolBarViewComp.kt

@@ -38,6 +38,9 @@ class PlaymateToolBarViewComp(
     private val detailViewModel by activityViewModels<PlaymateDetailViewModel> { PlaymateViewModelFactory() }
     private var uid: String? = null
     private var isFollow: Boolean = false
+
+    private var buttonIconColor = 0
+
     override fun onCreate() {
         super.onCreate()
         initView()
@@ -50,8 +53,8 @@ class PlaymateToolBarViewComp(
         val statusBarHeight = activity.statusBarHeight()
         val topbarHeight =
             statusBarHeight + getCompatDimension(APP_R.dimen.common_top_bar_height).toInt()
-        binding.topBarContainer.root.setPadding(16.dp(), statusBarHeight, 16.dp(), 0)
-        binding.topBarContainer.root.updateLayoutParams<MarginLayoutParams> {
+        binding.topBar.root.setPadding(16.dp(), statusBarHeight, 16.dp(), 0)
+        binding.topBar.root.updateLayoutParams<MarginLayoutParams> {
             height = topbarHeight
         }
         binding.collapsingToolbarLayout.minimumHeight = topbarHeight
@@ -60,7 +63,23 @@ class PlaymateToolBarViewComp(
         val fromColor = "#00FFFFFF".toColorInt()
         val toColor = "#FFFFFFFF".toColorInt()
         val topBarDrawable = ColorDrawable(fromColor)
-        binding.topBarContainer.root.background = topBarDrawable
+        binding.topBar.root.background = topBarDrawable
+
+        //顶部栏按钮背景
+        val buttonBgFromColor = "#66000000".toColorInt()
+        val buttonBgToColor = "#00000000".toColorInt()
+        val buttonBgDrawable = GradientDrawable().apply {
+            shape = GradientDrawable.OVAL
+            setColor(buttonBgFromColor)
+        }
+        binding.topBar.btnFollow.background = buttonBgDrawable
+        binding.topBar.btnHome.background = buttonBgDrawable
+        binding.topBar.btnMore.background = buttonBgDrawable
+
+        //按钮图标颜色
+        val buttonIconFromColor = "#FFFFFFFF".toColorInt()
+        val buttonIconToColor = "#FF000000".toColorInt()
+        buttonIconColor = buttonIconFromColor
 
         //内容背景
         val fromRadius = 20.dpf()
@@ -86,37 +105,59 @@ class PlaymateToolBarViewComp(
             val percent =
                 (abs(verticalOffset) * 1f / (appBarLayout.totalScrollRange)).coerceIn(0F, 1F)
 
-            val color = ArgbEvaluator().evaluate(percent, fromColor, toColor) as Int
-            topBarDrawable.color = color
+            //顶部栏背景
+            run {
+                val color = ArgbEvaluator().evaluate(percent, fromColor, toColor) as Int
+                topBarDrawable.color = color
+            }
 
-            val radius = fromRadius + (toRadius - fromRadius) * percent
-            contentDrawable.cornerRadii = floatArrayOf(
-                radius, radius, //top-left
-                radius, radius, //top-right
-                0f, 0f, //bottom-left
-                0f, 0f //bottom-right
-            )
+            //顶部栏按钮
+            run {
+                val color =
+                    ArgbEvaluator().evaluate(percent, buttonBgFromColor, buttonBgToColor) as Int
+                buttonBgDrawable.setColor(color)
+
+                buttonIconColor =
+                    ArgbEvaluator().evaluate(percent, buttonIconFromColor, buttonIconToColor) as Int
+                binding.topBar.btnBack.drawable?.setTint(buttonIconColor)
+                binding.topBar.btnFollow.drawable?.setTint(buttonIconColor)
+                binding.topBar.btnHome.drawable?.setTint(buttonIconColor)
+                binding.topBar.btnMore.drawable?.setTint(buttonIconColor)
+            }
 
-            if (percent >= 0.5f) {
-                binding.topBarContainer.ivBack.setImageResource(APP_R.drawable.commonui_back_black_48_ic)
-                QMUIStatusBarHelper.setStatusBarLightMode(activity)
-            } else {
-                binding.topBarContainer.ivBack.setImageResource(APP_R.drawable.commonui_back_white_48_ic)
-                QMUIStatusBarHelper.setStatusBarDarkMode(activity)
+            //主体内容圆角变直角
+            run {
+                val radius = fromRadius + (toRadius - fromRadius) * percent
+                contentDrawable.cornerRadii = floatArrayOf(
+                    radius, radius, //top-left
+                    radius, radius, //top-right
+                    0f, 0f, //bottom-left
+                    0f, 0f //bottom-right
+                )
+            }
+
+            run {
+                binding.topBar.ivAvatar.alpha = percent
+                binding.topBar.tvUserName.alpha = percent
+                if (percent >= 0.5f) {
+                    QMUIStatusBarHelper.setStatusBarLightMode(activity)
+                } else {
+                    QMUIStatusBarHelper.setStatusBarDarkMode(activity)
+                }
             }
 
         })
 
-        binding.topBarContainer.ivBack.onClick {
+        binding.topBar.btnBack.onClick {
             activity.finish()
         }
-        binding.topBarContainer.ivFollow.onClick {
+        binding.topBar.btnFollow.onClick {
             clickFollow()
         }
-        binding.topBarContainer.ivHome.onClick {
+        binding.topBar.btnHome.onClick {
             goProfile()
         }
-        binding.topBarContainer.ivMore.onClick {
+        binding.topBar.btnMore.onClick {
             clickMore()
         }
 
@@ -125,6 +166,8 @@ class PlaymateToolBarViewComp(
     private fun observeViewModel() {
         detailViewModel.detailLD.observe(viewLifecycleOwner) {
             this@PlaymateToolBarViewComp.uid = it?.uid
+            binding.topBar.ivAvatar.setImageUrl(it?.avatar)
+            binding.topBar.tvUserName.text = it?.nickname
         }
     }
 
@@ -143,10 +186,11 @@ class PlaymateToolBarViewComp(
     private fun clickFollow() {
         isFollow = !isFollow
         if (isFollow) {
-            binding.topBarContainer.ivFollow.setImageResource(R.drawable.playmate_followed_ic)
+            binding.topBar.btnFollow.setImageResource(R.drawable.playmate_followed_ic)
         } else {
-            binding.topBarContainer.ivFollow.setImageResource(R.drawable.playmate_follow_ic)
+            binding.topBar.btnFollow.setImageResource(R.drawable.playmate_follow_ic)
         }
+        binding.topBar.btnFollow.drawable?.setTint(buttonIconColor)
     }
 
     private fun clickMore() {

+ 6 - 0
module/playmate/src/main/java/com/adealink/weparty/playmate/list/PlaymateListFragment.kt

@@ -37,6 +37,7 @@ import com.adealink.weparty.ui.main.viewmodel.MainPageViewModel
 import com.adealink.weparty.viewmodel.parentFragmentViewModels
 import com.scwang.smart.refresh.layout.api.RefreshLayout
 import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
+import com.tencent.qcloud.tuikit.tuichat.component.audio.AudioPlayer
 
 @RouterUri(path = [Playmate.List.PATH], desc = "陪玩列表")
 class PlaymateListFragment : BaseFragment(R.layout.fragment_playmate_list),
@@ -63,6 +64,11 @@ class PlaymateListFragment : BaseFragment(R.layout.fragment_playmate_list),
         Router.bind(this)
     }
 
+    override fun onPause() {
+        super.onPause()
+        AudioPlayer.getInstance().stopPlay()
+    }
+
     override fun initViews() {
         super.initViews()
         if (category == null) {

+ 1 - 1
module/playmate/src/main/java/com/adealink/weparty/playmate/list/viewmodel/GuestPlaymateListViewModel.kt

@@ -23,7 +23,7 @@ class GuestPlaymateListViewModel : BaseViewModel() {
          * 利用缓存数据,提升路畅
          */
         private val playmateList = mutableListOf<PlaymateListData>()
-        private val pageHandler = PageHandler(pageSize = 20)
+        private val pageHandler = PageHandler()
     }
 
     private val playmateHttpService by lazy {

+ 1 - 1
module/playmate/src/main/java/com/adealink/weparty/playmate/list/viewmodel/PlaymateListViewModel.kt

@@ -26,7 +26,7 @@ class PlaymateListViewModel : BaseViewModel() {
     val listRltLD = ExtMutableLiveData<Rlt<Any>>()
 
     private var categoryCode: String? = null
-    private val pageHandler = PageHandler(pageSize = 20)
+    private val pageHandler = PageHandler()
 
     val starRankLD = ExtMutableLiveData<PlaymateListStarSort>()
 

BIN
module/playmate/src/main/res/drawable-xhdpi/playmate_follow_ic.png


BIN
module/playmate/src/main/res/drawable-xhdpi/playmate_followed_ic.png


BIN
module/playmate/src/main/res/drawable-xhdpi/playmate_home_ic.png


BIN
module/playmate/src/main/res/drawable-xhdpi/playmate_more_ic.png


+ 1 - 1
module/playmate/src/main/res/layout/activity_playmate_detail.xml

@@ -43,7 +43,7 @@
         app:layout_behavior="@string/appbar_scrolling_view_behavior" />
 
     <include
-        android:id="@+id/topBarContainer"
+        android:id="@+id/top_bar"
         layout="@layout/layout_playmate_detail_top_bar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/common_top_bar_height"

+ 45 - 6
module/playmate/src/main/res/layout/layout_playmate_detail_top_bar.xml

@@ -3,10 +3,11 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="@dimen/common_top_bar_height"
+    xmlns:tools="http://schemas.android.com/tools"
     android:paddingHorizontal="16dp">
 
     <androidx.appcompat.widget.AppCompatImageView
-        android:id="@+id/iv_back"
+        android:id="@+id/btn_back"
         android:layout_width="24dp"
         android:layout_height="24dp"
         app:layout_constraintBottom_toBottomOf="parent"
@@ -14,30 +15,68 @@
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/commonui_back_white_48_ic" />
 
+    <com.adealink.weparty.commonui.imageview.AvatarView
+        android:id="@+id/iv_avatar"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_marginStart="12dp"
+        android:alpha="0"
+        app:layout_constraintBottom_toBottomOf="@id/btn_back"
+        app:layout_constraintStart_toEndOf="@id/btn_back"
+        app:layout_constraintTop_toTopOf="@id/btn_back"
+        tools:alpha="1" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_user_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="12dp"
+        android:alpha="0"
+        android:ellipsize="end"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="start|center_vertical"
+        android:includeFontPadding="false"
+        android:singleLine="true"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="15sp"
+        app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
+        app:layout_constraintEnd_toStartOf="@id/btn_follow"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintStart_toEndOf="@id/iv_avatar"
+        app:layout_constraintTop_toTopOf="@id/iv_avatar"
+        tools:alpha="1"
+        tools:text="HelloWorld"
+        tools:visibility="visible" />
+
+
     <androidx.appcompat.widget.AppCompatImageView
-        android:id="@+id/iv_follow"
+        android:id="@+id/btn_follow"
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_marginEnd="14dp"
+        android:padding="4dp"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/iv_home"
+        app:layout_constraintEnd_toStartOf="@id/btn_home"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/playmate_follow_ic" />
 
     <androidx.appcompat.widget.AppCompatImageView
-        android:id="@+id/iv_home"
+        android:id="@+id/btn_home"
         android:layout_width="32dp"
         android:layout_height="32dp"
         android:layout_marginEnd="14dp"
+        android:padding="4dp"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/iv_more"
+        app:layout_constraintEnd_toStartOf="@id/btn_more"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/playmate_home_ic" />
 
     <androidx.appcompat.widget.AppCompatImageView
-        android:id="@+id/iv_more"
+        android:id="@+id/btn_more"
         android:layout_width="32dp"
         android:layout_height="32dp"
+        android:padding="4dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toTopOf="parent"

+ 9 - 1
module/profile/src/main/java/com/adealink/weparty/profile/comp/ProfileHeaderComp.kt

@@ -3,6 +3,7 @@ package com.adealink.weparty.profile.comp
 import android.annotation.SuppressLint
 import androidx.lifecycle.LifecycleOwner
 import com.adealink.frame.util.onClick
+import com.adealink.weparty.module.im.IMModule
 import com.adealink.weparty.module.profile.data.UserInfo
 import com.adealink.weparty.profile.databinding.LayoutUserProfileHeaderBinding
 import com.adealink.weparty.profile.dialog.EvaluateDialog
@@ -27,11 +28,18 @@ class ProfileHeaderComp(
 
     @SuppressLint("SetTextI18n")
     override fun updateUI(userInfo: UserInfo?) {
-        binding.ivBg.setImageUrl(userInfo?.cover)
+        binding.ivBg.setImageUrl(userInfo?.avatar)
         binding.tvName.text = userInfo?.nickName
         binding.tvUserId.text = "ID ${userInfo?.uid}"
 
         binding.vSound.setSoundUrl("")
+
+
+        binding.tvName.onClick {
+            val act = activity ?: return@onClick
+            val uid = profileViewModel.userInfoLD.value?.uid ?: return@onClick
+            IMModule.goSession(act, uid)
+        }
     }
 
     private fun showEvaluateDialog() {

+ 130 - 63
module/profile/src/main/java/com/adealink/weparty/profile/comp/ProfileToolBarViewComp.kt

@@ -11,14 +11,21 @@ import androidx.lifecycle.LifecycleOwner
 import com.adealink.frame.aab.util.getCompatDimension
 import com.adealink.frame.log.Log
 import com.adealink.frame.mvvm.view.ViewComponent
+import com.adealink.frame.mvvm.viewmodel.activityViewModels
+import com.adealink.frame.router.Router
 import com.adealink.frame.util.isActivityInValid
 import com.adealink.frame.util.onClick
 import com.adealink.frame.util.statusBarHeight
 import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.ext.dpf
+import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.show
+import com.adealink.weparty.module.profile.Profile
 import com.adealink.weparty.module.profile.ProfileModule
-import com.adealink.weparty.module.profile.data.UserInfo
+import com.adealink.weparty.module.share.Share
 import com.adealink.weparty.profile.databinding.ActivityUserProfileBinding
+import com.adealink.weparty.profile.viewmodel.ProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
 import com.google.android.material.appbar.AppBarLayout
 import com.qmuiteam.qmui.widget.util.QMUIStatusBarHelper
 import kotlin.math.abs
@@ -34,12 +41,13 @@ class ProfileToolBarViewComp(
         const val TAG = "ProfileToolBarViewComp"
     }
 
+    private val profileViewModel by activityViewModels<ProfileViewModel> { ProfileViewModelFactory() }
+
     private val isSelf: Boolean
         get() {
             return userUid == ProfileModule.getMyUid()
         }
 
-    private var userInfo: UserInfo? = null
     override fun onCreate() {
         super.onCreate()
         initView()
@@ -51,17 +59,46 @@ class ProfileToolBarViewComp(
         val statusBarHeight = activity.statusBarHeight()
         val topbarHeight =
             statusBarHeight + getCompatDimension(APP_R.dimen.common_top_bar_height).toInt()
-        binding.topBarContainer.root.setPadding(16.dp(), statusBarHeight, 16.dp(), 0)
-        binding.topBarContainer.root.updateLayoutParams<MarginLayoutParams> {
+        binding.topBar.root.setPadding(16.dp(), statusBarHeight, 16.dp(), 0)
+        binding.topBar.root.updateLayoutParams<MarginLayoutParams> {
             height = topbarHeight
         }
         binding.collapsingToolbarLayout.minimumHeight = topbarHeight
 
         //顶部栏背景
-        val fromColor = "#00FFFFFF".toColorInt()
-        val toColor = "#FFFFFFFF".toColorInt()
-        val topBarDrawable = ColorDrawable(fromColor)
-        binding.topBarContainer.root.background = topBarDrawable
+        val topbarFromColor = "#00FFFFFF".toColorInt()
+        val topbarToColor = "#FFFFFFFF".toColorInt()
+        val topBarDrawable = ColorDrawable(topbarFromColor)
+        binding.topBar.root.background = topBarDrawable
+
+        //顶部栏按钮背景
+        val buttonBgFromColor = "#66000000".toColorInt()
+        val buttonBgToColor = "#00000000".toColorInt()
+        val buttonBgDrawable = GradientDrawable().apply {
+            shape = GradientDrawable.OVAL
+            setColor(buttonBgFromColor)
+        }
+        binding.topBar.btnShare.background = buttonBgDrawable
+        binding.topBar.btnMore.background = buttonBgDrawable
+
+        //编辑按钮背景
+        val editButtonBgFromColor = "#66000000".toColorInt()
+        val editButtonBgToColor = "#00000000".toColorInt()
+        val editButtonBgDrawable = GradientDrawable().apply {
+            shape = GradientDrawable.RECTANGLE
+            setColor(editButtonBgFromColor)
+            cornerRadii = floatArrayOf(
+                20.dpf(), 20.dpf(), //top-left
+                20.dpf(), 20.dpf(), //top-right
+                20.dpf(), 20.dpf(), //bottom-left
+                20.dpf(), 20.dpf() //bottom-right
+            )
+        }
+        binding.topBar.btnEdit.background = editButtonBgDrawable
+
+        //按钮图标颜色
+        val buttonIconFromColor = "#FFFFFFFF".toColorInt()
+        val buttonIconToColor = "#FF000000".toColorInt()
 
         //内容背景
         val fromRadius = 20.dpf()
@@ -87,78 +124,108 @@ class ProfileToolBarViewComp(
             val percent =
                 (abs(verticalOffset) * 1f / (appBarLayout.totalScrollRange)).coerceIn(0F, 1F)
 
-            val color = ArgbEvaluator().evaluate(percent, fromColor, toColor) as Int
-            topBarDrawable.color = color
+            //顶部栏背景
+            run {
+                val color = ArgbEvaluator().evaluate(percent, topbarFromColor, topbarToColor) as Int
+                topBarDrawable.color = color
+            }
 
-            val radius = fromRadius + (toRadius - fromRadius) * percent
-            contentDrawable.cornerRadii = floatArrayOf(
-                radius, radius, //top-left
-                radius, radius, //top-right
-                0f, 0f, //bottom-left
-                0f, 0f //bottom-right
-            )
+            //顶部栏按钮背景
+            run {
+                val color =
+                    ArgbEvaluator().evaluate(percent, buttonBgFromColor, buttonBgToColor) as Int
+                buttonBgDrawable.setColor(color)
+            }
+
+            //顶部栏编辑按钮
+            run {
+                val color = ArgbEvaluator().evaluate(
+                    percent,
+                    editButtonBgFromColor,
+                    editButtonBgToColor
+                ) as Int
+                editButtonBgDrawable.setColor(color)
+            }
 
-            if (percent == 1f) {
-                binding.topBarContainer.ivBack.setImageResource(APP_R.drawable.commonui_back_black_48_ic)
-                QMUIStatusBarHelper.setStatusBarLightMode(activity)
-            } else {
-                binding.topBarContainer.ivBack.setImageResource(APP_R.drawable.commonui_back_white_48_ic)
-                QMUIStatusBarHelper.setStatusBarDarkMode(activity)
+            //顶部栏按钮图标
+            run {
+                val color =
+                    ArgbEvaluator().evaluate(percent, buttonIconFromColor, buttonIconToColor) as Int
+                binding.topBar.ivBack.drawable?.setTint(color)
+                binding.topBar.btnShare.drawable?.setTint(color)
+                binding.topBar.btnMore.drawable?.setTint(color)
+                binding.topBar.ivEdit.drawable?.setTint(color)
+                binding.topBar.tvEdit.setTextColor(color)
             }
 
+            //主体内容圆角变直角
+            run {
+                val radius = fromRadius + (toRadius - fromRadius) * percent
+                contentDrawable.cornerRadii = floatArrayOf(
+                    radius, radius, //top-left
+                    radius, radius, //top-right
+                    0f, 0f, //bottom-left
+                    0f, 0f //bottom-right
+                )
+            }
+
+            run {
+                binding.topBar.ivAvatar.alpha = percent
+                binding.topBar.tvUserName.alpha = percent
+                if (percent >= 0.85f) {
+                    QMUIStatusBarHelper.setStatusBarLightMode(activity)
+                } else {
+                    QMUIStatusBarHelper.setStatusBarDarkMode(activity)
+                }
+            }
         })
 
-        binding.topBarContainer.ivBack.onClick {
+        binding.topBar.ivBack.onClick {
             activity.finish()
         }
 
         if (isSelf) {
-//            binding.btnEdit.setBackgroundResource(R.drawable.profile_edit_icon)
-//            binding.btnEdit.onClick {
-//                Router.getRouterInstance<BaseDialogFragment>(Profile.EditProfileSelect.PATH)
-//                    ?.show(fragmentManager)
-//            }
-
+            binding.topBar.btnShare.show()
+            binding.topBar.btnShare.onClick {
+                goShare()
+            }
+            binding.topBar.btnMore.gone()
+            binding.topBar.btnEdit.show()
+            binding.topBar.btnEdit.onClick {
+                goEdit()
+            }
         } else {
-//            binding.btnEdit.setBackgroundResource(R.drawable.profile_more_icon)
-//            binding.btnEdit.setOnClickListener {
-//                val noteName = getDisplayName(userUid, "")
-//                UserProtectModule.showReportUserDialog(
-//                    userUid,
-//                    ReportFrom.USER_PROFILE,
-//                    ReportType.USER_INFO,
-//                    showNoteNicknameAction = false,
-//                    name = userInfo?.name ?: "",
-//                    noteName = noteName,
-//                    showSpecialFollowAction = false,
-//                    isSpecialFollowed = specialFollowed,
-//                    showUnFollowAction = isFollowed
-//                )
-//            }
+            binding.topBar.btnShare.gone()
+            binding.topBar.btnMore.show()
+            binding.topBar.btnMore.onClick {
+                clickMore()
+            }
+            binding.topBar.btnEdit.gone()
         }
     }
 
 
     private fun observeViewModel() {
-//        profileViewModel.uidUserInfoRltLD.observe(this) {
-//            when (it) {
-//                is Rlt.Success -> {
-//                    if (userUid == it.data.uid) {
-//                        userInfo = it.data
-//                        binding.tvTitle.text = getCompatString(
-//                            R.string.profile_personal_title, getDisplayName(
-//                                uid = userUid, originalName = userInfo?.name ?: ""
-//                            )
-//                        )
-//                    }
-//                }
-//
-//                is Rlt.Failed -> {
-//                    //ntd.
-//                }
-//            }
-//        }
+        profileViewModel.userInfoLD.observe(viewLifecycleOwner) { userInfo ->
+            binding.topBar.ivAvatar.setImageUrl(userInfo?.avatar)
+            binding.topBar.tvUserName.text = userInfo?.nickName
+        }
+    }
 
+    private fun goShare() {
+        activity?.let { act ->
+            Router.build(act, Share.Poster.PATH).start()
+        }
+    }
+
+    private fun clickMore() {
+
+    }
+
+    private fun goEdit() {
+        activity?.let { act ->
+            Router.build(act, Profile.EditProfile.PATH).start()
+        }
     }
 
 }

+ 14 - 7
module/profile/src/main/java/com/adealink/weparty/profile/datasource/remote/FollowHttpService.kt

@@ -2,25 +2,32 @@ package com.adealink.weparty.profile.datasource.remote
 
 import com.adealink.frame.base.Rlt
 import com.adealink.frame.network.data.Res
-import com.adealink.weparty.profile.relation.data.FansReq
-import com.adealink.weparty.profile.relation.data.FansRes
+import com.adealink.weparty.profile.relation.data.FansListReq
+import com.adealink.weparty.profile.relation.data.FansLlistRes
+import com.adealink.weparty.profile.relation.data.FollowListReq
+import com.adealink.weparty.profile.relation.data.FollowListRes
 import com.adealink.weparty.profile.relation.data.FollowReq
-import com.adealink.weparty.profile.relation.data.FollowRes
 import retrofit2.http.Body
 import retrofit2.http.POST
 
 interface FollowHttpService {
 
+    @POST("user/follow")
+    suspend fun follow(
+        @Body req: FollowReq
+    ): Rlt<Res<Any>>
+
+
     @POST("user/my/info/edit")
     suspend fun pullFollow(
-        @Body req: FollowReq
-    ): Rlt<Res<FollowRes>>
+        @Body req: FollowListReq
+    ): Rlt<Res<FollowListRes>>
 
 
     @POST("user/my/info/edit")
     suspend fun pullFans(
-        @Body req: FansReq
-    ): Rlt<Res<FansRes>>
+        @Body req: FansListReq
+    ): Rlt<Res<FansLlistRes>>
 
 
 }

+ 13 - 0
module/profile/src/main/java/com/adealink/weparty/profile/datasource/remote/SearchHttpService.kt

@@ -0,0 +1,13 @@
+package com.adealink.weparty.profile.datasource.remote
+
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.network.data.Res
+import com.adealink.weparty.profile.search.data.SearchReq
+import com.adealink.weparty.profile.search.data.SearchRes
+import retrofit2.http.Body
+import retrofit2.http.POST
+
+interface SearchHttpService {
+    @POST("playmate/search")
+    suspend fun search(@Body req: SearchReq): Rlt<Res<SearchRes>>
+}

+ 30 - 73
module/profile/src/main/java/com/adealink/weparty/profile/edit/EditProfileActivity.kt

@@ -3,27 +3,22 @@ package com.adealink.weparty.profile.edit
 import androidx.activity.viewModels
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.updateLayoutParams
-import com.adealink.frame.aab.util.getCompatColor
-import com.adealink.frame.aab.util.getCompatString
-import com.adealink.frame.base.Rlt
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.router.Router
 import com.adealink.frame.router.annotation.BindExtra
 import com.adealink.frame.router.annotation.RouterUri
+import com.adealink.frame.util.naviBarHeight
 import com.adealink.frame.util.onClick
 import com.adealink.frame.util.statusBarHeight
 import com.adealink.weparty.commonui.BaseActivity
-import com.adealink.weparty.commonui.toast.util.showFailedToast
-import com.adealink.weparty.commonui.toast.util.showToast
+import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.module.profile.Profile
-import com.adealink.weparty.module.profile.ProfileModule
-import com.adealink.weparty.module.profile.data.Gender
-import com.adealink.weparty.profile.R
 import com.adealink.weparty.profile.databinding.ActivityEditProfileBinding
-import com.adealink.weparty.profile.edit.comp.EditAvatarViewComponent
+import com.adealink.weparty.profile.edit.comp.EditPersonComp
+import com.adealink.weparty.profile.edit.comp.EditPhotoWallComp
+import com.adealink.weparty.profile.edit.viewmodel.EditProfileViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
-import com.adealink.weparty.R as APP_R
 
 @RouterUri(
     path = [Profile.EditProfile.PATH],
@@ -36,9 +31,7 @@ class EditProfileActivity : BaseActivity() {
 
     private val binding by viewBinding(ActivityEditProfileBinding::inflate)
     private val profileViewModel by viewModels<ProfileViewModel> { ProfileViewModelFactory() }
-    private var inputGender: Gender? = null
-
-    private lateinit var avatarComp: EditAvatarViewComponent
+    private val editViewModel by viewModels<EditProfileViewModel> { ProfileViewModelFactory() }
 
     override fun onBeforeCreate() {
         super.onBeforeCreate()
@@ -51,14 +44,9 @@ class EditProfileActivity : BaseActivity() {
         binding.topBar.updateLayoutParams<ConstraintLayout.LayoutParams> {
             topMargin = this@EditProfileActivity.statusBarHeight()
         }
-
-        binding.tvGenderMale.onClick {
-            selectGender(Gender.MALE)
-        }
-        binding.tvGenderFemale.onClick {
-            selectGender(Gender.FEMALE)
-        }
-
+        binding.clContent.setPadding(
+            16.dp(), 0, 16.dp(), naviBarHeight() + 24.dp()
+        )
         binding.btnSave.onClick {
             saveEdit()
         }
@@ -66,66 +54,35 @@ class EditProfileActivity : BaseActivity() {
 
     override fun initComponents() {
         super.initComponents()
-        EditAvatarViewComponent(this, binding.ivAvatar).also {
-            avatarComp = it
-        }.attach()
+        EditPhotoWallComp(this, binding.vPhotoWall).attach()
+        EditPersonComp(this, binding.vPersonInfo).attach()
+//        EditTalentComp(this, binding.vTalent).attach()
     }
 
     override fun loadData() {
         super.loadData()
-        val myUserInfo = ProfileModule.getMyUserInfo()
-        binding.ivAvatar.setImageUrl(myUserInfo?.avatar)
-        binding.etUserName.setText(myUserInfo?.nickName)
-        selectGender(Gender.map(myUserInfo?.gender))
-        binding.etUserAge.setText(myUserInfo?.age?.toString())
-    }
-
-    private fun selectGender(gender: Gender) {
-        inputGender = gender
-        when (gender) {
-            Gender.UNKNOWN -> {
-                binding.tvGenderMale.setTextColor(getCompatColor(APP_R.color.color_FFCDCFD9))
-                binding.tvGenderMale.setBackgroundResource(R.drawable.profile_edit_gender_unselect_bg)
-                binding.tvGenderFemale.setTextColor(getCompatColor(APP_R.color.color_FFCDCFD9))
-                binding.tvGenderFemale.setBackgroundResource(R.drawable.profile_edit_gender_unselect_bg)
-            }
-
-            Gender.MALE -> {
-                binding.tvGenderMale.setTextColor(getCompatColor(APP_R.color.white))
-                binding.tvGenderMale.setBackgroundResource(R.drawable.profile_edit_gender_select_bg)
-                binding.tvGenderFemale.setTextColor(getCompatColor(APP_R.color.color_FFCDCFD9))
-                binding.tvGenderFemale.setBackgroundResource(R.drawable.profile_edit_gender_unselect_bg)
-            }
-
-            Gender.FEMALE -> {
-                binding.tvGenderMale.setTextColor(getCompatColor(APP_R.color.color_FFCDCFD9))
-                binding.tvGenderMale.setBackgroundResource(R.drawable.profile_edit_gender_unselect_bg)
-                binding.tvGenderFemale.setTextColor(getCompatColor(APP_R.color.white))
-                binding.tvGenderFemale.setBackgroundResource(R.drawable.profile_edit_gender_select_bg)
-            }
-        }
     }
 
     private fun saveEdit() {
         showLoading()
-        profileViewModel.updateProfile(
-            newAvatarPath = avatarComp.getAvatarPath(),
-            newNickName = binding.etUserName.text?.toString(),
-            newGender = inputGender?.gender,
-            newBirthday = binding.etUserAge.text?.toString(),
-        ).observe(this) { rlt ->
-            dismissLoading()
-            when (rlt) {
-                is Rlt.Failed -> {
-                    showFailedToast(rlt)
-                }
-
-                is Rlt.Success<*> -> {
-                    showToast(getCompatString(APP_R.string.common_success))
-                    this@EditProfileActivity.finish()
-                }
-            }
-        }
+//        profileViewModel.updateProfile(
+//            newAvatarPath = avatarComp.getAvatarPath(),
+//            newNickName = binding.etUserName.text?.toString(),
+//            newGender = inputGender?.gender,
+//            newBirthday = binding.etUserAge.text?.toString(),
+//        ).observe(this) { rlt ->
+//            dismissLoading()
+//            when (rlt) {
+//                is Rlt.Failed -> {
+//                    showFailedToast(rlt)
+//                }
+//
+//                is Rlt.Success<*> -> {
+//                    showToast(getCompatString(APP_R.string.common_success))
+//                    this@EditProfileActivity.finish()
+//                }
+//            }
+//        }
     }
 
 }

+ 43 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/adapter/AddPhotoItemViewBinder.kt

@@ -0,0 +1,43 @@
+package com.adealink.weparty.profile.edit.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
+import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
+import com.adealink.weparty.profile.databinding.ItemEditProfileAddPhotoBinding
+import com.adealink.weparty.profile.edit.data.AddPhotoItemData
+
+
+class AddPhotoItemViewBinder(
+    val onItemClick: () -> Unit,
+) :
+    ItemViewBinder<AddPhotoItemData, AddPhotoItemViewBinder.ViewHolder>() {
+
+    override fun onBindViewHolder(
+        holder: ViewHolder,
+        item: AddPhotoItemData,
+    ) {
+        holder.binding.root.onClick {
+            onItemClick.invoke()
+        }
+        holder.binding.tvAddDesc.text = item.getPhotoDesc(holder.layoutPosition)
+    }
+
+    override fun onCreateViewHolder(
+        inflater: LayoutInflater,
+        parent: ViewGroup,
+    ): ViewHolder {
+        return ViewHolder(
+            ItemEditProfileAddPhotoBinding.inflate(
+                inflater,
+                parent,
+                false
+            )
+        )
+    }
+
+    class ViewHolder(
+        rootBinding: ItemEditProfileAddPhotoBinding,
+    ) : BindingViewHolder<ItemEditProfileAddPhotoBinding>(rootBinding)
+}

+ 43 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/adapter/PhotoItemViewBinder.kt

@@ -0,0 +1,43 @@
+package com.adealink.weparty.profile.edit.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
+import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
+import com.adealink.weparty.profile.databinding.ItemEditProfilePhotoBinding
+import com.adealink.weparty.profile.edit.data.PhotoItemData
+
+
+class PhotoItemViewBinder(
+    val onItemClick: (item: PhotoItemData) -> Unit,
+    val onDeleteClick: (item: PhotoItemData) -> Unit
+) :
+    ItemViewBinder<PhotoItemData, BindingViewHolder<ItemEditProfilePhotoBinding>>() {
+
+    override fun onBindViewHolder(
+        holder: BindingViewHolder<ItemEditProfilePhotoBinding>,
+        item: PhotoItemData,
+    ) {
+        holder.binding.root.onClick {
+            onItemClick.invoke(item)
+        }
+        holder.binding.ivDelete.onClick {
+            onDeleteClick.invoke(item)
+        }
+        holder.binding.ivPicture.setImageURI(item.data.uri)
+    }
+
+    override fun onCreateViewHolder(
+        inflater: LayoutInflater,
+        parent: ViewGroup,
+    ): BindingViewHolder<ItemEditProfilePhotoBinding> {
+        return BindingViewHolder(
+            ItemEditProfilePhotoBinding.inflate(
+                inflater,
+                parent,
+                false
+            )
+        )
+    }
+}

+ 0 - 77
module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditAvatarViewComponent.kt

@@ -1,77 +0,0 @@
-package com.adealink.weparty.profile.edit.comp
-
-import androidx.lifecycle.LifecycleOwner
-import com.adealink.frame.base.fastLazy
-import com.adealink.frame.mvvm.view.ViewComponent
-import com.adealink.frame.util.onClick
-import com.adealink.weparty.commonui.imageview.AvatarView
-import com.adealink.weparty.imageselect.SelectImageLifecycleObserver
-import com.adealink.weparty.imageselect.model.LocalMedia
-import com.adealink.weparty.imageselect.model.MediaType
-
-class EditAvatarViewComponent(
-    lifecycleOwner: LifecycleOwner,
-    private val ivAvatar: AvatarView
-) : ViewComponent(lifecycleOwner) {
-
-    companion object {
-        private const val SOURCE_TAG = "EditAvatarViewComponent"
-    }
-
-    private var avatarPath: String? = null
-    private val selectImageObserver: SelectImageLifecycleObserver by fastLazy {
-        object : SelectImageLifecycleObserver(requireActivity().activityResultRegistry) {
-
-            override fun onResult(
-                source: String,
-                resultCode: Int,
-                path: String?,
-                uri: String?,
-                mediaType: MediaType,
-                mediaInfos: List<LocalMedia>?,
-                fromPosition: Int?
-            ) {
-                onImageSelectResult(source, path, uri)
-            }
-
-        }
-    }
-
-    override fun onCreate() {
-        super.onCreate()
-        initView()
-    }
-
-    private fun initView() {
-        lifecycle.addObserver(selectImageObserver)
-        ivAvatar.onClick {
-            selectImageObserver.launch(
-                SOURCE_TAG,
-//                gifOpt = gifOpt,
-//                imageMinSize = imageMinSize,
-//                topTipsString = ImageSelectTopTips.gifAvatarTips()
-            )
-        }
-    }
-
-    private fun onImageSelectResult(source: String, path: String?, uri: String?) {
-        if (path.isNullOrEmpty() || uri.isNullOrEmpty()) {
-            return
-        }
-        when (source) {
-            SOURCE_TAG -> {
-                avatarPath = path
-                ivAvatar.setImageURI(uri)
-            }
-        }
-    }
-
-    fun isAvatarChanged(): Boolean {
-        return !avatarPath.isNullOrEmpty()
-    }
-
-    fun getAvatarPath(): String? {
-        return avatarPath
-    }
-
-}

+ 117 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditPersonComp.kt

@@ -0,0 +1,117 @@
+package com.adealink.weparty.profile.edit.comp
+
+import androidx.lifecycle.LifecycleOwner
+import com.adealink.frame.aab.util.getCompatString
+import com.adealink.frame.mvvm.view.ViewComponent
+import com.adealink.frame.mvvm.viewmodel.activityViewModels
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.widget.wheel.WheelDatePickerDialog
+import com.adealink.weparty.module.profile.data.Gender
+import com.adealink.weparty.profile.databinding.LayoutEditProfilePersonInfoBinding
+import com.adealink.weparty.profile.edit.dialog.EditGenderDialog
+import com.adealink.weparty.profile.edit.dialog.EditInterestDialog
+import com.adealink.weparty.profile.edit.dialog.EditIntroDialog
+import com.adealink.weparty.profile.edit.dialog.EditNickNameDialog
+import com.adealink.weparty.profile.edit.viewmodel.EditProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
+import com.adealink.weparty.util.formatTimeStr
+import com.adealink.weparty.R as APP_R
+
+class EditPersonComp(
+    lifecycleOwner: LifecycleOwner,
+    private val binging: LayoutEditProfilePersonInfoBinding
+) : ViewComponent(lifecycleOwner) {
+
+    companion object {
+        private const val SOURCE_TAG = "EditPersonComp"
+    }
+
+
+    private val profileViewModel by activityViewModels<ProfileViewModel> { ProfileViewModelFactory() }
+    private val editViewModel by activityViewModels<EditProfileViewModel> { ProfileViewModelFactory() }
+
+    override fun onCreate() {
+        super.onCreate()
+        initView()
+        observeViewModel()
+    }
+
+    private fun initView() {
+        binging.clNickname.onClick {
+            editNickName()
+        }
+        binging.clGender.onClick {
+            editGender()
+        }
+        binging.clBirthday.onClick {
+            editBirthday()
+        }
+        binging.clIntro.onClick {
+            editIntro()
+        }
+        binging.clInterest.onClick {
+            editInterest()
+        }
+    }
+
+    private fun observeViewModel() {
+        profileViewModel.userInfoLD.observe(viewLifecycleOwner) {
+            binging.tvNickname.text = it?.nickName
+            binging.tvGender.text = Gender.map(it?.gender).getDesc()
+            binging.tvBirthday.text = it?.birthday?.formatTimeStr()
+            binging.tvIntro.text = it?.intro
+            binging.tvInterest.text = it?.interest?.joinToString(separator = ",")
+        }
+    }
+
+    private fun editNickName() {
+        EditNickNameDialog().apply {
+            setCallback(object : EditNickNameDialog.IEditNameCallback {
+                override fun onEditName(name: String) {
+
+                }
+            })
+        }.show(fragmentManager, "editNickName")
+    }
+
+    private fun editGender() {
+        EditGenderDialog().apply {
+            setCallback(object : EditGenderDialog.IEditGenderCallback {
+                override fun onEditGender(gender: Gender) {
+
+                }
+            })
+        }.show(fragmentManager, "editGender")
+    }
+
+    private fun editBirthday() {
+        WheelDatePickerDialog.newInstance(
+            confirmButtonText = getCompatString(APP_R.string.common_save)
+        ).apply {
+            selectBirthdayCallback = object : WheelDatePickerDialog.ISelectDateCallback {
+                override fun onSelectComplete(timestamp: Long, timeStr: String) {
+                    //viewModel.selectBirthday(timestamp)
+                }
+            }
+        }.show(
+            fragmentManager, "editBirthday"
+        )
+    }
+
+    private fun editIntro() {
+        EditIntroDialog().apply {
+            setCallback(object : EditIntroDialog.IEditIntroCallback {
+                override fun onEditIntro(intro: String?) {
+                }
+            })
+        }.show(fragmentManager, "EditIntro")
+    }
+
+    private fun editInterest() {
+        EditInterestDialog().apply {
+
+        }.show(fragmentManager, "EditInterest")
+    }
+
+}

+ 127 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditPhotoWallComp.kt

@@ -0,0 +1,127 @@
+package com.adealink.weparty.profile.edit.comp
+
+import androidx.lifecycle.LifecycleOwner
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.ItemTouchHelper
+import com.adealink.frame.base.fastLazy
+import com.adealink.frame.mvvm.view.ViewComponent
+import com.adealink.frame.mvvm.viewmodel.activityViewModels
+import com.adealink.weparty.commonui.ext.dp
+import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
+import com.adealink.weparty.commonui.recycleview.itemdecoration.GridSpacingItemDecoration
+import com.adealink.weparty.imageselect.comp.TakeFromAlbumComp
+import com.adealink.weparty.profile.databinding.LayoutEditProfilePhotoWallBinding
+import com.adealink.weparty.profile.edit.adapter.AddPhotoItemViewBinder
+import com.adealink.weparty.profile.edit.adapter.PhotoItemViewBinder
+import com.adealink.weparty.profile.edit.data.BasePhotoItemData
+import com.adealink.weparty.profile.edit.data.PhotoData
+import com.adealink.weparty.profile.edit.viewmodel.EditProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
+import com.adealink.weparty.util.goImagePreviewActivity
+
+class EditPhotoWallComp(
+    lifecycleOwner: LifecycleOwner,
+    private val binding: LayoutEditProfilePhotoWallBinding
+) : ViewComponent(lifecycleOwner) {
+
+    companion object {
+        private const val TAG = "EditPhotoWallComp"
+        private const val PHOTO_SPAN = 3
+
+    }
+
+    private val profileViewModel by activityViewModels<ProfileViewModel> { ProfileViewModelFactory() }
+    private val editViewModel by activityViewModels<EditProfileViewModel> { ProfileViewModelFactory() }
+
+    private val photoAdapter by fastLazy { MultiTypeListAdapter<BasePhotoItemData>() }
+
+    private lateinit var photoTouchHelper: ItemTouchHelper
+    private lateinit var photoTouchCallback: PhotoWallItemTouchHelperCallback
+    private lateinit var takeFromAlbumComp: TakeFromAlbumComp
+    override fun onCreate() {
+        super.onCreate()
+        initView()
+        initViewComponent()
+        observeViewModel()
+    }
+
+    private fun initView() {
+        photoAdapter.register(
+            AddPhotoItemViewBinder {
+                addPicture()
+            }
+        )
+        photoAdapter.register(
+            PhotoItemViewBinder(
+                onItemClick = {
+                    previewPicture(it.data)
+                },
+                onDeleteClick = {
+                    deletePicture(it.data)
+                }
+            ))
+        binding.rvPhoto.adapter = photoAdapter
+        binding.rvPhoto.layoutManager = GridLayoutManager(context, PHOTO_SPAN)
+        binding.rvPhoto.addItemDecoration(
+            GridSpacingItemDecoration(PHOTO_SPAN, 4.dp(), 4.dp(), false)
+        )
+
+        photoTouchCallback =
+            PhotoWallItemTouchHelperCallback(
+                {
+                    editViewModel.photoList.isNotEmpty()
+                },
+                object : PhotoWallItemTouchHelperCallback.OnItemDragCallback {
+
+                    override fun onMoved(fromPosition: Int, toPosition: Int) {
+                        //调整位置
+                        editViewModel.adjustPhotoPosition(fromPosition, toPosition)
+                    }
+
+                })
+        photoTouchHelper = ItemTouchHelper(photoTouchCallback)
+        photoTouchHelper.attachToRecyclerView(binding.rvPhoto)
+    }
+
+    private fun initViewComponent() {
+        TakeFromAlbumComp(viewLifecycleOwner, null) { path, uri ->
+            editViewModel.addPhoto(path, uri)
+        }.also {
+            takeFromAlbumComp = it
+        }.attach()
+    }
+
+    private fun observeViewModel() {
+        editViewModel.photoItemListLD.observe(viewLifecycleOwner) {
+            photoAdapter.submitList(it)
+        }
+        editViewModel.adjustPhotoPositionLD.observe(viewLifecycleOwner) {
+            photoAdapter.notifyItemMoved(it.first, it.second)
+        }
+    }
+
+    private fun addPicture() {
+        takeFromAlbumComp.takeFromAlbum()
+    }
+
+    private fun previewPicture(data: PhotoData) {
+        val act = activity ?: return
+        if (data.isRemoteImage()) {
+            goImagePreviewActivity(
+                act,
+                arrayListOf(data.url ?: "")
+            )
+        } else {
+            goImagePreviewActivity(
+                act,
+                arrayListOf(data.uri ?: "")
+            )
+        }
+    }
+
+    private fun deletePicture(data: PhotoData) {
+        editViewModel.removePhoto(data)
+    }
+
+}

+ 37 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditTalentComp.kt

@@ -0,0 +1,37 @@
+package com.adealink.weparty.profile.edit.comp
+
+import androidx.lifecycle.LifecycleOwner
+import com.adealink.frame.mvvm.view.ViewComponent
+import com.adealink.frame.mvvm.viewmodel.activityViewModels
+import com.adealink.weparty.profile.databinding.LayoutEditProfilePersonTalentBinding
+import com.adealink.weparty.profile.edit.viewmodel.EditProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
+
+class EditTalentComp(
+    lifecycleOwner: LifecycleOwner,
+    private val binging: LayoutEditProfilePersonTalentBinding
+) : ViewComponent(lifecycleOwner) {
+
+    companion object {
+        private const val SOURCE_TAG = "EditTalentComp"
+    }
+
+    private val profileViewModel by activityViewModels<ProfileViewModel> { ProfileViewModelFactory() }
+    private val editViewModel by activityViewModels<EditProfileViewModel> { ProfileViewModelFactory() }
+
+    override fun onCreate() {
+        super.onCreate()
+        initView()
+        observeViewModel()
+    }
+
+    private fun initView() {
+
+    }
+
+    private fun observeViewModel() {
+
+    }
+
+}

+ 81 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/PhotoWallItemTouchHelperCallback.kt

@@ -0,0 +1,81 @@
+package com.adealink.weparty.profile.edit.comp
+
+import androidx.recyclerview.widget.ItemTouchHelper
+import androidx.recyclerview.widget.RecyclerView
+import com.adealink.frame.log.Log
+import com.adealink.weparty.profile.edit.adapter.AddPhotoItemViewBinder
+
+
+class PhotoWallItemTouchHelperCallback(
+    private var isLongPressDragEnabled: (() -> Boolean)?,
+    private var dragCallback: OnItemDragCallback?,
+) : ItemTouchHelper.Callback() {
+
+    private var startDragPosition = -1
+
+    override fun isLongPressDragEnabled(): Boolean {
+        Log.d(TAG, "isLongPressDragEnabled")
+        return isLongPressDragEnabled?.invoke() ?: true
+    }
+
+    override fun getMovementFlags(
+        recyclerView: RecyclerView,
+        viewHolder: RecyclerView.ViewHolder,
+    ): Int {
+        Log.d(TAG, "getMovementFlags, vh:$viewHolder")
+        if (viewHolder is AddPhotoItemViewBinder.ViewHolder) {
+            //"添加图片"不能拖动
+            return makeMovementFlags(0, 0)
+        }
+        val dragFlags =
+            ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
+        return makeMovementFlags(dragFlags, 0)
+    }
+
+    override fun onMove(
+        recyclerView: RecyclerView,
+        viewHolder: RecyclerView.ViewHolder,
+        target: RecyclerView.ViewHolder,
+    ): Boolean {
+        Log.d(
+            TAG,
+            "onMove: originPosition: ${viewHolder.bindingAdapterPosition}, targetPosition:${target.bindingAdapterPosition}"
+        )
+        dragCallback?.onMoved(viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
+        return true
+    }
+
+    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
+        Log.d(TAG, "onSwiped: direction:${direction}")
+    }
+
+    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
+        Log.d(TAG, "onSelectedChanged:$viewHolder, $actionState")
+        if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
+            startDragPosition = viewHolder?.bindingAdapterPosition ?: -1
+            Log.d(TAG, "start drag position:$startDragPosition")
+            dragCallback?.onDragStart()
+        }
+    }
+
+    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
+        Log.d(TAG, "clearView")
+        viewHolder.itemView.isClickable = true
+        if (viewHolder.bindingAdapterPosition != startDragPosition) {
+            dragCallback?.onDragEndByPositionChanged()
+        } else {
+            dragCallback?.onDragEndByNoChanged()
+        }
+    }
+
+    interface OnItemDragCallback {
+        fun onDragStart() {}
+        fun onMoved(fromPosition: Int, toPosition: Int) {}
+        fun onDragEndByPositionChanged() {}
+        fun onDragEndByNoChanged() {}
+    }
+
+    companion object {
+        private const val TAG = "PhotoWallItemTouchHelperCallback"
+    }
+}

+ 41 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/data/EditData.kt

@@ -0,0 +1,41 @@
+package com.adealink.weparty.profile.edit.data
+
+import com.adealink.frame.aab.util.getCompatString
+import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
+import com.adealink.weparty.profile.R
+
+data class PhotoData(
+    //远端路径
+    var url: String?,
+
+    //本地路径
+    val path: String?,
+    val uri: String?
+) {
+    fun isRemoteImage(): Boolean {
+        return !url.isNullOrEmpty()
+    }
+}
+
+sealed class BasePhotoItemData : BaseListItemData {
+    fun getPhotoDesc(position: Int): String {
+        return when (position) {
+            0 -> getCompatString(R.string.profile_edit_photo_wall_tips_1)
+            1 -> getCompatString(R.string.profile_edit_photo_wall_tips_2)
+            2 -> getCompatString(R.string.profile_edit_photo_wall_tips_3)
+            3 -> getCompatString(R.string.profile_edit_photo_wall_tips_4)
+            4 -> getCompatString(R.string.profile_edit_photo_wall_tips_5)
+            5 -> getCompatString(R.string.profile_edit_photo_wall_tips_6)
+            6 -> getCompatString(R.string.profile_edit_photo_wall_tips_7)
+            7 -> getCompatString(R.string.profile_edit_photo_wall_tips_8)
+            8 -> getCompatString(R.string.profile_edit_photo_wall_tips_9)
+            else -> getCompatString(R.string.profile_edit_photo_wall_tips_1)
+        }
+    }
+}
+
+object AddPhotoItemData : BasePhotoItemData()
+
+data class PhotoItemData(
+    val data: PhotoData,
+) : BasePhotoItemData()

+ 71 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditGenderDialog.kt

@@ -0,0 +1,71 @@
+package com.adealink.weparty.profile.edit.dialog
+
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.widget.BottomDialogFragment
+import com.adealink.weparty.module.profile.ProfileModule
+import com.adealink.weparty.module.profile.data.Gender
+import com.adealink.weparty.profile.R
+import com.adealink.weparty.profile.databinding.DialogEditGenderBinding
+
+class EditGenderDialog : BottomDialogFragment(R.layout.dialog_edit_gender) {
+
+    private val binding by viewBinding(DialogEditGenderBinding::bind)
+    private var callback: IEditGenderCallback? = null
+
+    private var selectedGender: Gender? = null
+
+    fun setCallback(callback: IEditGenderCallback?) {
+        this.callback = callback
+    }
+
+    override fun initViews() {
+        super.initViews()
+        binding.btnMale.onClick {
+            select(Gender.MALE)
+        }
+        binding.btnFemale.onClick {
+            select(Gender.FEMALE)
+        }
+        binding.btnSave.onClick {
+            save()
+        }
+        updateUI(Gender.map(ProfileModule.getMyUserInfo()?.gender))
+    }
+
+    private fun updateUI(gender: Gender) {
+        when (gender) {
+            Gender.MALE -> {
+                binding.btnMale.setBackgroundResource(R.drawable.profile_edit_gender_selected_bg)
+                binding.btnFemale.setBackgroundResource(R.drawable.profile_edit_gender_bg)
+            }
+
+            Gender.FEMALE -> {
+                binding.btnMale.setBackgroundResource(R.drawable.profile_edit_gender_bg)
+                binding.btnFemale.setBackgroundResource(R.drawable.profile_edit_gender_selected_bg)
+            }
+
+            Gender.UNKNOWN -> {
+
+            }
+        }
+    }
+
+    private fun select(gender: Gender) {
+        selectedGender = gender
+        updateUI(gender)
+    }
+
+    private fun save() {
+        selectedGender?.let {
+            callback?.onEditGender(it)
+        }
+        dismiss()
+    }
+
+
+    interface IEditGenderCallback {
+        fun onEditGender(gender: Gender)
+    }
+
+}

+ 13 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditInterestDialog.kt

@@ -0,0 +1,13 @@
+package com.adealink.weparty.profile.edit.dialog
+
+import com.adealink.weparty.commonui.widget.BottomDialogFragment
+import com.adealink.weparty.profile.R
+
+class EditInterestDialog: BottomDialogFragment(R.layout.dialog_edit_nickname) {
+
+    override fun initViews() {
+        super.initViews()
+    }
+
+
+}

+ 37 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditIntroDialog.kt

@@ -0,0 +1,37 @@
+package com.adealink.weparty.profile.edit.dialog
+
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.widget.BottomDialogFragment
+import com.adealink.weparty.profile.R
+import com.adealink.weparty.profile.databinding.DialogEditIntroBinding
+
+class EditIntroDialog : BottomDialogFragment(R.layout.dialog_edit_intro) {
+
+    private val binding by viewBinding(DialogEditIntroBinding::bind)
+    private var callback: IEditIntroCallback? = null
+
+    fun setCallback(callback: IEditIntroCallback?) {
+        this.callback = callback
+    }
+
+    override fun initViews() {
+        super.initViews()
+        binding.btnSave.onClick {
+            save()
+        }
+    }
+
+    private fun save() {
+        val intro = binding.etInput.text?.toString()?.trim()
+        callback?.onEditIntro(intro)
+        dismiss()
+    }
+
+
+    interface IEditIntroCallback {
+        fun onEditIntro(intro: String?)
+    }
+
+
+}

+ 40 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditNickNameDialog.kt

@@ -0,0 +1,40 @@
+package com.adealink.weparty.profile.edit.dialog
+
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.toast.util.showToast
+import com.adealink.weparty.commonui.widget.BottomDialogFragment
+import com.adealink.weparty.profile.R
+import com.adealink.weparty.profile.databinding.DialogEditNicknameBinding
+
+class EditNickNameDialog : BottomDialogFragment(R.layout.dialog_edit_nickname) {
+
+    private val binding by viewBinding(DialogEditNicknameBinding::bind)
+    private var callback: IEditNameCallback? = null
+
+    fun setCallback(callback: IEditNameCallback?) {
+        this.callback = callback
+    }
+
+    override fun initViews() {
+        super.initViews()
+        binding.btnSave.onClick {
+            save()
+        }
+    }
+
+    private fun save() {
+        val nickName = binding.etInput.text?.toString()?.trim()
+        if (nickName.isNullOrEmpty()) {
+            showToast(R.string.profile_edit_nickname_empty)
+            return
+        }
+        callback?.onEditName(nickName)
+        dismiss()
+    }
+
+
+    interface IEditNameCallback {
+        fun onEditName(name: String)
+    }
+}

+ 71 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditTalentVoiceDialog.kt

@@ -0,0 +1,71 @@
+package com.adealink.weparty.profile.edit.dialog
+
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.widget.BottomDialogFragment
+import com.adealink.weparty.module.profile.ProfileModule
+import com.adealink.weparty.module.profile.data.Gender
+import com.adealink.weparty.profile.R
+import com.adealink.weparty.profile.databinding.DialogEditGenderBinding
+
+class EditTalentVoiceDialog : BottomDialogFragment(R.layout.dialog_edit_gender) {
+
+    private val binding by viewBinding(DialogEditGenderBinding::bind)
+    private var callback: IEditGenderCallback? = null
+
+    private var selectedGender: Gender? = null
+
+    fun setCallback(callback: IEditGenderCallback?) {
+        this.callback = callback
+    }
+
+    override fun initViews() {
+        super.initViews()
+        binding.btnMale.onClick {
+            select(Gender.MALE)
+        }
+        binding.btnFemale.onClick {
+            select(Gender.FEMALE)
+        }
+        binding.btnSave.onClick {
+            save()
+        }
+        updateUI(Gender.map(ProfileModule.getMyUserInfo()?.gender))
+    }
+
+    private fun updateUI(gender: Gender) {
+        when (gender) {
+            Gender.MALE -> {
+                binding.btnMale.setBackgroundResource(R.drawable.profile_edit_gender_selected_bg)
+                binding.btnFemale.setBackgroundResource(R.drawable.profile_edit_gender_bg)
+            }
+
+            Gender.FEMALE -> {
+                binding.btnMale.setBackgroundResource(R.drawable.profile_edit_gender_bg)
+                binding.btnFemale.setBackgroundResource(R.drawable.profile_edit_gender_selected_bg)
+            }
+
+            Gender.UNKNOWN -> {
+
+            }
+        }
+    }
+
+    private fun select(gender: Gender) {
+        selectedGender = gender
+        updateUI(gender)
+    }
+
+    private fun save() {
+        selectedGender?.let {
+            callback?.onEditGender(it)
+        }
+        dismiss()
+    }
+
+
+    interface IEditGenderCallback {
+        fun onEditGender(gender: Gender)
+    }
+
+}

+ 4 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/SubmitVoiceFragment.kt

@@ -0,0 +1,4 @@
+package com.adealink.weparty.profile.edit.dialog.fragment
+
+class SubmitVoiceFragment {
+}

+ 34 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/VoiceFragment.kt

@@ -0,0 +1,34 @@
+package com.adealink.weparty.profile.edit.dialog.fragment
+
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.BaseFragment
+import com.adealink.weparty.module.profile.ProfileModule
+import com.adealink.weparty.profile.R
+import com.adealink.weparty.profile.databinding.FragmentEditTalentVoiceBinding
+import com.adealink.weparty.profile.edit.dialog.EditTalentVoiceDialog
+import com.adealink.weparty.profile.edit.dialog.viewmodel.EditVoiceViewModel
+import com.adealink.weparty.viewmodel.parentFragmentViewModels
+
+class VoiceFragment : BaseFragment(R.layout.fragment_edit_talent_voice) {
+
+    private val binding by viewBinding(FragmentEditTalentVoiceBinding::bind)
+
+    private val viewModel by parentFragmentViewModels<EditVoiceViewModel, EditTalentVoiceDialog>(
+        EditTalentVoiceDialog::class.java
+    )
+
+    override fun initViews() {
+        super.initViews()
+        //binding.vSound.setSoundUrl()
+        binding.btnRecord.onClick {
+
+        }
+    }
+
+    override fun loadData() {
+        super.loadData()
+        ProfileModule.getMyUserInfo()?.gender
+    }
+
+}

+ 19 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/viewmodel/EditVoiceViewModel.kt

@@ -0,0 +1,19 @@
+package com.adealink.weparty.profile.edit.dialog.viewmodel
+
+import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
+import com.adealink.frame.mvvm.viewmodel.BaseViewModel
+
+enum class EditVoicePage {
+    VOICE,
+    EDIT
+}
+
+class EditVoiceViewModel : BaseViewModel() {
+
+    val pageLD = ExtMutableLiveData<EditVoicePage>()
+
+    fun showPage(page: EditVoicePage) {
+        pageLD.send(page)
+    }
+
+}

+ 81 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/viewmodel/EditProfileViewModel.kt

@@ -0,0 +1,81 @@
+package com.adealink.weparty.profile.edit.viewmodel
+
+import androidx.lifecycle.MutableLiveData
+import com.adealink.frame.log.Log
+import com.adealink.frame.mvvm.viewmodel.BaseViewModel
+import com.adealink.weparty.profile.edit.data.AddPhotoItemData
+import com.adealink.weparty.profile.edit.data.BasePhotoItemData
+import com.adealink.weparty.profile.edit.data.PhotoData
+import com.adealink.weparty.profile.edit.data.PhotoItemData
+import kotlinx.coroutines.launch
+
+class EditProfileViewModel : BaseViewModel() {
+
+    companion object {
+        private const val TAG = "EditProfileViewModel"
+        const val MAX_PHOTO_COUNT = 9
+    }
+
+    val photoList = mutableListOf<PhotoData>()
+
+    val photoItemList = mutableListOf<BasePhotoItemData>()
+    val photoItemListLD = MutableLiveData<MutableList<BasePhotoItemData>>()
+
+    init {
+        onPictureListChanged()
+    }
+
+    fun addPhoto(path: String?, uri: String?) {
+        viewModelScope.launch {
+            photoList.add(
+                PhotoData(
+                    url = null,
+                    path = path,
+                    uri = uri
+                )
+            )
+            onPictureListChanged()
+        }
+    }
+
+    fun removePhoto(data: PhotoData) {
+        viewModelScope.launch {
+            photoList.remove(data)
+            onPictureListChanged()
+        }
+    }
+
+    private fun onPictureListChanged() {
+        photoItemList.clear()
+        for ((i, data) in photoList.take(MAX_PHOTO_COUNT).withIndex()) {
+            photoItemList.add(PhotoItemData(data))
+        }
+        //小于9张图片,可以继续添加图片
+        for (i in photoList.size until MAX_PHOTO_COUNT) {
+            photoItemList.add(AddPhotoItemData)
+        }
+        photoItemListLD.send(photoItemList)
+    }
+
+    //调整勋章位置
+    val adjustPhotoPositionLD = MutableLiveData<Pair<Int, Int>>()
+    fun adjustPhotoPosition(fromPosition: Int, toPosition: Int) {
+        Log.d(TAG, "adjustPhotoPosition, from:$fromPosition, to:$toPosition")
+        if (fromPosition < 0 || toPosition < 0) return
+        val itemCount = photoItemList.size
+        if (fromPosition > itemCount || toPosition > itemCount) return
+
+        viewModelScope.launch {
+            photoItemList.add(toPosition, photoItemList.removeAt(fromPosition))
+            photoList.clear()
+            for (itemData in photoItemList) {
+                if (itemData is PhotoItemData) {
+                    photoList.add(itemData.data)
+                }
+            }
+            adjustPhotoPositionLD.send(Pair(fromPosition, toPosition))
+        }
+    }
+
+
+}

+ 2 - 3
module/profile/src/main/java/com/adealink/weparty/profile/me/MeFragment.kt

@@ -17,7 +17,7 @@ import com.adealink.weparty.profile.me.comp.MeFunctionCenterComp
 import com.adealink.weparty.profile.me.comp.MeHeaderComp
 import com.adealink.weparty.profile.me.comp.MeShareComp
 import com.adealink.weparty.profile.me.comp.MeWalletComp
-import com.adealink.weparty.profile.relation.viewmodel.RelationShipViewModel
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
 import com.adealink.weparty.R as APP_R
@@ -27,7 +27,7 @@ class MeFragment : BaseFragment(R.layout.fragment_me) {
 
     private val binding by viewBinding(FragmentMeBinding::bind)
     private val profileViewModel by viewModels<ProfileViewModel> { ProfileViewModelFactory() }
-    private val followViewModel by viewModels<RelationShipViewModel> { ProfileViewModelFactory() }
+    private val followViewModel by viewModels<FollowViewModel> { ProfileViewModelFactory() }
 
     override fun initViews() {
         super.initViews()
@@ -47,7 +47,6 @@ class MeFragment : BaseFragment(R.layout.fragment_me) {
         profileViewModel.pullUserInfoBy(ProfileModule.getMyUid(), false)
         // TODO: 刷新关注人数
         followViewModel
-
     }
 
     override fun observeViewModel() {

+ 2 - 2
module/profile/src/main/java/com/adealink/weparty/profile/relation/RelationShipActivity.kt

@@ -15,9 +15,9 @@ import com.adealink.weparty.commonui.recycleview.adapter.BaseActivityTabFragment
 import com.adealink.weparty.commonui.widget.EmptyFragment
 import com.adealink.weparty.module.profile.Profile
 import com.adealink.weparty.profile.databinding.ActivityProfileRelationshipBinding
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
 import com.adealink.weparty.profile.relation.viewmodel.RELATIONSHIP_TABS
 import com.adealink.weparty.profile.relation.viewmodel.RelationShipTab
-import com.adealink.weparty.profile.relation.viewmodel.RelationShipViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
 
 @RouterUri(
@@ -30,7 +30,7 @@ class RelationShipActivity : BaseActivity() {
     var tabIndex: Int = RelationShipTab.FOLLOW.index
 
     private val binding by viewBinding(ActivityProfileRelationshipBinding::inflate)
-    private val viewModel by viewModels<RelationShipViewModel> { ProfileViewModelFactory() }
+    private val viewModel by viewModels<FollowViewModel> { ProfileViewModelFactory() }
     private lateinit var pageAdapter: PageAdapter
 
     override fun onBeforeCreate() {

+ 9 - 3
module/profile/src/main/java/com/adealink/weparty/profile/relation/data/RelationShipData.kt

@@ -7,10 +7,16 @@ import com.google.gson.annotations.SerializedName
 
 
 data class FollowReq(
+    @SerializedName("userNo") val uid: String,
+    @SerializedName("follow") val follow: Boolean,
+)
+
+
+data class FollowListReq(
     @SerializedName("page") val page: PageReq
 )
 
-data class FollowRes(
+data class FollowListRes(
     @SerializedName("list") val list: List<FollowData>
 )
 
@@ -19,11 +25,11 @@ data class FollowData(
 )
 
 
-data class FansReq(
+data class FansListReq(
     @SerializedName("page") val page: PageReq
 )
 
-data class FansRes(
+data class FansLlistRes(
     @SerializedName("list") val list: List<FansData>
 )
 

+ 69 - 0
module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/FollowViewModel.kt

@@ -0,0 +1,69 @@
+package com.adealink.weparty.profile.relation.viewmodel
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
+import com.adealink.frame.mvvm.viewmodel.BaseViewModel
+import com.adealink.weparty.App
+import com.adealink.weparty.profile.datasource.remote.FollowHttpService
+import com.adealink.weparty.profile.relation.data.FansItemData
+import com.adealink.weparty.profile.relation.data.FollowItemData
+import com.adealink.weparty.profile.relation.data.FollowReq
+import com.adealink.weparty.util.PageHandler
+import kotlinx.coroutines.launch
+
+class FollowViewModel : BaseViewModel() {
+
+    private val followHttpService by lazy {
+        App.instance.networkService.getHttpService(FollowHttpService::class.java)
+    }
+
+    fun follow(uid: String): LiveData<Rlt<Any>> {
+        val liveData = OnceMutableLiveData<Rlt<Any>>()
+        viewModelScope.launch {
+            liveData.send(followHttpService.follow(FollowReq(uid, true)))
+        }
+        return liveData
+    }
+
+    fun unFollow(uid: String): LiveData<Rlt<Any>> {
+        val liveData = OnceMutableLiveData<Rlt<Any>>()
+        viewModelScope.launch {
+            liveData.send(followHttpService.follow(FollowReq(uid, false)))
+        }
+        return liveData
+    }
+
+
+    private val followList = mutableListOf<FollowItemData>()
+    private val followPageHandler = PageHandler()
+    val followListLD = MutableLiveData<List<FollowItemData>>()
+    fun pullFollowed() {
+        viewModelScope.launch {
+
+        }
+    }
+
+    fun loadMoreFollowed() {
+        viewModelScope.launch {
+
+        }
+    }
+
+
+    private val fansList = mutableListOf<FansItemData>()
+    private val fansPageHandler = PageHandler()
+    val fansListLD = MutableLiveData<List<FansItemData>>()
+    fun pullFans() {
+        viewModelScope.launch {
+
+        }
+    }
+
+    fun loadMoreFans() {
+        viewModelScope.launch {
+
+        }
+    }
+}

+ 0 - 43
module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/RelationShipViewModel.kt

@@ -1,43 +0,0 @@
-package com.adealink.weparty.profile.relation.viewmodel
-
-import androidx.lifecycle.MutableLiveData
-import com.adealink.frame.mvvm.viewmodel.BaseViewModel
-import com.adealink.weparty.profile.relation.data.FansItemData
-import com.adealink.weparty.profile.relation.data.FollowItemData
-import com.adealink.weparty.util.PageHandler
-import kotlinx.coroutines.launch
-
-class RelationShipViewModel : BaseViewModel() {
-
-
-    private val followList = mutableListOf<FollowItemData>()
-    private val followPageHandler = PageHandler(pageSize = 20)
-    val followListLD = MutableLiveData<List<FollowItemData>>()
-    fun pullFollowed() {
-        viewModelScope.launch {
-
-        }
-    }
-
-    fun loadMoreFollowed(){
-        viewModelScope.launch {
-
-        }
-    }
-
-
-    private val fansList = mutableListOf<FansItemData>()
-    private val fansPageHandler = PageHandler(pageSize = 20)
-    val fansListLD = MutableLiveData<List<FansItemData>>()
-    fun pullFans() {
-        viewModelScope.launch {
-
-        }
-    }
-
-    fun loadMoreFans(){
-        viewModelScope.launch {
-
-        }
-    }
-}

+ 2 - 2
module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/fans/FansFragment.kt

@@ -18,12 +18,12 @@ import com.adealink.weparty.profile.databinding.FragmentFansBinding
 import com.adealink.weparty.profile.relation.adapter.FansItemViewBinder
 import com.adealink.weparty.profile.relation.data.BaseRelationShipItemData
 import com.adealink.weparty.profile.relation.data.FansItemData
-import com.adealink.weparty.profile.relation.viewmodel.RelationShipViewModel
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
 
 class FansFragment : BaseFragment(R.layout.fragment_fans), FansItemViewBinder.OnFansItemClick {
     private val binding by viewBinding(FragmentFansBinding::bind)
-    private val viewModel by activityViewModels<RelationShipViewModel> { ProfileViewModelFactory() }
+    private val viewModel by activityViewModels<FollowViewModel> { ProfileViewModelFactory() }
     private val listAdapter by fastLazy { MultiTypeListAdapter<BaseRelationShipItemData>() }
     override fun initViews() {
         super.initViews()

+ 2 - 2
module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/follow/FollowFragment.kt

@@ -18,14 +18,14 @@ import com.adealink.weparty.profile.databinding.FragmentFollowBinding
 import com.adealink.weparty.profile.relation.adapter.FollowItemViewBinder
 import com.adealink.weparty.profile.relation.data.BaseRelationShipItemData
 import com.adealink.weparty.profile.relation.data.FollowItemData
-import com.adealink.weparty.profile.relation.viewmodel.RelationShipViewModel
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
 
 class FollowFragment : BaseFragment(R.layout.fragment_follow),
     FollowItemViewBinder.OnFollowItemClick {
 
     private val binding by viewBinding(FragmentFollowBinding::bind)
-    private val viewModel by activityViewModels<RelationShipViewModel> { ProfileViewModelFactory() }
+    private val viewModel by activityViewModels<FollowViewModel> { ProfileViewModelFactory() }
     private val listAdapter by fastLazy { MultiTypeListAdapter<BaseRelationShipItemData>() }
 
     override fun initViews() {

+ 39 - 7
module/profile/src/main/java/com/adealink/weparty/profile/search/SearchActivity.kt

@@ -27,14 +27,18 @@ import com.adealink.weparty.commonui.BaseActivity
 import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.ext.fitSystemWindows
 import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.isSuccess
 import com.adealink.weparty.commonui.ext.onWindowInsets
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
 import com.adealink.weparty.commonui.recycleview.itemdecoration.VerticalSpaceItemDecoration
 import com.adealink.weparty.commonui.recycleview.layoutmanager.FlowLayoutManager
+import com.adealink.weparty.commonui.toast.util.showFailedToast
 import com.adealink.weparty.module.profile.Profile
+import com.adealink.weparty.network.data.NoMoreDataError
 import com.adealink.weparty.profile.databinding.ActivityUserSearchBinding
 import com.adealink.weparty.profile.datasource.local.SearchLocalService
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
 import com.adealink.weparty.profile.search.adapter.SearchHistoryViewBinder
 import com.adealink.weparty.profile.search.adapter.SearchItemViewBinder
 import com.adealink.weparty.profile.search.data.SearchHistoryItemData
@@ -59,6 +63,7 @@ class SearchActivity : BaseActivity(),
     private val resultAdapter by fastLazy { MultiTypeListAdapter<SearchResultItemData>() }
 
     private val searchViewModel by viewModels<SearchViewModel>()
+    private val followViewModel by viewModels<FollowViewModel>()
     private var isSearching = MutableLiveData<Boolean>()
     private var isInputEmpty = MutableLiveData<Boolean>()
 
@@ -214,10 +219,13 @@ class SearchActivity : BaseActivity(),
                 }
             }
         }
-        searchViewModel.searchResultLD.observeWithoutCache(this) { rlt ->
+        searchViewModel.searchRltLD.observeWithoutCache(this) { rlt ->
             isSearching.postValue(false)
             when (rlt) {
                 is Rlt.Failed -> {
+                    if (rlt.error is NoMoreDataError) {
+                        return@observeWithoutCache
+                    }
                     binding.clSearchResult.show()
                     binding.rvResult.gone()
                     binding.vErrorView.show(
@@ -230,10 +238,12 @@ class SearchActivity : BaseActivity(),
                     binding.clSearchResult.show()
                     binding.rvResult.show()
                     binding.vErrorView.gone()
-                    resultAdapter.submitList(rlt.data)
                 }
             }
         }
+        searchViewModel.searchResultLD.observeWithoutCache(this) { list ->
+            resultAdapter.submitList(list, true)
+        }
     }
 
     private fun hideHistoryList() {
@@ -241,15 +251,37 @@ class SearchActivity : BaseActivity(),
     }
 
 
-    override fun onClick(
-        item: SearchResultItemData,
-        pos: Int
-    ) {
+    override fun goProfile(uid: String) {
         Router.build(this, Profile.UserProfile.PATH)
-            .putExtra(Profile.Common.EXTRA_UID, item.data.userinfo.uid)
+            .putExtra(Profile.Common.EXTRA_UID, uid)
             .start()
     }
 
+    override fun follow(uid: String) {
+        showLoading()
+        followViewModel.follow(uid).observe(this) {
+            dismissLoading()
+            if (it.isSuccess) {
+                searchViewModel.notifyFollowChanged(uid, true)
+            } else {
+                showFailedToast(it)
+            }
+        }
+    }
+
+    override fun unFollow(uid: String) {
+        showLoading()
+        followViewModel.follow(uid).observe(this) {
+            dismissLoading()
+            if (it.isSuccess) {
+                searchViewModel.notifyFollowChanged(uid, false)
+            } else {
+                showFailedToast(it)
+            }
+        }
+    }
+
+
     override fun onClick(
         item: SearchHistoryItemData,
         pos: Int

+ 30 - 12
module/profile/src/main/java/com/adealink/weparty/profile/search/adapter/SearchItemViewBinder.kt

@@ -3,9 +3,11 @@ package com.adealink.weparty.profile.search.adapter
 import android.annotation.SuppressLint
 import android.view.LayoutInflater
 import android.view.ViewGroup
+import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.util.onClick
 import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
 import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
+import com.adealink.weparty.profile.R
 import com.adealink.weparty.profile.databinding.LayoutProfileSearchItemBinding
 import com.adealink.weparty.profile.search.data.SearchResultItemData
 
@@ -18,18 +20,29 @@ class SearchItemViewBinder(val listener: OnResultClickListener) :
         item: SearchResultItemData,
     ) {
         holder.binding.root.onClick {
-            listener.onClick(item, holder.layoutPosition)
+            listener.goProfile(item.data.uid)
+        }
+        holder.binding.ivAvatar.setImageUrl(item.data.avatar)
+        holder.binding.tvName.text = item.data.nickName
+        holder.binding.vGender.setGender(item.data.gender)
+        holder.binding.vGender.setAge(item.data.age)
+        holder.binding.tvId.text = "ID ${item.data.uid}"
+        holder.binding.tvFans.text =
+            getCompatString(
+                R.string.profile_search_user_fans,
+                (item.data.followCount ?: 0).toString()
+            )
+        if (item.data.follow == true) {
+            holder.binding.btnFollow.setBackgroundResource(R.drawable.profile_followed_btn_bg)
+            holder.binding.btnFollow.onClick {
+                listener.unFollow(item.data.uid)
+            }
+        } else {
+            holder.binding.btnFollow.setBackgroundResource(R.drawable.profile_follow_btn_bg)
+            holder.binding.btnFollow.onClick {
+                listener.follow(item.data.uid)
+            }
         }
-        holder.binding.ivAvatar.setImageUrl(item.data.userinfo.avatar)
-        holder.binding.tvName.text = item.data.userinfo.nickName
-        holder.binding.vGender.setGender(item.data.userinfo.gender)
-        holder.binding.vGender.setAge(item.data.userinfo.age)
-        holder.binding.tvId.text = "ID ${item.data.userinfo.uid}"
-//        holder.binding.tvFans.text =
-//            getCompatString(
-//                R.string.profile_search_user_fans,
-//                (item.data.userinfo.fans ?: 0).toString()
-//            )
     }
 
     override fun onCreateViewHolder(
@@ -40,7 +53,12 @@ class SearchItemViewBinder(val listener: OnResultClickListener) :
     }
 
     interface OnResultClickListener {
-        fun onClick(item: SearchResultItemData, pos: Int)
+        fun goProfile(uid: String)
+
+        fun follow(uid: String)
+
+        fun unFollow(uid: String)
+
     }
 
 }

+ 38 - 7
module/profile/src/main/java/com/adealink/weparty/profile/search/data/SearchData.kt

@@ -1,27 +1,58 @@
 package com.adealink.weparty.profile.search.data
 
+import com.adealink.frame.network.data.PageReq
 import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
-import com.adealink.weparty.module.profile.data.UserInfo
+import com.google.gson.annotations.GsonNullable
 import com.google.gson.annotations.SerializedName
 
 
 data class SearchReq(
-    @SerializedName("keywork") val keywork: String
+    @SerializedName("keyword") val keyword: String,
+    @SerializedName("page") val page: PageReq
 )
 
 data class SearchRes(
-    @SerializedName("list") val result: List<SearchData>
+    @SerializedName("list") val list: List<SearchData>,
+    @GsonNullable
+    @SerializedName("next") val next: String?
 )
 
 data class SearchData(
-    @SerializedName("user")
-    val userinfo: UserInfo
+    @SerializedName("userNo") val uid: String,
+    @GsonNullable
+    @SerializedName("nickname") val nickName: String? = null,
+    @GsonNullable
+    @SerializedName("avatar") val avatar: String? = null,
+    @GsonNullable
+    @SerializedName("age") val age: Int? = null,
+    @GsonNullable
+    @SerializedName("birthdayAt") val birthdayAt: Long? = null,
+    @GsonNullable
+    @SerializedName("gender") val gender: Int? = null,
+
+    @GsonNullable
+    @SerializedName("follow") var follow: Boolean? = null, //是否关注
+    @GsonNullable
+    @SerializedName("followCount") val followCount: Int? = null, //粉丝人数
+    @GsonNullable
+    @SerializedName("online") val online: Boolean? = null //在线状态
 )
 
 data class SearchResultItemData(
     val data: SearchData
-) : BaseListItemData
+) : BaseListItemData {
+    override fun areContentsTheSame(newItem: Any): Boolean {
+        val new = newItem as? SearchResultItemData ?: return false
+        return data.uid == new.data.uid
+                && data.follow == new.data.follow
+    }
+}
 
 data class SearchHistoryItemData(
     val keyword: String
-) : BaseListItemData
+) : BaseListItemData {
+    override fun areContentsTheSame(newItem: Any): Boolean {
+        val new = newItem as? SearchHistoryItemData ?: return false
+        return keyword == new.keyword
+    }
+}

+ 52 - 58
module/profile/src/main/java/com/adealink/weparty/profile/search/viewmodel/SearchViewModel.kt

@@ -3,73 +3,67 @@ package com.adealink.weparty.profile.search.viewmodel
 import com.adealink.frame.base.Rlt
 import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
-import com.adealink.weparty.module.profile.ProfileModule
-import com.adealink.weparty.module.profile.data.UserInfo
-import com.adealink.weparty.profile.search.data.SearchData
+import com.adealink.frame.network.data.PageReq
+import com.adealink.weparty.App
+import com.adealink.weparty.network.data.NoMoreDataError
+import com.adealink.weparty.profile.datasource.remote.SearchHttpService
+import com.adealink.weparty.profile.search.data.SearchReq
 import com.adealink.weparty.profile.search.data.SearchResultItemData
+import com.adealink.weparty.util.PageHandler
 import kotlinx.coroutines.launch
 
 class SearchViewModel : BaseViewModel() {
 
-    val searchResultLD = ExtMutableLiveData<Rlt<List<SearchResultItemData>>>()
+    private val searchHttpService by lazy {
+        App.instance.networkService.getHttpService(SearchHttpService::class.java)
+    }
+
+    val searchResultLD = ExtMutableLiveData<List<SearchResultItemData>>()
+    val searchRltLD = ExtMutableLiveData<Rlt<Any>>()
+    private val searchResultList = mutableListOf<SearchResultItemData>()
+    private val pageHandler = PageHandler()
+    private var keyword: String? = null
 
-    fun search(keywork: String) {
+    fun search(keyword: String) {
+        pageHandler.reset()
+        this.keyword = keyword
+        searchMore()
+    }
+
+    fun searchMore() {
+        if (pageHandler.isEnd) {
+            searchRltLD.send(Rlt.Failed(NoMoreDataError()))
+            return
+        }
         viewModelScope.launch {
-            // TODO: zhangfei 测试
-            searchResultLD.send(
-                Rlt.Success(
-                    listOf(
-                        SearchResultItemData(
-                            SearchData(
-                                ProfileModule.getMyUserInfo() ?: UserInfo.emptyUserInfo(
-                                    "123",
-                                    ""
-                                )
-                            )
-                        ),
-                        SearchResultItemData(
-                            SearchData(
-                                ProfileModule.getMyUserInfo() ?: UserInfo.emptyUserInfo(
-                                    "123",
-                                    ""
-                                )
-                            )
-                        ),
-                        SearchResultItemData(
-                            SearchData(
-                                ProfileModule.getMyUserInfo() ?: UserInfo.emptyUserInfo(
-                                    "123",
-                                    ""
-                                )
-                            )
-                        ),
-                        SearchResultItemData(
-                            SearchData(
-                                ProfileModule.getMyUserInfo() ?: UserInfo.emptyUserInfo(
-                                    "123",
-                                    ""
-                                )
-                            )
-                        ),
-                        SearchResultItemData(
-                            SearchData(
-                                ProfileModule.getMyUserInfo() ?: UserInfo.emptyUserInfo(
-                                    "123",
-                                    ""
-                                )
-                            )
-                        ),
-                        SearchResultItemData(
-                            SearchData(
-                                ProfileModule.getMyUserInfo() ?: UserInfo.emptyUserInfo(
-                                    "123",
-                                    ""
-                                )
-                            )
-                        ),
-                    )
+            val keyword = this@SearchViewModel.keyword ?: return@launch
+            val rlt = searchHttpService.search(
+                SearchReq(
+                    keyword = keyword,
+                    page = PageReq(size = pageHandler.pageSize, next = pageHandler.currentPage)
                 )
             )
+            when (rlt) {
+                is Rlt.Failed -> {
+                    searchRltLD.send(rlt)
+                }
+
+                is Rlt.Success -> {
+                    pageHandler.nextPage(rlt.data.data?.next)
+                    searchResultList.addAll(rlt.data.data?.list?.map {
+                        SearchResultItemData(it)
+                    } ?: emptyList())
+                    searchRltLD.send(rlt)
+                    searchResultLD.send(searchResultList)
+                }
+            }
+        }
+    }
+
+    fun notifyFollowChanged(uid: String, follow: Boolean) {
+        viewModelScope.launch {
+            searchResultList.find { it.data.uid == uid }?.data?.follow = follow
+            searchResultLD.send(searchResultList)
         }
     }
 }

+ 7 - 3
module/profile/src/main/java/com/adealink/weparty/profile/viewmodel/ProfileViewModelFactory.kt

@@ -2,7 +2,8 @@ package com.adealink.weparty.profile.viewmodel
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
-import com.adealink.weparty.profile.relation.viewmodel.RelationShipViewModel
+import com.adealink.weparty.profile.edit.viewmodel.EditProfileViewModel
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
 
 @Suppress("UNCHECKED_CAST")
 class ProfileViewModelFactory : ViewModelProvider.NewInstanceFactory() {
@@ -13,8 +14,11 @@ class ProfileViewModelFactory : ViewModelProvider.NewInstanceFactory() {
                 isAssignableFrom(ProfileViewModel::class.java) ->
                     ProfileViewModel()
 
-                isAssignableFrom(RelationShipViewModel::class.java) ->
-                    RelationShipViewModel()
+                isAssignableFrom(EditProfileViewModel::class.java) ->
+                    EditProfileViewModel()
+
+                isAssignableFrom(FollowViewModel::class.java) ->
+                    FollowViewModel()
 
                 else ->
                     throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")

BIN
module/profile/src/main/res/drawable-xhdpi/profile_add_photo_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_edit_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_edit_talent_voice_preview_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_edit_talent_voice_re_record_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_edit_talent_voice_record_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_edit_talent_voice_stop_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_me_edit_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_more_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_share_ic.png


+ 6 - 0
module/profile/src/main/res/drawable/profile_add_photo_bg.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#F2F3F5" />
+    <corners android:radius="12dp" />
+</shape>

+ 6 - 0
module/profile/src/main/res/drawable/profile_edit_button_bg.xml

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

+ 2 - 6
module/profile/src/main/res/drawable/profile_edit_gender_select_bg.xml → module/profile/src/main/res/drawable/profile_edit_gender_bg.xml

@@ -2,12 +2,8 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
 
-    <corners android:radius="30dp" />
+    <solid android:color="@color/color_FFF1F2F5" />
 
-    <gradient
-        android:angle="180"
-        android:endColor="#4ED2FF"
-        android:startColor="#B1EF5D"
-        android:type="linear" />
+    <corners android:radius="30dp" />
 
 </shape>

+ 9 - 0
module/profile/src/main/res/drawable/profile_edit_gender_selected_bg.xml

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

+ 0 - 5
module/profile/src/main/res/drawable/profile_follow_btn_bg_sel.xml

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

+ 5 - 0
module/profile/src/main/res/drawable/profile_top_bar_button_bg.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid android:color="@color/color_66000000" />
+</shape>

+ 52 - 145
module/profile/src/main/res/layout/activity_edit_profile.xml

@@ -1,14 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
+
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:clipChildren="false">
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/top_bar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/common_top_bar_height"
+        android:paddingHorizontal="16dp"
         app:layout_constraintTop_toTopOf="parent">
 
         <androidx.appcompat.widget.AppCompatImageView
@@ -47,161 +49,66 @@
     <androidx.core.widget.NestedScrollView
         android:layout_width="match_parent"
         android:layout_height="0dp"
-        android:background="@color/color_FFF1F2F5"
         android:orientation="vertical"
+        android:clipChildren="false"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintTop_toBottomOf="@id/top_bar">
 
         <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cl_content"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:paddingHorizontal="16dp">
+            android:paddingHorizontal="16dp"
+            android:clipChildren="false">
+
+            <include
+                android:id="@+id/v_photo_wall"
+                layout="@layout/layout_edit_profile_photo_wall"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
 
-            <com.adealink.weparty.commonui.imageview.AvatarView
-                android:id="@+id/iv_avatar"
-                android:layout_width="90dp"
-                android:layout_height="90dp"
-                android:layout_marginTop="20dp"
+            <View
+                android:layout_width="0dp"
+                android:layout_height="1dp"
+                android:layout_marginTop="24dp"
+                android:background="@color/color_FFF2F3F5"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent"
-                app:roundingBorderColor="@color/white"
-                app:roundingBorderWidth="1dp" />
-
-            <androidx.appcompat.widget.AppCompatImageView
-                android:id="@+id/iv_edit_avatar"
-                android:layout_width="32dp"
-                android:layout_height="32dp"
-                app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
-                app:layout_constraintEnd_toEndOf="@id/iv_avatar"
-                app:srcCompat="@drawable/profile_edit_avatar_ic" />
-
-            <androidx.constraintlayout.widget.ConstraintLayout
-                android:id="@+id/cl_content"
+                app:layout_constraintTop_toBottomOf="@id/v_photo_wall" />
+
+            <include
+                android:id="@+id/v_person_info"
+                layout="@layout/layout_edit_profile_person_info"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="20dp"
-                android:background="@drawable/commonui_dialog_bg"
-                android:padding="16dp"
-                app:layout_constraintTop_toBottomOf="@id/iv_avatar">
-
-                <!--昵称-->
-                <androidx.appcompat.widget.AppCompatTextView
-                    android:id="@+id/tv_user_name"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:fontFamily="@font/poppins_semibold"
-                    android:includeFontPadding="false"
-                    android:text="@string/profile_edit_nickname"
-                    android:textColor="@color/color_FF4E5969"
-                    android:textSize="14sp"
-                    app:layout_constrainedWidth="true"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintHorizontal_bias="0"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
-
-                <androidx.appcompat.widget.AppCompatEditText
-                    android:id="@+id/et_user_name"
-                    style="@style/CommonEditText"
-                    android:layout_width="0dp"
-                    android:layout_height="36dp"
-                    android:layout_marginTop="8dp"
-                    android:gravity="start|center_vertical"
-                    android:singleLine="true"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toBottomOf="@id/tv_user_name"
-                    tools:hint="Please input" />
-
-                <!--性别-->
-                <androidx.appcompat.widget.AppCompatTextView
-                    android:id="@+id/tv_gender"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="24dp"
-                    android:fontFamily="@font/poppins_semibold"
-                    android:includeFontPadding="false"
-                    android:text="@string/profile_edit_gender"
-                    android:textColor="@color/color_FF4E5969"
-                    android:textSize="14sp"
-                    app:layout_constrainedWidth="true"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintHorizontal_bias="0"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toBottomOf="@id/et_user_name" />
-
-                <androidx.constraintlayout.widget.ConstraintLayout
-                    android:id="@+id/cl_gender"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="8dp"
-                    app:layout_constraintTop_toBottomOf="@id/tv_gender">
-
-                    <androidx.appcompat.widget.AppCompatTextView
-                        android:id="@+id/tv_gender_male"
-                        android:layout_width="wrap_content"
-                        android:layout_height="28dp"
-                        android:gravity="center"
-                        android:minWidth="70dp"
-                        android:paddingHorizontal="12dp"
-                        android:text="@string/common_male"
-                        android:textSize="14sp"
-                        app:layout_constraintBottom_toBottomOf="parent"
-                        app:layout_constraintStart_toStartOf="parent"
-                        app:layout_constraintTop_toTopOf="parent"
-                        tools:background="@drawable/profile_edit_gender_select_bg"
-                        tools:textColor="@color/white" />
-
-                    <androidx.appcompat.widget.AppCompatTextView
-                        android:id="@+id/tv_gender_female"
-                        android:layout_width="wrap_content"
-                        android:layout_height="28dp"
-                        android:layout_marginStart="8dp"
-                        android:gravity="center"
-                        android:minWidth="70dp"
-                        android:paddingHorizontal="12dp"
-                        android:text="@string/common_female"
-                        android:textSize="14sp"
-                        app:layout_constraintBottom_toBottomOf="parent"
-                        app:layout_constraintStart_toEndOf="@id/tv_gender_male"
-                        app:layout_constraintTop_toTopOf="parent"
-                        tools:background="@drawable/profile_edit_gender_unselect_bg"
-                        tools:textColor="@color/color_FFCDCFD9" />
-
-                </androidx.constraintlayout.widget.ConstraintLayout>
-
-                <!--性别-->
-                <androidx.appcompat.widget.AppCompatTextView
-                    android:id="@+id/tv_user_age"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="24dp"
-                    android:fontFamily="@font/poppins_semibold"
-                    android:includeFontPadding="false"
-                    android:text="@string/profile_edit_age"
-                    android:textColor="@color/color_FF4E5969"
-                    android:textSize="14sp"
-                    app:layout_constrainedWidth="true"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintHorizontal_bias="0"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toBottomOf="@id/cl_gender" />
-
-                <androidx.appcompat.widget.AppCompatEditText
-                    android:id="@+id/et_user_age"
-                    style="@style/CommonEditText"
-                    android:layout_width="0dp"
-                    android:layout_height="36dp"
-                    android:layout_marginTop="8dp"
-                    android:gravity="start|center_vertical"
-                    android:singleLine="true"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toBottomOf="@id/tv_user_age"
-                    tools:hint="Please input" />
-
-            </androidx.constraintlayout.widget.ConstraintLayout>
+                android:layout_marginTop="36dp"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@id/v_photo_wall" />
+
+<!--            <View-->
+<!--                android:layout_width="0dp"-->
+<!--                android:layout_height="1dp"-->
+<!--                android:layout_marginTop="24dp"-->
+<!--                android:background="@color/color_FFF2F3F5"-->
+<!--                app:layout_constraintEnd_toEndOf="parent"-->
+<!--                app:layout_constraintStart_toStartOf="parent"-->
+<!--                app:layout_constraintTop_toBottomOf="@id/v_person_info" />-->
+
+<!--            <include-->
+<!--                android:id="@+id/v_talent"-->
+<!--                layout="@layout/layout_edit_profile_person_talent"-->
+<!--                android:layout_width="match_parent"-->
+<!--                android:layout_height="wrap_content"-->
+<!--                android:layout_marginTop="36dp"-->
+<!--                app:layout_constraintEnd_toEndOf="parent"-->
+<!--                app:layout_constraintStart_toStartOf="parent"-->
+<!--                app:layout_constraintTop_toBottomOf="@id/v_person_info" />-->
+
 
         </androidx.constraintlayout.widget.ConstraintLayout>
 

+ 1 - 1
module/profile/src/main/res/layout/activity_user_profile.xml

@@ -67,7 +67,7 @@
         app:layout_behavior="@string/appbar_scrolling_view_behavior" />
 
     <include
-        android:id="@+id/topBarContainer"
+        android:id="@+id/top_bar"
         layout="@layout/layout_user_profile_topbar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/common_top_bar_height"

+ 65 - 0
module/profile/src/main/res/layout/dialog_edit_birthday.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/common_bottom_dialog_bg">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/common_top_bar_height"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_nickname"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.appcompat.widget.AppCompatEditText
+        android:id="@+id/et_input"
+        android:layout_width="0dp"
+        android:layout_height="36dp"
+        android:layout_marginHorizontal="16dp"
+        android:background="@drawable/common_input_edit_bg"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="start|center_vertical"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_FF1D2129"
+        android:textColorHint="@color/color_FFC9CDD4"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_tips"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="16dp"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_person_nickname_limit"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="12sp"
+        app:layout_constraintEnd_toEndOf="@id/et_input"
+        app:layout_constraintTop_toBottomOf="@id/et_input" />
+
+    <com.adealink.weparty.commonui.widget.CommonButton
+        android:id="@+id/btn_save"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:layout_marginTop="72dp"
+        android:text="@string/common_save"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_tips" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 114 - 0
module/profile/src/main/res/layout/dialog_edit_gender.xml

@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/common_bottom_dialog_bg">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/common_top_bar_height"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_nickname"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/btn_male"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:background="@drawable/profile_edit_gender_bg"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title">
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_male"
+            android:layout_width="14dp"
+            android:layout_height="14dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/tv_male"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_male_ic" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_male"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dp"
+            android:fontFamily="@font/poppins_semibold"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:text="@string/common_male"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/iv_male"
+            app:layout_constraintTop_toTopOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/btn_female"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:layout_marginTop="12dp"
+        android:background="@drawable/profile_edit_gender_bg"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/btn_male">
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_female"
+            android:layout_width="14dp"
+            android:layout_height="14dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/tv_female"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_female_ic" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_female"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dp"
+            android:fontFamily="@font/poppins_semibold"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:text="@string/common_male"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/iv_female"
+            app:layout_constraintTop_toTopOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <com.adealink.weparty.commonui.widget.CommonButton
+        android:id="@+id/btn_save"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:layout_marginTop="22dp"
+        android:text="@string/common_save"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/btn_female" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 65 - 0
module/profile/src/main/res/layout/dialog_edit_interest.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/common_bottom_dialog_bg">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/common_top_bar_height"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_nickname"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.appcompat.widget.AppCompatEditText
+        android:id="@+id/et_input"
+        android:layout_width="0dp"
+        android:layout_height="36dp"
+        android:layout_marginHorizontal="16dp"
+        android:background="@drawable/common_input_edit_bg"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="start|center_vertical"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_FF1D2129"
+        android:textColorHint="@color/color_FFC9CDD4"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_tips"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="16dp"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_person_nickname_limit"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="12sp"
+        app:layout_constraintEnd_toEndOf="@id/et_input"
+        app:layout_constraintTop_toBottomOf="@id/et_input" />
+
+    <com.adealink.weparty.commonui.widget.CommonButton
+        android:id="@+id/btn_save"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:layout_marginTop="72dp"
+        android:text="@string/common_save"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_tips" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 65 - 0
module/profile/src/main/res/layout/dialog_edit_intro.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/common_bottom_dialog_bg">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/common_top_bar_height"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_nickname"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.appcompat.widget.AppCompatEditText
+        android:id="@+id/et_input"
+        android:layout_width="0dp"
+        android:layout_height="36dp"
+        android:layout_marginHorizontal="16dp"
+        android:background="@drawable/common_input_edit_bg"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="start|center_vertical"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_FF1D2129"
+        android:textColorHint="@color/color_FFC9CDD4"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_tips"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="16dp"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_person_nickname_limit"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="12sp"
+        app:layout_constraintEnd_toEndOf="@id/et_input"
+        app:layout_constraintTop_toBottomOf="@id/et_input" />
+
+    <com.adealink.weparty.commonui.widget.CommonButton
+        android:id="@+id/btn_save"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:layout_marginTop="72dp"
+        android:text="@string/common_save"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_tips" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 67 - 0
module/profile/src/main/res/layout/dialog_edit_nickname.xml

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/common_bottom_dialog_bg">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/common_top_bar_height"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_nickname"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.appcompat.widget.AppCompatEditText
+        android:id="@+id/et_input"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="16dp"
+        android:background="@drawable/common_input_edit_bg"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="start|center_vertical"
+        android:includeFontPadding="false"
+        android:paddingHorizontal="12dp"
+        android:paddingVertical="8dp"
+        android:textColor="@color/color_FF1D2129"
+        android:textColorHint="@color/color_FFC9CDD4"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_tips"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="16dp"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_person_nickname_limit"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="12sp"
+        app:layout_constraintEnd_toEndOf="@id/et_input"
+        app:layout_constraintTop_toBottomOf="@id/et_input" />
+
+    <com.adealink.weparty.commonui.widget.CommonButton
+        android:id="@+id/btn_save"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:layout_marginTop="72dp"
+        android:text="@string/common_save"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_tips" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 30 - 0
module/profile/src/main/res/layout/dialog_edit_talent_voice.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/common_bottom_dialog_bg">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/common_top_bar_height"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_talent_voice_title"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="16sp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.fragment.app.FragmentContainerView
+        android:id="@+id/fl_content"
+        android:layout_width="match_parent"
+        android:layout_height="240dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 30 - 0
module/profile/src/main/res/layout/fragment_edit_talent_voice.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="240dp">
+
+    <com.adealink.weparty.module.playmate.widget.SoundView
+        android:id="@+id/v_sound"
+        android:layout_width="160dp"
+        android:layout_height="32dp"
+        app:layout_constraintBottom_toTopOf="@id/btn_record"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.37"
+        app:sound_duration_text_gravity="end"
+        app:sound_duration_text_size="12sp"
+        app:sound_show_wave="true" />
+
+    <com.adealink.weparty.commonui.widget.CommonButton
+        android:id="@+id/btn_record"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:text="@string/profile_edit_talent_voice_delete_record"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 157 - 0
module/profile/src/main/res/layout/fragment_edit_talent_voice_submit.xml

@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="240dp">
+
+    <!--录制-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_record"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:layout_constraintBottom_toTopOf="@id/btn_submit"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_duration"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constraintBottom_toTopOf="@id/btn_record"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            tools:text="00:00" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/btn_record"
+            android:layout_width="70dp"
+            android:layout_height="70dp"
+            android:layout_marginTop="12dp"
+            app:layout_constraintBottom_toTopOf="@id/tv_duration_tips"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_duration"
+            app:srcCompat="@drawable/profile_edit_talent_voice_record_ic" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_duration_tips"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:text="@string/profile_edit_talent_voice_record"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/btn_record"
+            app:layout_constraintVertical_chainStyle="packed" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <!--重录,试听-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_preview"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toTopOf="@id/btn_submit"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_preview_duration"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            tools:text="00:00" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/btn_re_record"
+            android:layout_width="70dp"
+            android:layout_height="70dp"
+            android:layout_marginTop="50dp"
+            app:layout_constraintEnd_toStartOf="@id/btn_preview"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            app:srcCompat="@drawable/profile_edit_talent_voice_re_record_ic" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_re_record"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:maxLines="2"
+            android:text="@string/profile_edit_talent_voice_re_record"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constraintEnd_toEndOf="@id/btn_re_record"
+            app:layout_constraintStart_toStartOf="@id/btn_re_record"
+            app:layout_constraintTop_toBottomOf="@id/btn_re_record"
+            app:layout_constraintVertical_chainStyle="packed"
+            app:layout_constraintWidth_max="120dp" />
+
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/btn_preview"
+            android:layout_width="70dp"
+            android:layout_height="70dp"
+            android:layout_marginTop="50dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/btn_re_record"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            app:srcCompat="@drawable/profile_edit_talent_voice_preview_ic" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_preview"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:maxLines="2"
+            android:text="@string/profile_edit_talent_voice_preview"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constraintEnd_toEndOf="@id/btn_preview"
+            app:layout_constraintStart_toStartOf="@id/btn_preview"
+            app:layout_constraintTop_toBottomOf="@id/btn_preview"
+            app:layout_constraintVertical_chainStyle="packed"
+            app:layout_constraintWidth_max="120dp" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+    <com.adealink.weparty.commonui.widget.CommonButton
+        android:id="@+id/btn_submit"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/common_button_height"
+        android:layout_marginHorizontal="20dp"
+        android:text="@string/common_submit"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 48 - 0
module/profile/src/main/res/layout/item_edit_profile_add_photo.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    tools:layout_height="100dp"
+    tools:layout_width="100dp">
+
+    <View
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="@drawable/profile_add_photo_bg"
+        app:layout_constraintDimensionRatio="1:1"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/btn_add_picture"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        app:layout_constraintBottom_toTopOf="@id/tv_add_desc"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:srcCompat="@drawable/profile_add_photo_ic" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_add_desc"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
+        android:ellipsize="end"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:maxLines="3"
+        android:text="@string/profile_edit_photo_wall_tips_1"
+        android:textColor="@color/color_FF4E5969"
+        android:textSize="11sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/btn_add_picture"
+        app:layout_constraintWidth_percent="0.6" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 31 - 0
module/profile/src/main/res/layout/item_edit_profile_photo.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    tools:layout_height="100dp"
+    tools:layout_width="100dp">
+
+    <com.adealink.frame.image.view.NetworkImageView
+        android:id="@+id/iv_picture"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintDimensionRatio="1:1"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:roundedCornerRadius="10dp" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_delete"
+        android:layout_width="20dp"
+        android:layout_height="20dp"
+        android:paddingStart="0dp"
+        android:paddingTop="6dp"
+        android:paddingEnd="6dp"
+        app:layout_constraintEnd_toEndOf="@id/iv_picture"
+        app:layout_constraintTop_toTopOf="@id/iv_picture"
+        app:srcCompat="@drawable/common_remove_picture_ic" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 287 - 0
module/profile/src/main/res/layout/layout_edit_profile_person_info.xml

@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:fontFamily="@font/poppins_semibold"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_person_info"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="14sp"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <!--昵称-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_nickname"
+        android:layout_width="match_parent"
+        android:layout_height="36dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_nickname_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:includeFontPadding="false"
+            android:text="@string/profile_edit_person_nickname"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_nickname"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="end|center_vertical"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/iv_nick_name_go"
+            app:layout_constraintHorizontal_bias="1"
+            app:layout_constraintStart_toEndOf="@id/tv_nickname_title"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_percent="0.6" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_nick_name_go"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_go_ic" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <!--性别-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_gender"
+        android:layout_width="match_parent"
+        android:layout_height="36dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/cl_nickname">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_gender_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:includeFontPadding="false"
+            android:text="@string/profile_edit_person_gender"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_gender"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="end|center_vertical"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/iv_gender_go"
+            app:layout_constraintHorizontal_bias="1"
+            app:layout_constraintStart_toEndOf="@id/tv_gender_title"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_percent="0.6" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_gender_go"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_go_ic" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <!--生日-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_birthday"
+        android:layout_width="match_parent"
+        android:layout_height="36dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/cl_gender">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_birthday_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:includeFontPadding="false"
+            android:text="@string/profile_edit_person_birthday"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_birthday"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="end|center_vertical"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/iv_birthday_go"
+            app:layout_constraintHorizontal_bias="1"
+            app:layout_constraintStart_toEndOf="@id/tv_birthday_title"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_percent="0.6" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_birthday_go"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_go_ic" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <!--个性签名-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_intro"
+        android:layout_width="match_parent"
+        android:layout_height="36dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/cl_birthday">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_intro_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:includeFontPadding="false"
+            android:text="@string/profile_edit_person_intro"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_intro"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="end|center_vertical"
+            android:hint="@string/profile_edit_person_intro_desc"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:textColor="@color/color_FF1D2129"
+            android:textColorHint="@color/color_FF3FBFBD"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/iv_intro_go"
+            app:layout_constraintHorizontal_bias="1"
+            app:layout_constraintStart_toEndOf="@id/tv_intro_title"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_percent="0.6" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_intro_go"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_go_ic" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <!--兴趣-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_interest"
+        android:layout_width="match_parent"
+        android:layout_height="36dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/cl_intro">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_interest_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:includeFontPadding="false"
+            android:text="@string/profile_edit_person_interest"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_interest"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="end|center_vertical"
+            android:hint="@string/profile_edit_person_interest_desc"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:textColor="@color/color_FF1D2129"
+            android:textColorHint="@color/color_FF3FBFBD"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/iv_interest_go"
+            app:layout_constraintHorizontal_bias="1"
+            app:layout_constraintStart_toEndOf="@id/tv_interest_title"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_percent="0.6" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_interest_go"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_go_ic" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 77 - 0
module/profile/src/main/res/layout/layout_edit_profile_person_talent.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:fontFamily="@font/poppins_semibold"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_talent"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="14sp"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <!--声音-->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_voice"
+        android:layout_width="match_parent"
+        android:layout_height="36dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_voice_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:includeFontPadding="false"
+            android:text="@string/profile_edit_talent_voice"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintHorizontal_bias="0"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_voice"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="end|center_vertical"
+            android:hint="@string/profile_edit_talent_voice_desc"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:textColor="@color/color_FF1D2129"
+            android:textColorHint="@color/color_FF3FBFBD"
+            android:textSize="14sp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/iv_voice_go"
+            app:layout_constraintHorizontal_bias="1"
+            app:layout_constraintStart_toEndOf="@id/tv_voice_title"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_percent="0.6" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_voice_go"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_go_ic" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 47 - 0
module/profile/src/main/res/layout/layout_edit_profile_photo_wall.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clipChildren="false">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:fontFamily="@font/poppins_semibold"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_photo_wall_title"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="14sp"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_desc"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
+        android:includeFontPadding="false"
+        android:text="@string/profile_edit_photo_wall_desc"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="12sp"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_title" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/rv_photo"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_desc" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 2 - 2
module/profile/src/main/res/layout/layout_profile_search_item.xml

@@ -92,7 +92,6 @@
         android:id="@+id/btn_follow"
         android:layout_width="wrap_content"
         android:layout_height="22dp"
-        android:background="@drawable/profile_follow_btn_bg_sel"
         android:gravity="center"
         android:minWidth="56dp"
         android:paddingHorizontal="4.5dp"
@@ -100,6 +99,7 @@
         android:textColor="@color/white"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent"
+        tools:background="@drawable/profile_follow_btn_bg" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 94 - 9
module/profile/src/main/res/layout/layout_user_profile_topbar.xml

@@ -15,17 +15,102 @@
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/commonui_back_white_48_ic" />
 
+    <com.adealink.weparty.commonui.imageview.AvatarView
+        android:id="@+id/iv_avatar"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_marginStart="12dp"
+        android:alpha="0"
+        app:layout_constraintBottom_toBottomOf="@id/iv_back"
+        app:layout_constraintStart_toEndOf="@id/iv_back"
+        app:layout_constraintTop_toTopOf="@id/iv_back"
+        tools:alpha="1" />
+
     <androidx.appcompat.widget.AppCompatTextView
-        android:id="@+id/tv_title"
-        android:layout_width="match_parent"
-        android:layout_height="44dp"
+        android:id="@+id/tv_user_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="12dp"
+        android:alpha="0"
         android:ellipsize="end"
-        android:gravity="center"
-        android:maxLines="1"
-        android:textColor="@color/color_222222"
-        android:textSize="18sp"
-        android:textStyle="bold"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="start|center_vertical"
+        android:includeFontPadding="false"
+        android:singleLine="true"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="15sp"
+        app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
+        app:layout_constraintEnd_toStartOf="@id/btn_share"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintStart_toEndOf="@id/iv_avatar"
+        app:layout_constraintTop_toTopOf="@id/iv_avatar"
+        tools:alpha="1"
+        tools:text="HelloWorld"
+        tools:visibility="visible" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/btn_share"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:padding="4dp"
+        tools:background="@drawable/profile_top_bar_button_bg"
+        app:layout_constraintBottom_toBottomOf="@id/btn_edit"
+        app:layout_constraintEnd_toStartOf="@id/btn_more"
+        app:layout_constraintStart_toEndOf="@id/tv_user_name"
+        app:layout_constraintTop_toTopOf="@id/btn_edit"
+        app:srcCompat="@drawable/profile_share_ic" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/btn_more"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:padding="4dp"
+        tools:background="@drawable/profile_top_bar_button_bg"
+        android:layout_marginStart="12dp"
+        app:layout_constraintBottom_toBottomOf="@id/btn_edit"
+        app:layout_constraintEnd_toStartOf="@id/btn_edit"
+        app:layout_constraintStart_toEndOf="@id/btn_share"
+        app:layout_constraintTop_toTopOf="@id/btn_edit"
+        app:srcCompat="@drawable/profile_more_ic" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/btn_edit"
+        android:layout_width="wrap_content"
+        android:layout_height="32dp"
+        android:layout_marginStart="12dp"
+        android:background="@drawable/profile_edit_button_bg"
+        android:minWidth="55dp"
+        android:paddingHorizontal="6dp"
         app:layout_constraintBottom_toBottomOf="parent"
-        tools:text="HelloWorld" />
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/btn_more"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_edit"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/tv_edit"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/profile_edit_ic" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_edit"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:includeFontPadding="false"
+            android:text="@string/common_edit"
+            android:textColor="@color/white"
+            android:textSize="15sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/iv_edit"
+            app:layout_constraintTop_toTopOf="parent" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 30 - 0
module/profile/src/main/res/values/strings.xml

@@ -33,4 +33,34 @@
     <string name="profile_me_follower">Follower</string>
     <string name="profile_me_fans">Fans</string>
     <string name="profile_me_function_center">Function Center</string>
+    <string name="profile_edit_photo_wall_title">照片墙(%1$s/%2$s)</string>
+    <string name="profile_edit_photo_wall_desc">建议上传清晰的照片,便于全方位展示形象</string>
+    <string name="profile_edit_photo_wall_tips_1">我的旅行日志</string>
+    <string name="profile_edit_photo_wall_tips_2">我的有趣自拍</string>
+    <string name="profile_edit_photo_wall_tips_3">我的日常生活</string>
+    <string name="profile_edit_photo_wall_tips_4">独一无二的才艺</string>
+    <string name="profile_edit_photo_wall_tips_5">独一无二的才艺</string>
+    <string name="profile_edit_photo_wall_tips_6">我最买的角度</string>
+    <string name="profile_edit_photo_wall_tips_7">我热爱的运动</string>
+    <string name="profile_edit_photo_wall_tips_8">我最喜欢做的事</string>
+    <string name="profile_edit_photo_wall_tips_9">我喜欢的穿搭</string>
+    <string name="profile_edit_person_info">个人信息</string>
+    <string name="profile_edit_person_nickname">昵称</string>
+    <string name="profile_edit_person_nickname_limit">最多可输入%s个字符</string>
+    <string name="profile_edit_person_gender">性别</string>
+    <string name="profile_edit_person_birthday">出生日期</string>
+    <string name="profile_edit_person_intro">个性签名</string>
+    <string name="profile_edit_person_intro_desc">有什么想说给朋友听</string>
+    <string name="profile_edit_person_interest">兴趣</string>
+    <string name="profile_edit_person_interest_desc">让更多朋友了解你</string>
+    <string name="profile_edit_talent">才艺展示</string>
+    <string name="profile_edit_talent_voice">声音</string>
+    <string name="profile_edit_talent_voice_desc">用声音介绍你自己</string>
+    <string name="profile_edit_nickname_empty">昵称不能为空</string>
+    <string name="profile_edit_talent_voice_title">设置声音</string>
+    <string name="profile_edit_talent_voice_record">点击开始录音</string>
+    <string name="profile_edit_talent_voice_stop">点击结束录音</string>
+    <string name="profile_edit_talent_voice_re_record">重录</string>
+    <string name="profile_edit_talent_voice_preview">试听</string>
+    <string name="profile_edit_talent_voice_delete_record">删除并重新录制</string>
 </resources>

+ 0 - 5
module/setting/src/main/java/com/adealink/weparty/setting/helpcenter/HelpCenterActivity.kt

@@ -5,12 +5,9 @@ import android.text.Editable
 import android.text.TextWatcher
 import androidx.activity.viewModels
 import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.core.view.setPadding
 import androidx.core.view.updateLayoutParams
 import androidx.recyclerview.widget.GridLayoutManager
 import com.adealink.frame.aab.util.getCompatDimension
-import com.adealink.frame.aab.util.getCompatString
-import com.adealink.frame.base.AppBase
 import com.adealink.frame.base.fastLazy
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.router.Router
@@ -22,10 +19,8 @@ import com.adealink.weparty.commonui.BaseActivity
 import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
 import com.adealink.weparty.commonui.recycleview.itemdecoration.GridSpacingItemDecoration
-import com.adealink.weparty.imageselect.clip.avatarClipParam
 import com.adealink.weparty.imageselect.comp.TakeFromAlbumComp
 import com.adealink.weparty.module.setting.Setting
-import com.adealink.weparty.setting.R
 import com.adealink.weparty.setting.databinding.ActivityHelpCenterBinding
 import com.adealink.weparty.setting.helpcenter.adapter.AddPictureItemViewBinder
 import com.adealink.weparty.setting.helpcenter.adapter.PictureItemViewBinder

+ 1 - 1
module/setting/src/main/res/layout/item_setting_help_add_picture.xml

@@ -24,6 +24,6 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
-        app:srcCompat="@drawable/setting_add_picture_ic" />
+        app:srcCompat="@drawable/common_add_picture_ic" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 1
module/setting/src/main/res/layout/item_setting_help_picture.xml

@@ -26,6 +26,6 @@
         android:paddingEnd="6dp"
         app:layout_constraintEnd_toEndOf="@id/iv_picture"
         app:layout_constraintTop_toTopOf="@id/iv_picture"
-        app:srcCompat="@drawable/setting_help_remove_picture_ic" />
+        app:srcCompat="@drawable/common_remove_picture_ic" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>