Răsfoiți Sursa

feat: CountrySelectActivity

XiaodongLin 1 an în urmă
părinte
comite
77b1bfeebd

+ 2 - 0
app/src/main/java/com/adealink/weparty/module/profile/Router.kt

@@ -59,6 +59,8 @@ interface Profile {
     interface CountrySelect {
         companion object {
             const val PATH = "/countrySelect"
+            const val EXTRA_FROM = "extra_from"
+            const val EXTRA_SELECTED_COUNTRY = "extra_selected_country"
         }
     }
 

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

@@ -455,6 +455,7 @@ data class CountryConfigVersion(
     @SerializedName("version") val version: Int,
 )
 
+@Parcelize
 data class CountryResource(
     @SerializedName("iconUrl")
     val iconUrl: String,
@@ -468,7 +469,7 @@ data class CountryResource(
     val status: Int,
     @SerializedName("hot")
     val hot: Int,//0:非热门,1:热门
-)
+) : Parcelable
 
 enum class CountryStatus(val status: Int) {
     OFFLINE(0), //已下线

+ 2 - 0
app/src/main/java/com/adealink/weparty/ui/home/BaseHomeFragment.kt

@@ -72,6 +72,7 @@ abstract class BaseHomeFragment : BaseFragment, ITabManager {
     private val familyInfoViewModel by fastLazy { FamilyModule.getFamilyInfoViewModel(this.requireActivity()) }
     private val medalViewModel by fastLazy { MedalModule.getMedalViewModel(this) }
     protected val operationViewModel by fastLazy { OperationModule.getOperationViewModel(this.requireActivity()) }
+    private val countryViewModel by fastLazy { ProfileModule.getCountryViewModel(this) }
 
     private lateinit var homePagerAdapter: HomePagerAdapter
 
@@ -155,6 +156,7 @@ abstract class BaseHomeFragment : BaseFragment, ITabManager {
         BackpackModule.checkGiftBackpack()
         RoomModule.init()
         GameModule.checkPlayingGame()
+        countryViewModel?.getCountryList(true)
     }
 
     private val minorLoad by fastLazy {

+ 4 - 0
module/profile/src/main/AndroidManifest.xml

@@ -49,5 +49,9 @@
             android:name=".edit.EditPersonProfileActivity"
             android:screenOrientation="portrait"
             android:theme="@style/AppTheme" />
+        <activity
+            android:name=".country.CountrySelectActivity"
+            android:screenOrientation="portrait"
+            android:theme="@style/AppTheme" />
     </application>
 </manifest>

+ 73 - 0
module/profile/src/main/java/com/adealink/weparty/profile/country/CountrySelectActivity.kt

@@ -0,0 +1,73 @@
+package com.adealink.weparty.profile.country
+
+import android.app.Activity
+import android.content.Intent
+import androidx.activity.viewModels
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.adealink.frame.base.fastLazy
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.frame.router.annotation.RouterUri
+import com.adealink.weparty.commonui.BaseActivity
+import com.adealink.weparty.commonui.recycleview.adapter.multitype.MultiTypeAdapter
+import com.adealink.weparty.module.profile.Profile
+import com.adealink.weparty.profile.country.data.CountryData
+import com.adealink.weparty.profile.country.data.CountryItemData
+import com.adealink.weparty.profile.country.listener.ICountryItemListener
+import com.adealink.weparty.profile.country.manager.countryManager
+import com.adealink.weparty.profile.country.view.CountryItemViewBinder
+import com.adealink.weparty.profile.country.view.CountrySectionItemViewBinder
+import com.adealink.weparty.profile.country.viewmodel.CountryViewModel
+import com.adealink.weparty.profile.databinding.ActivityCountrySelectBinding
+import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
+import com.qmuiteam.qmui.widget.util.QMUIStatusBarHelper
+
+/**
+ * 端内的国家选择页面,区分于SmsCountrySelectActivity
+ * Created by XiaoDongLin.
+ * Date: 2025/3/11
+ */
+@RouterUri(path = [Profile.CountrySelect.PATH], desc = "国家选择")
+class CountrySelectActivity : BaseActivity(), ICountryItemListener {
+    val binding by viewBinding(ActivityCountrySelectBinding::inflate)
+    private val listAdapter by fastLazy { MultiTypeAdapter() }
+    private val countryViewModel by viewModels<CountryViewModel> { ProfileViewModelFactory() }
+    private val source by fastLazy { intent.getStringExtra(Profile.CountrySelect.EXTRA_FROM) }
+
+    override fun initViews() {
+        QMUIStatusBarHelper.setStatusBarLightMode(this)
+        setContentView(binding.root)
+        listAdapter.register(CountryItemViewBinder(this))
+        binding.rvCountry.apply {
+            adapter = listAdapter
+            layoutManager = LinearLayoutManager(this@CountrySelectActivity)
+        }
+    }
+
+    override fun observeViewModel() {
+        countryViewModel.countryListLD.observe(this) {
+            val allCountryDataList = mutableListOf<CountryItemData>()
+            it.forEach { countryRes ->
+                val countryData = CountryData(
+                    countryCode = countryRes.code,
+                    nationFlag = countryRes.iconUrl,
+                    country = countryManager.getCountryName(countryRes.code)
+                )
+                allCountryDataList.add(countryData)
+            }
+            listAdapter.items = allCountryDataList
+            listAdapter.notifyDataSetChanged()
+        }
+    }
+
+    override fun loadData() {
+        countryViewModel.getCountryList(true)
+    }
+
+    override fun onCountrySelect(countryData: CountryData) {
+        val intent = Intent()
+        intent.putExtra(Profile.CountrySelect.EXTRA_SELECTED_COUNTRY, countryData)
+        intent.putExtra(Profile.CountrySelect.EXTRA_FROM, source)
+        setResult(Activity.RESULT_OK, intent)
+        finish()
+    }
+}

+ 42 - 0
module/profile/src/main/java/com/adealink/weparty/profile/country/SelectCountryContract.kt

@@ -0,0 +1,42 @@
+package com.adealink.weparty.profile.country
+
+import android.content.Context
+import android.content.Intent
+import androidx.activity.result.contract.ActivityResultContract
+import com.adealink.frame.log.Log
+import com.adealink.weparty.module.profile.Profile
+import com.adealink.weparty.profile.country.data.CountryData
+
+/**
+ * Created by XiaoDongLin.
+ * Date: 2025/3/11
+ */
+
+val SOURCE_SELECT_PLACE_OF_BIRTH = "SelectPlaceOfBirth"
+val SOURCE_SELECT_CURRENT_PLACE = "SelectCurrentPlace"
+
+
+data class SelectCountryRequest(val source: String)
+data class SelectCountryResult(val source: String, val countryData: CountryData? = null)
+
+class SelectCountryContract :
+    ActivityResultContract<SelectCountryRequest, SelectCountryResult?>() {
+    override fun createIntent(context: Context, input: SelectCountryRequest): Intent {
+        Log.i("SelectCountryContract", "createIntent")
+        return Intent(context, CountrySelectActivity::class.java).apply {
+            putExtra(Profile.CountrySelect.EXTRA_FROM, input.source)
+        }
+    }
+
+    override fun parseResult(resultCode: Int, intent: Intent?): SelectCountryResult? {
+        val source = intent?.getStringExtra(Profile.CountrySelect.EXTRA_FROM) ?: ""
+        val selectCountry =
+            intent?.getParcelableExtra<CountryData>(Profile.CountrySelect.EXTRA_SELECTED_COUNTRY)
+        Log.i("SelectCountryContract", "parseResult:$selectCountry")
+        return SelectCountryResult(
+            source = source,
+            countryData = selectCountry
+        )
+    }
+
+}

+ 48 - 0
module/profile/src/main/java/com/adealink/weparty/profile/country/SelectCountryLifecycleObserver.kt

@@ -0,0 +1,48 @@
+package com.adealink.weparty.profile.country
+
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.ActivityResultRegistry
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.LifecycleOwner
+import com.adealink.weparty.profile.country.data.CountryData
+
+/**
+ * Created by XiaoDongLin.
+ * Date: 2025/3/11
+ */
+abstract class SelectCountryLifecycleObserver(private val registry: ActivityResultRegistry) :
+    DefaultLifecycleObserver {
+
+    private lateinit var countryLauncher: ActivityResultLauncher<SelectCountryRequest>
+
+    override fun onCreate(owner: LifecycleOwner) {
+        countryLauncher =
+            registry.register("SelectCountryContract", SelectCountryContract()) { data ->
+                data ?: return@register
+                onResult(data.source, data.countryData)
+            }
+    }
+
+    override fun onStart(owner: LifecycleOwner) {
+    }
+
+    override fun onResume(owner: LifecycleOwner) {
+    }
+
+    override fun onDestroy(owner: LifecycleOwner) {
+    }
+
+    override fun onPause(owner: LifecycleOwner) {
+    }
+
+    override fun onStop(owner: LifecycleOwner) {
+    }
+
+
+    fun launch(source: String) {
+        countryLauncher.launch(SelectCountryRequest(source))
+    }
+
+    abstract fun onResult(source: String, countryData: CountryData?)
+
+}

+ 9 - 1
module/profile/src/main/java/com/adealink/weparty/profile/country/data/CountryData.kt

@@ -1,7 +1,15 @@
 package com.adealink.weparty.profile.country.data
 
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+
 sealed class CountryItemData
-class CountryData(val nationFlag: String, val countryCode: String, val country: String): CountryItemData()
+
+@Parcelize
+class CountryData(val nationFlag: String, val countryCode: String, val country: String): CountryItemData(),
+    Parcelable
+
+
 class CountrySectionData(val section: CountrySection): CountryItemData()
 
 enum class CountrySection{

+ 3 - 1
module/profile/src/main/java/com/adealink/weparty/profile/country/listener/ICountryItemListener.kt

@@ -1,5 +1,7 @@
 package com.adealink.weparty.profile.country.listener
 
+import com.adealink.weparty.profile.country.data.CountryData
+
 interface ICountryItemListener {
-    fun onCountrySelect(countryCode: String)
+    fun onCountrySelect(countryData: CountryData)
 }

+ 4 - 4
module/profile/src/main/java/com/adealink/weparty/profile/country/view/CountryItemViewBinder.kt

@@ -4,10 +4,10 @@ import android.annotation.SuppressLint
 import android.view.LayoutInflater
 import android.view.ViewGroup
 import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
+import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
 import com.adealink.weparty.profile.country.data.CountryData
 import com.adealink.weparty.profile.country.listener.ICountryItemListener
 import com.adealink.weparty.profile.databinding.LayoutCountryItemBinding
-import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
 
 class CountryItemViewBinder(private val countryListItem: ICountryItemListener) :
     ItemViewBinder<CountryData, BindingViewHolder<LayoutCountryItemBinding>>() {
@@ -17,10 +17,10 @@ class CountryItemViewBinder(private val countryListItem: ICountryItemListener) :
         holder: BindingViewHolder<LayoutCountryItemBinding>,
         item: CountryData,
     ) {
-        holder.binding.ivCountryFlag.setImageUrl(item.nationFlag)
-        holder.binding.tvCountry.text = item.country
+        holder.binding.nationalFlag.setImageUrl(item.nationFlag)
+        holder.binding.localeCountry.text = item.country
         holder.binding.root.setOnClickListener {
-            countryListItem.onCountrySelect(item.countryCode)
+            countryListItem.onCountrySelect(item)
         }
     }
 

+ 31 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/viewcomp/BasicDataViewComponent.kt

@@ -8,6 +8,10 @@ import com.adealink.weparty.commonui.widget.wheel.WheelBirthdayPickerDialogFragm
 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.profile.country.SOURCE_SELECT_CURRENT_PLACE
+import com.adealink.weparty.profile.country.SOURCE_SELECT_PLACE_OF_BIRTH
+import com.adealink.weparty.profile.country.SelectCountryLifecycleObserver
+import com.adealink.weparty.profile.country.data.CountryData
 import com.adealink.weparty.profile.databinding.LayoutEditProfileBasicDataBinding
 
 /**
@@ -19,12 +23,39 @@ class BasicDataViewComponent(
     private val binding: LayoutEditProfileBasicDataBinding
 ) : BaseProfileEditViewComponent(lifecycleOwner) {
 
+
+    private lateinit var selectCountryObserver: SelectCountryLifecycleObserver
+
     override fun initView() {
         binding.tvNickName.onClick {
             Router.build(requireActivity(), Profile.EditNickName.PATH)
                 .start()
         }
+        binding.tvPlaceOfBirth.onClick {
+            selectCountryObserver.launch(SOURCE_SELECT_PLACE_OF_BIRTH)
+        }
+        binding.tvCurrentResidence.onClick {
+            selectCountryObserver.launch(SOURCE_SELECT_CURRENT_PLACE)
+        }
 
+        selectCountryObserver =
+            object : SelectCountryLifecycleObserver(requireActivity().activityResultRegistry) {
+                override fun onResult(source: String, countryData: CountryData?) {
+                    val newUserInfo = ProfileModule.getMyUserInfo() ?: return
+
+                    if (source == SOURCE_SELECT_PLACE_OF_BIRTH) {
+                        profileViewModel?.updateUserInfo(
+                            userInfo = newUserInfo.copy(country = countryData?.country)
+                        )
+                    } else if (source == SOURCE_SELECT_CURRENT_PLACE) {
+                        profileViewModel?.updateUserInfo(
+                            userInfo = newUserInfo.copy(liveCountry = countryData?.country)
+                        )
+                    }
+
+                }
+            }
+        lifecycle.addObserver(selectCountryObserver)
     }
 
 

+ 22 - 0
module/profile/src/main/res/layout/activity_country_select.xml

@@ -0,0 +1,22 @@
+<?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="match_parent"
+    android:fitsSystemWindows="true">
+
+    <com.adealink.weparty.commonui.widget.CommonTopBar
+        android:id="@+id/top_bar"
+        android:layout_width="match_parent"
+        android:layout_height="44dp"
+        app:layout_constraintTop_toTopOf="parent"
+        app:top_bar_title="@string/profile_countries" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/rv_country"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/top_bar" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 18 - 19
module/profile/src/main/res/layout/layout_country_item.xml

@@ -1,37 +1,36 @@
 <?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="40dp"
-    xmlns:tools="http://schemas.android.com/tools">
+    android:layout_height="wrap_content"
+    android:background="?attr/selectableItemBackground"
+    android:minHeight="60dp"
+    android:paddingHorizontal="16dp">
 
     <com.adealink.frame.image.view.NetworkImageView
-        android:id="@+id/iv_country_flag"
+        android:id="@+id/national_flag"
         android:layout_width="24dp"
         android:layout_height="16dp"
-        android:layout_marginStart="16dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
     <androidx.appcompat.widget.AppCompatTextView
-        android:id="@+id/tv_country"
-        android:layout_width="wrap_content"
+        android:id="@+id/locale_country"
+        style="@style/RtlTextViewStyle"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="16dp"
-        android:gravity="start"
-        android:textColor="@color/color_FF25252F"
+        android:layout_marginHorizontal="9dp"
+        android:ellipsize="end"
+        android:singleLine="true"
+        android:textColor="@color/color_222222"
         android:textSize="16sp"
-        tools:text="KSA"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toEndOf="@id/iv_country_flag"
-        app:layout_constraintTop_toTopOf="parent" />
-    <View
-        android:id="@+id/bottom_line"
-        android:layout_width="match_parent"
-        android:layout_height="0.5dp"
-        android:layout_marginStart="16dp"
-        android:background="@color/color_FFE9E9E9"
-        app:layout_constraintBottom_toBottomOf="parent" />
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/national_flag"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_chainStyle="packed"
+        tools:text="中国" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>