From f6c2354f4c1dce595643475c4f86ac89eb9b1fb6 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 13 Dec 2023 15:34:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5peko=EF=BC=9A=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E5=9C=B0=E5=8C=BA=E9=80=89=E6=8B=A9=E5=99=A8=E4=BC=98?= =?UTF-8?q?=E5=8C=96=EF=BC=88=E8=B0=83=E6=95=B4=E5=9C=B0=E5=8C=BA=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E3=80=81=E6=94=AF=E6=8C=81=E5=AD=97=E6=AF=8D=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=E3=80=81=E6=9C=89=E6=95=88=E5=B1=95=E7=A4=BA=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E5=9C=B0=E5=8C=BA=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/hot_region.json | 1 + app/src/main/assets/region.json | 1 + .../com/chwl/app/ui/login/AreaCodeActivity.kt | 89 +++++---- .../chwl/app/ui/login/BindPhoneActivity.kt | 2 + .../app/ui/login/LoginPasswordActivity.java | 2 + .../chwl/app/ui/login/LoginPhoneActivity.kt | 2 + .../chwl/app/ui/login/RegionListAdapter.kt | 32 ++++ .../app/ui/setting/ResetPasswordActivity.kt | 2 + .../app/ui/setting/VerifyPhoneActivity.kt | 2 + .../com/chwl/app/ui/widget/SideBarView.kt | 146 +++++++++++++++ .../main/res/layout/activity_area_code.xml | 10 + .../{item_country.xml => region_item_def.xml} | 0 app/src/main/res/layout/region_item_group.xml | 46 +++++ app/src/main/res/values/arrays.xml | 171 ------------------ .../java/com/chwl/core/auth/AuthModel.java | 24 --- .../com/chwl/core/auth/bean/AreaInfoBean.kt | 15 -- .../xchat_android_core/region/RegionHelper.kt | 118 ++++++++++++ .../region/bean/RegionBean.kt | 48 +++++ .../com/example/lib_utils/TelephonyUtils.kt | 83 +++++---- 19 files changed, 505 insertions(+), 289 deletions(-) create mode 100644 app/src/main/assets/hot_region.json create mode 100644 app/src/main/assets/region.json create mode 100644 app/src/main/java/com/chwl/app/ui/login/RegionListAdapter.kt create mode 100644 app/src/main/java/com/chwl/app/ui/widget/SideBarView.kt rename app/src/main/res/layout/{item_country.xml => region_item_def.xml} (100%) create mode 100644 app/src/main/res/layout/region_item_group.xml delete mode 100644 core/src/main/java/com/chwl/core/auth/bean/AreaInfoBean.kt create mode 100644 core/src/main/java/com/yizhuan/xchat_android_core/region/RegionHelper.kt create mode 100644 core/src/main/java/com/yizhuan/xchat_android_core/region/bean/RegionBean.kt diff --git a/app/src/main/assets/hot_region.json b/app/src/main/assets/hot_region.json new file mode 100644 index 000000000..1f6bad501 --- /dev/null +++ b/app/src/main/assets/hot_region.json @@ -0,0 +1 @@ +[{"name":"Taiwan","abbr":"TW","mcc":"466","code":"886"},{"name":"Hong Kong","abbr":"HK","mcc":"454","code":"852"},{"name":"Singapore","abbr":"SG","mcc":"525","code":"65"},{"name":"Malaysia","abbr":"MY","mcc":"502","code":"60"},{"name":"China","abbr":"CN","mcc":"460","code":"86"}] \ No newline at end of file diff --git a/app/src/main/assets/region.json b/app/src/main/assets/region.json new file mode 100644 index 000000000..aa34d9418 --- /dev/null +++ b/app/src/main/assets/region.json @@ -0,0 +1 @@ +[{"name":"Afghanistan","abbr":"AF","mcc":"412","code":"93"},{"name":"Albania","abbr":"AL","mcc":"276","code":"355"},{"name":"Algeria","abbr":"DZ","mcc":"603","code":"213"},{"name":"American Samoa","abbr":"AS","mcc":"544","code":"1684"},{"name":"Andorra","abbr":"AD","mcc":"213","code":"376"},{"name":"Angola","abbr":"AO","mcc":"631","code":"244"},{"name":"Anguilla","abbr":"AI","mcc":"365","code":"1264"},{"name":"Antigua and Barbuda","abbr":"AG","mcc":"344","code":"1268"},{"name":"Argentina","abbr":"AR","mcc":"722","code":"54"},{"name":"Aruba","abbr":"AW","mcc":"363","code":"297"},{"name":"Australia","abbr":"AU","mcc":"505","code":"61"},{"name":"Austria","abbr":"AT","mcc":"232","code":"43"},{"name":"Azerbaijan","abbr":"AZ","mcc":"400","code":"994"},{"name":"Bahamas","abbr":"BS","mcc":"364","code":"1242"},{"name":"Bahrain","abbr":"BH","mcc":"426","code":"973"},{"name":"Bangladesh","abbr":"BD","mcc":"470","code":"880"},{"name":"Barbados","abbr":"BB","mcc":"342","code":"1246"},{"name":"Belarus","abbr":"BY","mcc":"257","code":"375"},{"name":"Belgium","abbr":"BE","mcc":"206","code":"32"},{"name":"Belize","abbr":"BZ","mcc":"702","code":"501"},{"name":"Benin","abbr":"BJ","mcc":"616","code":"229"},{"name":"Bermuda","abbr":"BM","mcc":"350","code":"1441"},{"name":"Bolivia, Plurinational State of","abbr":"BO","mcc":"736","code":"591"},{"name":"Botswana","abbr":"BW","mcc":"652","code":"267"},{"name":"Brazil","abbr":"BR","mcc":"724","code":"55"},{"name":"Brunei Darussalam","abbr":"BN","mcc":"528","code":"673"},{"name":"Bulgaria","abbr":"BG","mcc":"284","code":"359"},{"name":"Burkina Faso","abbr":"BF","mcc":"613","code":"226"},{"name":"Burundi","abbr":"BI","mcc":"642","code":"257"},{"name":"Cambodia","abbr":"KH","mcc":"456","code":"855"},{"name":"Cameroon","abbr":"CM","mcc":"624","code":"237"},{"name":"Canada","abbr":"CA","mcc":"302","code":"1"},{"name":"Cape Verde","abbr":"CV","mcc":"625","code":"238"},{"name":"Cayman Islands","abbr":"KY","mcc":"346","code":"1345"},{"name":"Central African Republic","abbr":"CF","mcc":"623","code":"236"},{"name":"Chad","abbr":"TD","mcc":"622","code":"235"},{"name":"Chile","abbr":"CL","mcc":"730","code":"56"},{"name":"China","abbr":"CN","mcc":"460","code":"86"},{"name":"Colombia","abbr":"CO","mcc":"732","code":"57"},{"name":"Congo","abbr":"CG","mcc":"629","code":"242"},{"name":"Cook Islands","abbr":"CK","mcc":"548","code":"682"},{"name":"Costa Rica","abbr":"CR","mcc":"712","code":"506"},{"name":"Croatia","abbr":"HR","mcc":"219","code":"385"},{"name":"Cuba","abbr":"CU","mcc":"368","code":"53"},{"name":"Curaçao","abbr":"CW","mcc":"362","code":"599"},{"name":"Cyprus","abbr":"CY","mcc":"280","code":"357"},{"name":"Czech Republic","abbr":"CZ","mcc":"230","code":"420"},{"name":"Denmark","abbr":"DK","mcc":"238","code":"45"},{"name":"Djibouti","abbr":"DJ","mcc":"638","code":"253"},{"name":"Dominica","abbr":"DM","mcc":"366","code":"1767"},{"name":"Dominican Republic","abbr":"DO","mcc":"370","code":"1809"},{"name":"Ecuador","abbr":"EC","mcc":"740","code":"593"},{"name":"Egypt","abbr":"EG","mcc":"602","code":"20"},{"name":"El Salvador","abbr":"SV","mcc":"706","code":"503"},{"name":"Equatorial Guinea","abbr":"GQ","mcc":"627","code":"240"},{"name":"Estonia","abbr":"EE","mcc":"248","code":"372"},{"name":"Ethiopia","abbr":"ET","mcc":"636","code":"251"},{"name":"Fiji","abbr":"FJ","mcc":"542","code":"679"},{"name":"Finland","abbr":"FI","mcc":"244","code":"358"},{"name":"France","abbr":"FR","mcc":"208","code":"33"},{"name":"French Guiana","abbr":"GF","mcc":"742","code":"594"},{"name":"French Polynesia","abbr":"PF","mcc":"547","code":"689"},{"name":"Gabon","abbr":"GA","mcc":"628","code":"241"},{"name":"Gambia","abbr":"GM","mcc":"607","code":"220"},{"name":"Germany","abbr":"DE","mcc":"262","code":"49"},{"name":"Ghana","abbr":"GH","mcc":"620","code":"233"},{"name":"Gibraltar","abbr":"GI","mcc":"266","code":"350"},{"name":"Greece","abbr":"GR","mcc":"202","code":"30"},{"name":"Greenland","abbr":"GL","mcc":"290","code":"299"},{"name":"Grenada","abbr":"GD","mcc":"352","code":"1473"},{"name":"Guam","abbr":"GU","mcc":"535","code":"1671"},{"name":"Guatemala","abbr":"GT","mcc":"704","code":"502"},{"name":"Guinea","abbr":"GN","mcc":"611","code":"224"},{"name":"Guyana","abbr":"GY","mcc":"738","code":"592"},{"name":"Haiti","abbr":"HT","mcc":"372","code":"509"},{"name":"Honduras","abbr":"HN","mcc":"708","code":"504"},{"name":"Hong Kong","abbr":"HK","mcc":"454","code":"852"},{"name":"Iceland","abbr":"IS","mcc":"274","code":"354"},{"name":"India","abbr":"IN","mcc":"404","code":"91"},{"name":"Indonesia","abbr":"ID","mcc":"510","code":"62"},{"name":"Iran, Islamic Republic of","abbr":"IR","mcc":"432","code":"98"},{"name":"Iraq","abbr":"IQ","mcc":"418","code":"964"},{"name":"Ireland","abbr":"IE","mcc":"272","code":"353"},{"name":"Israel","abbr":"IL","mcc":"425","code":"972"},{"name":"Italy","abbr":"IT","mcc":"222","code":"39"},{"name":"Jamaica","abbr":"JM","mcc":"338","code":"1876"},{"name":"Japan","abbr":"JP","mcc":"440","code":"81"},{"name":"Jordan","abbr":"JO","mcc":"416","code":"962"},{"name":"Kazakhstan","abbr":"KZ","mcc":"401","code":"327"},{"name":"Kenya","abbr":"KE","mcc":"639","code":"254"},{"name":"Kiribati","abbr":"KI","mcc":"545","code":"686"},{"name":"Korea, Republic of","abbr":"KR","mcc":"450","code":"82"},{"name":"Kuwait","abbr":"KW","mcc":"419","code":"965"},{"name":"Lao People's Democratic Republic","abbr":"LA","mcc":"457","code":"856"},{"name":"Latvia","abbr":"LV","mcc":"247","code":"371"},{"name":"Lebanon","abbr":"LB","mcc":"415","code":"961"},{"name":"Lesotho","abbr":"LS","mcc":"651","code":"266"},{"name":"Liberia","abbr":"LR","mcc":"618","code":"231"},{"name":"Libya","abbr":"LY","mcc":"606","code":"218"},{"name":"Lithuania","abbr":"LT","mcc":"246","code":"370"},{"name":"Luxembourg","abbr":"LU","mcc":"270","code":"352"},{"name":"Macao","abbr":"MO","mcc":"455","code":"853"},{"name":"Madagascar","abbr":"MG","mcc":"646","code":"261"},{"name":"Malawi","abbr":"MW","mcc":"650","code":"265"},{"name":"Malaysia","abbr":"MY","mcc":"502","code":"60"},{"name":"Maldives","abbr":"MV","mcc":"472","code":"960"},{"name":"Mali","abbr":"ML","mcc":"610","code":"223"},{"name":"Malta","abbr":"MT","mcc":"278","code":"356"},{"name":"Mauritius","abbr":"MU","mcc":"617","code":"230"},{"name":"Mexico","abbr":"MX","mcc":"334","code":"52"},{"name":"Moldova, Republic of","abbr":"MD","mcc":"259","code":"373"},{"name":"Monaco","abbr":"MC","mcc":"212","code":"377"},{"name":"Mongolia","abbr":"MN","mcc":"428","code":"976"},{"name":"Morocco","abbr":"MA","mcc":"604","code":"212"},{"name":"Mozambique","abbr":"MZ","mcc":"643","code":"258"},{"name":"Myanmar","abbr":"MM","mcc":"414","code":"95"},{"name":"Namibia","abbr":"NA","mcc":"649","code":"264"},{"name":"Nepal","abbr":"NP","mcc":"429","code":"977"},{"name":"Netherlands","abbr":"NL","mcc":"204","code":"31"},{"name":"New Zealand","abbr":"NZ","mcc":"530","code":"64"},{"name":"Nicaragua","abbr":"NI","mcc":"710","code":"505"},{"name":"Niger","abbr":"NE","mcc":"614","code":"227"},{"name":"Nigeria","abbr":"NG","mcc":"621","code":"234"},{"name":"Norway","abbr":"NO","mcc":"242","code":"47"},{"name":"Oman","abbr":"OM","mcc":"422","code":"968"},{"name":"Pakistan","abbr":"PK","mcc":"410","code":"92"},{"name":"Panama","abbr":"PA","mcc":"714","code":"507"},{"name":"Papua New Guinea","abbr":"PG","mcc":"537","code":"675"},{"name":"Paraguay","abbr":"PY","mcc":"744","code":"595"},{"name":"Peru","abbr":"PE","mcc":"716","code":"51"},{"name":"Philippines","abbr":"PH","mcc":"515","code":"63"},{"name":"Poland","abbr":"PL","mcc":"260","code":"48"},{"name":"Portugal","abbr":"PT","mcc":"268","code":"351"},{"name":"Puerto Rico","abbr":"PR","mcc":"330","code":"1787"},{"name":"Qatar","abbr":"QA","mcc":"427","code":"974"},{"name":"Romania","abbr":"RO","mcc":"226","code":"40"},{"name":"Saint Lucia","abbr":"LC","mcc":"358","code":"1758"},{"name":"San Marino","abbr":"SM","mcc":"292","code":"378"},{"name":"Sao Tome and Principe","abbr":"ST","mcc":"626","code":"239"},{"name":"Saudi Arabia","abbr":"SA","mcc":"420","code":"966"},{"name":"Senegal","abbr":"SN","mcc":"608","code":"221"},{"name":"Seychelles","abbr":"SC","mcc":"633","code":"248"},{"name":"Sierra Leone","abbr":"SL","mcc":"619","code":"232"},{"name":"Singapore","abbr":"SG","mcc":"525","code":"65"},{"name":"Slovakia","abbr":"SK","mcc":"231","code":"421"},{"name":"Slovenia","abbr":"SI","mcc":"293","code":"386"},{"name":"Solomon Islands","abbr":"SB","mcc":"540","code":"677"},{"name":"Somalia","abbr":"SO","mcc":"637","code":"252"},{"name":"South Africa","abbr":"ZA","mcc":"655","code":"27"},{"name":"Spain","abbr":"ES","mcc":"214","code":"34"},{"name":"Sri Lanka","abbr":"LK","mcc":"413","code":"94"},{"name":"Sudan","abbr":"SD","mcc":"634","code":"249"},{"name":"Suriname","abbr":"SR","mcc":"746","code":"597"},{"name":"Swaziland","abbr":"SZ","mcc":"653","code":"268"},{"name":"Sweden","abbr":"SE","mcc":"240","code":"46"},{"name":"Switzerland","abbr":"CH","mcc":"228","code":"41"},{"name":"Syrian Arab Republic","abbr":"SY","mcc":"417","code":"963"},{"name":"Taiwan","abbr":"TW","mcc":"466","code":"886"},{"name":"Vanuatu","abbr":"VU","mcc":"541","code":"678"},{"name":"Virgin Islands, British","abbr":"VG","mcc":"348","code":"1284"}] \ No newline at end of file diff --git a/app/src/main/java/com/chwl/app/ui/login/AreaCodeActivity.kt b/app/src/main/java/com/chwl/app/ui/login/AreaCodeActivity.kt index 2ac3f036f..5b4f5036f 100644 --- a/app/src/main/java/com/chwl/app/ui/login/AreaCodeActivity.kt +++ b/app/src/main/java/com/chwl/app/ui/login/AreaCodeActivity.kt @@ -3,17 +3,19 @@ package com.chwl.app.ui.login import android.app.Activity import android.content.Intent import android.view.View +import androidx.lifecycle.lifecycleScope import com.chad.library.adapter.base.BaseQuickAdapter -import com.chad.library.adapter.base.BaseViewHolder import com.netease.nim.uikit.StatusBarUtil -import com.trello.rxlifecycle3.android.ActivityEvent import com.chwl.app.R import com.chwl.app.base.BaseViewBindingActivity import com.chwl.app.databinding.ActivityAreaCodeBinding -import com.chwl.core.auth.AuthModel -import com.chwl.core.auth.bean.AreaInfoBean -import com.chwl.core.utils.CoreLogger -import com.chwl.core.utils.net.BeanObserver +import com.chwl.app.ui.widget.SideBarView +import com.example.lib_utils.UiUtils +import com.example.lib_utils.ktx.getColorById +import com.yizhuan.xchat_android_core.region.RegionHelper +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext /** * 区号 @@ -22,7 +24,9 @@ import com.chwl.core.utils.net.BeanObserver */ class AreaCodeActivity : BaseViewBindingActivity() { - private val mCountries = ArrayList() + private val regionRepository = RegionHelper() + + private val adapter = RegionListAdapter() companion object { const val COUNTRY_NUMBER = "country_number" @@ -39,55 +43,51 @@ class AreaCodeActivity : BaseViewBindingActivity() { override fun init() { initTitleBar(getString(R.string.select_area_code)) - initCountryData() initListView() + initSideBar() + loadData() } - private fun initCountryData() { - val countryList = resources.getStringArray(R.array.country_code_list_ch) - for (s in countryList) { - val country = s.split("*").toTypedArray() - val countryName = country[0] - val countryNumber = country[1] - val c = AreaInfoBean( - name = countryName, - phoneAreaCode = countryNumber - ) - mCountries.add(c) + private fun initSideBar() { + binding.sideBarView.setTextColor(context.getColorById(R.color.color_5caaff)) + binding.sideBarView.setTextSize(UiUtils.dip2px(12f).toFloat()) + binding.sideBarView.setListener(object : SideBarView.Listener { + override fun onSideBarScroll(word: String) { + val index = adapter.data.indexOfFirst { + it.itemType == RegionListAdapter.ITEM_TYPE_GROUP && it.groupName?.toString() == word + } + if (index >= 0) { + binding.mRecyclerView.scrollToPosition(index) + } + } + + override fun onSideBarScrollEnd() { + } + }) + } + + private fun loadData() { + lifecycleScope.launch { + val list = regionRepository.getRegionSelectorList(RegionListAdapter.ITEM_TYPE_GROUP) + withContext(Dispatchers.Main) { + adapter.setNewData(list) + } } } private fun initListView() { - val mAdapter = object : - BaseQuickAdapter(R.layout.item_country) { - override fun convert(helper: BaseViewHolder, item: AreaInfoBean) { - helper.setText(R.id.tv_name, item.name) - helper.setText(R.id.tv_country_code, "+${item.phoneAreaCode}") - } - } - binding.mRecyclerView.adapter = mAdapter - mAdapter.setNewData(mCountries) + binding.mRecyclerView.adapter = adapter //返回国家 - mAdapter.setOnItemClickListener { adapter: BaseQuickAdapter<*, *>?, view: View?, position: Int -> - val country = mAdapter.data[position] + adapter.setOnItemClickListener { adapter: BaseQuickAdapter<*, *>?, view: View?, position: Int -> + val region = this.adapter.getItem(position) + if (region?.code.isNullOrEmpty()) { + return@setOnItemClickListener + } val intent = Intent() - intent.putExtra(COUNTRY_NUMBER, "+${country.phoneAreaCode}") + intent.putExtra(COUNTRY_NUMBER, region?.fullCode) setResult(RESULT_OK, intent) finish() } - - AuthModel.get() - .areaCodeList - .compose(bindUntilEvent(ActivityEvent.DESTROY)) - .subscribe(object : BeanObserver>() { - override fun onErrorMsg(error: String) { - CoreLogger.error("areaCode", error) - } - - override fun onSuccess(list: List) { - mAdapter.setNewData(list) - } - }) } override fun needSteepStateBar() = true @@ -97,5 +97,4 @@ class AreaCodeActivity : BaseViewBindingActivity() { StatusBarUtil.transparencyBar(this) StatusBarUtil.StatusBarLightMode(this) } - } \ No newline at end of file diff --git a/app/src/main/java/com/chwl/app/ui/login/BindPhoneActivity.kt b/app/src/main/java/com/chwl/app/ui/login/BindPhoneActivity.kt index e920df404..4057fdce0 100644 --- a/app/src/main/java/com/chwl/app/ui/login/BindPhoneActivity.kt +++ b/app/src/main/java/com/chwl/app/ui/login/BindPhoneActivity.kt @@ -23,6 +23,7 @@ import com.chwl.core.user.UserModel import com.chwl.core.user.bean.UserInfo import com.chwl.library.utils.NetworkUtils import com.chwl.library.utils.ResUtil +import com.yizhuan.xchat_android_core.region.RegionHelper import io.reactivex.SingleObserver import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable @@ -50,6 +51,7 @@ class BindPhoneActivity : BaseViewBindingActivity(), override fun init() { initTitleBar(getString(R.string.text_bind_phone)) initListener() + RegionHelper().loadRecommendRegion(lifecycle, binding.tvAreaCode) } private fun initListener() { diff --git a/app/src/main/java/com/chwl/app/ui/login/LoginPasswordActivity.java b/app/src/main/java/com/chwl/app/ui/login/LoginPasswordActivity.java index 41f979d65..00757aae2 100644 --- a/app/src/main/java/com/chwl/app/ui/login/LoginPasswordActivity.java +++ b/app/src/main/java/com/chwl/app/ui/login/LoginPasswordActivity.java @@ -34,6 +34,7 @@ import com.chwl.core.code.CodeType; import com.chwl.library.common.SpConstants; import com.chwl.library.common.util.SPUtils; import com.chwl.library.utils.TextWatcherWrapper; +import com.yizhuan.xchat_android_core.region.RegionHelper; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -90,6 +91,7 @@ public class LoginPasswordActivity extends BaseActivity { setContentView(R.layout.activity_login_password); EventBus.getDefault().register(this); initView(); + new RegionHelper().loadRecommendRegion(getLifecycle(), tvAreaCode); } private void checkInput() { diff --git a/app/src/main/java/com/chwl/app/ui/login/LoginPhoneActivity.kt b/app/src/main/java/com/chwl/app/ui/login/LoginPhoneActivity.kt index 7a1392dea..35864c80d 100644 --- a/app/src/main/java/com/chwl/app/ui/login/LoginPhoneActivity.kt +++ b/app/src/main/java/com/chwl/app/ui/login/LoginPhoneActivity.kt @@ -16,6 +16,7 @@ import com.chwl.app.databinding.ActivityLoginPhoneBinding import com.chwl.core.auth.AuthModel import com.chwl.core.auth.event.LoginEvent import com.chwl.core.code.CodeType +import com.yizhuan.xchat_android_core.region.RegionHelper import io.reactivex.SingleObserver import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable @@ -43,6 +44,7 @@ class LoginPhoneActivity : BaseViewBindingActivity(), override fun init() { EventBus.getDefault().register(this) initListener() + RegionHelper().loadRecommendRegion(lifecycle, binding.tvAreaCode) } private fun initListener() { diff --git a/app/src/main/java/com/chwl/app/ui/login/RegionListAdapter.kt b/app/src/main/java/com/chwl/app/ui/login/RegionListAdapter.kt new file mode 100644 index 000000000..31a92f618 --- /dev/null +++ b/app/src/main/java/com/chwl/app/ui/login/RegionListAdapter.kt @@ -0,0 +1,32 @@ +package com.chwl.app.ui.login + +import com.chad.library.adapter.base.BaseMultiItemQuickAdapter +import com.chad.library.adapter.base.BaseViewHolder +import com.chwl.app.R +import com.yizhuan.xchat_android_core.region.bean.RegionBean + +/** + * Created by Max on 2023/12/7 19:34 + * Desc: + **/ +class RegionListAdapter: + BaseMultiItemQuickAdapter(ArrayList()) { + + companion object { + const val ITEM_TYPE_GROUP = 1 + } + + init { + addItemType(0, R.layout.region_item_def) + addItemType(ITEM_TYPE_GROUP, R.layout.region_item_group) + } + + override fun convert(helper: BaseViewHolder, item: RegionBean?) { + if (helper.itemViewType == ITEM_TYPE_GROUP) { + helper.setText(R.id.tv_group, item?.groupName?.toString() ?: "") + } + helper.setText(R.id.tv_name, item?.name ?: "") + helper.setText(R.id.tv_country_code, "+${item?.code}") + } + +} diff --git a/app/src/main/java/com/chwl/app/ui/setting/ResetPasswordActivity.kt b/app/src/main/java/com/chwl/app/ui/setting/ResetPasswordActivity.kt index 2ed5ec2ea..010eb2bc8 100644 --- a/app/src/main/java/com/chwl/app/ui/setting/ResetPasswordActivity.kt +++ b/app/src/main/java/com/chwl/app/ui/setting/ResetPasswordActivity.kt @@ -23,6 +23,7 @@ import com.chwl.core.code.CodeType import com.chwl.core.user.UserModel import com.chwl.library.utils.ResUtil import com.chwl.library.utils.TextWatcherWrapper +import com.yizhuan.xchat_android_core.region.RegionHelper import io.reactivex.SingleObserver import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable @@ -59,6 +60,7 @@ class ResetPasswordActivity : BaseViewBindingActivity(), View.OnClickListener, TextWatcher { @@ -53,6 +54,7 @@ class VerifyPhoneActivity : BaseViewBindingActivity( resetPwd = intent.getBooleanExtra("resetPwd", false) initListener() + RegionHelper().loadRecommendRegion(lifecycle, binding.tvAreaCode) } private fun initListener() { diff --git a/app/src/main/java/com/chwl/app/ui/widget/SideBarView.kt b/app/src/main/java/com/chwl/app/ui/widget/SideBarView.kt new file mode 100644 index 000000000..53fb8ef9c --- /dev/null +++ b/app/src/main/java/com/chwl/app/ui/widget/SideBarView.kt @@ -0,0 +1,146 @@ +package com.chwl.app.ui.widget + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Typeface +import android.util.AttributeSet +import android.view.MotionEvent +import android.view.View +import android.view.ViewParent + + +/** + * Created by Max on 2023/12/8 10:43 + * Desc:字母索引 + **/ +class SideBarView : View { + private var selectIndex = 0 + private var textSize = 0f + private var textColor = 0 + private var textSizeFocus = 0f + private var textColorFocus = 0 + + //标记 避免重复调用 + private var isDown = false + + //这里也可以传入数组方式 + private var list = listOf( + "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z", "#" + ) + private var paint = Paint() + + private var listener: Listener? = null + + constructor(context: Context?) : super(context) + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) + constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) + + constructor( + context: Context?, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int + ) : super(context, attrs, defStyleAttr, defStyleRes) + + fun setTextColor(textColor: Int, focusTextColor: Int = textColor) { + this.textColor = textColor + this.textColorFocus = focusTextColor + } + + fun setTextSize(textSize: Float, focusTextSize: Float = textSize) { + this.textSize = textSize + this.textSizeFocus = focusTextSize + } + + override fun onDraw(canvas: Canvas?) { + super.onDraw(canvas) + paintText(canvas) + } + + private fun paintText(canvas: Canvas?) { + //计算每一个字母的高度,总告诉除以字母集合的高度就可以 + val height: Int = height / list.size + for (i in list.indices) { + if (i == selectIndex) { + paint.color = textColorFocus + paint.textSize = textSizeFocus + } else { + paint.color = textColor + paint.textSize = textSize + } + paint.isAntiAlias = true //设置抗锯齿 + paint.typeface = Typeface.DEFAULT_BOLD + //计算每一个字母x轴 + val paintX = width / 2f - paint.measureText(list[i]) / 2 + //计算每一个字母Y轴 + val paintY = height * i + height + //绘画出来这个TextView + canvas?.drawText(list[i], paintX, paintY.toFloat(), paint) + //画完一个以后重置画笔 + paint.reset() + } + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + val parent: ViewParent? + when (event.action) { + MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> { + val index = (event.y / height * list.size).toInt() + if (index >= 0 && index < list.size && selectIndex != index) { + listener?.onSideBarScroll(list[index]) + selectIndex = index + invalidate() + //改变标记状态 + isDown = true + } + parent = getParent() + parent?.requestDisallowInterceptTouchEvent(true) + } + + MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { + listener?.onSideBarScrollEnd() + //改变标记状态 + isDown = false + parent = getParent() + parent?.requestDisallowInterceptTouchEvent(false) + } + } + return true + } + + interface Listener { + //滚动位置 + fun onSideBarScroll(word: String) + + //隐藏提示文本 + fun onSideBarScrollEnd() + } + + fun setListener(listener: Listener?) { + this.listener = listener + } + + /** + * Item滚动 更新侧边栏字母 + * + * @param word 字母 + */ + fun onUpdateSideBarText(word: String?) { + //手指没触摸才调用 + if (!isDown) { + for (i in list.indices) { + if (list[i] == word && selectIndex != i) { + selectIndex = i + invalidate() + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_area_code.xml b/app/src/main/res/layout/activity_area_code.xml index 4ae46b6e8..af6d63432 100644 --- a/app/src/main/res/layout/activity_area_code.xml +++ b/app/src/main/res/layout/activity_area_code.xml @@ -19,6 +19,7 @@ android:id="@+id/mRecyclerView" android:layout_width="match_parent" android:layout_height="0dp" + android:layout_marginEnd="@dimen/dp_10" android:overScrollMode="never" android:scrollbars="none" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" @@ -27,4 +28,13 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/title_bar" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_country.xml b/app/src/main/res/layout/region_item_def.xml similarity index 100% rename from app/src/main/res/layout/item_country.xml rename to app/src/main/res/layout/region_item_def.xml diff --git a/app/src/main/res/layout/region_item_group.xml b/app/src/main/res/layout/region_item_group.xml new file mode 100644 index 000000000..68db8ed52 --- /dev/null +++ b/app/src/main/res/layout/region_item_group.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 6e84d547c..2ad5ff922 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -67,175 +67,4 @@ 夢幻花園CP位 永恆愛情城堡CP位\n永恆CP頭飾\n永恆CP銘牌 - - - Taiwan*886 - Hongkong*852 - Macao*853 - Malaysia*60 - Singapore*65 - India*91 - Indonesia*62 - ישראל *972 - الأردن *962 - البحرين *973 - الجزائر *213 - العراق *964 - الكويت *965 - المغرب *212 - المملكة,العربية,السعودية *966 - پاکستان *92 - عُمان *968 - قطر *974 - مصر *20 - Brasil*55 - Colombia*57 - Philippines*63 - افغانستان *93 - Shqipëri*355 - American samoa*1684 - Andorra*376 - Angola*244 - Anguilla*1264 - Antigua and Barbuda*1268 - Argentina*54 - Հայաստան*374 - Aruba*297 - Ascension,Island*247 - Australia*61 - Österreich*43 - Azərbaycan*994 - Bahamas*1242 - বাংলাদেশ*880 - Barbados*1246 - Беларусь*375 - België*32 - Belize*501 - Bénin*229 - Bermuda Is.*1441 - Bolivia*591 - Botswana*267 - Brunei*673 - България*359 - Burkina,Faso*226 - Myanmar*95 - Burundi*257 - China*86 - Cameroon*237 - Canada*1 - Kabu Verdi*238 - Cayman Islands*1345 - Central African Republic*236 - Chad*235 - Chile*56 - Congo*242 - Jamhuri ya Kidemokrasia ya Kongo*249 - Cook Is.*682 - Costa Rica*506 - Hrvatska*385 - Cuba*53 - Curacao*599 - Cyprus*357 - Czech Republic*420 - Denmark*45 - Djibouti*253 - Dominica*1767 - Dominica Rep.*1809 - Ecuador*593 - EI Salvador*503 - Guinea Ecuatorial*240 - Estonia*372 - Ethiopia*251 - Fiji*679 - Finland*358 - France*33 - French Guiana*594 - French Polynesia*689 - Gabon*241 - Gambia*220 - Georgia*995 - Germany*49 - Ghana*233 - Gibraltar*350 - Greece*30 - Kalaallit Nunaat*299 - Grenada*1473 - Guam*1671 - Guatemala*502 - Guinea*224 - Guyana*592 - Haiti*509 - Honduras*504 - Hungary*36 - Iceland*354 - ایران *98 - Ireland*353 - Italy*39 - Jamaica*1876 - Japan*81 - កម្ពុជា*855 - Kazakstan*327 - Kenya*254 - Kiribati*686 - Korea*82 - Kazakstan*996 - Laos*856 - Latvia*371 - لبنان *961 - Lesotho*266 - Liberia*231 - ليبيا *218 - Liechtenstein*423 - Lithuania*370 - Luxembourg*352 - Madagascar*261 - Malawi*265 - Maldives*960 - Mali*223 - Malta*356 - Mauritius*230 - Mexico*52 - Moldova, Republic of*373 - Monaco*377 - Mongolia*976 - Mozambique*258 - Namibia*264 - Nepal*977 - Netherlands*31 - New Zealand*64 - Nicaragua*505 - Nijar*227 - Nigeria*234 - Norway*47 - Panama*507 - Papua New Cuinea*675 - Paraguay*595 - Peru*51 - Poland*48 - Portugal*351 - Puerto Rico*1787 - Romania*40 - St.Lucia*1758 - San Marino*378 - Sao Tome and Principe*239 - Senegal*221 - Seychelles*248 - Sierra Leone*232 - Slovakia*421 - Slovenia*386 - Solomon Is*677 - Somali*252 - South Africa*27 - Spain*34 - Sri Lanka*94 - Sudan*249 - Suriname*597 - Swaziland*268 - Sweden*46 - Switzerland*41 - Syria*963 - Vanuatu*678 - British Virgin Islands*1284 - - \ No newline at end of file diff --git a/core/src/main/java/com/chwl/core/auth/AuthModel.java b/core/src/main/java/com/chwl/core/auth/AuthModel.java index 1a3deaeb6..1361a69b9 100644 --- a/core/src/main/java/com/chwl/core/auth/AuthModel.java +++ b/core/src/main/java/com/chwl/core/auth/AuthModel.java @@ -27,7 +27,6 @@ import com.netease.nimlib.sdk.msg.MsgService; import com.orhanobut.logger.Logger; import com.chwl.core.DemoCache; import com.chwl.core.R; -import com.chwl.core.auth.bean.AreaInfoBean; import com.chwl.core.auth.entity.AccountInfo; import com.chwl.core.auth.entity.ThirdUserInfo; import com.chwl.core.auth.entity.TicketInfo; @@ -63,10 +62,6 @@ import com.chwl.library.utils.constant.PackageNameConstants; import com.chwl.library.utils.json.JsonUtils; import org.greenrobot.eventbus.EventBus; -import org.json.JSONObject; - -import java.util.HashMap; -import java.util.List; import cn.sharesdk.framework.Platform; import io.reactivex.Single; @@ -1068,17 +1063,6 @@ public class AuthModel extends BaseModel implements IAuthModel { .compose(RxHelper.handleSchedulers()); } - /** - * 区号 - * - * @return - */ - public Single> getAreaCodeList() { - return api.getAreaCodeList() - .compose(RxHelper.handleBeanData()) - .compose(RxHelper.handleSchedulers()); - } - /** * 发送验证码 * @@ -1340,14 +1324,6 @@ public class AuthModel extends BaseModel implements IAuthModel { @POST("phone/auth/bound") Single> boundAuthCode(@Field("authCode") String authCode); - /** - * 获取地区码 - * - * @return - */ - @GET("areaInfo/list") - Single>> getAreaCodeList(); - /** * 发送验证码 * diff --git a/core/src/main/java/com/chwl/core/auth/bean/AreaInfoBean.kt b/core/src/main/java/com/chwl/core/auth/bean/AreaInfoBean.kt deleted file mode 100644 index fe7da3a14..000000000 --- a/core/src/main/java/com/chwl/core/auth/bean/AreaInfoBean.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.chwl.core.auth.bean - -import lombok.Data - -@Data -class AreaInfoBean( - val id: Long = 0L, - val name: String? = null, - val abbr: String? = null, - val phoneAreaCode: String? = null, - val seq: Int = 0, - val status: Int = 0, - val createTime: Long = 0L, - val updateTime: Long = 0L -) \ No newline at end of file diff --git a/core/src/main/java/com/yizhuan/xchat_android_core/region/RegionHelper.kt b/core/src/main/java/com/yizhuan/xchat_android_core/region/RegionHelper.kt new file mode 100644 index 000000000..d09aad90a --- /dev/null +++ b/core/src/main/java/com/yizhuan/xchat_android_core/region/RegionHelper.kt @@ -0,0 +1,118 @@ +package com.yizhuan.xchat_android_core.region + +import android.widget.TextView +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.coroutineScope +import com.example.lib_utils.AppUtils +import com.example.lib_utils.TelephonyUtils +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.yizhuan.xchat_android_core.region.bean.RegionBean +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.io.InputStream + +/** + * Created by Max on 2023/12/7 18:23 + * Desc:地区 + **/ +class RegionHelper { + + fun loadRecommendRegion(lifecycle: Lifecycle, textView: TextView){ + lifecycle.coroutineScope.launch { + RegionHelper().getCurrentOrDefRegion().let { + textView.text = it.fullCode + } + } + } + + private fun getDefaultRegion(): RegionBean { + return RegionBean(name = "Taiwan", abbr = "TW", mcc = "466", code = "886") + } + + /** + * 获取当前地区或默认 + */ + private suspend fun getCurrentOrDefRegion(): RegionBean { + return withContext(Dispatchers.IO) { + var operator = TelephonyUtils.getNetWorkOperator() + if (operator.isNullOrEmpty()) { + operator = TelephonyUtils.getSimOperator() + } + val mcc = operator?.take(3) + val region = getAllRegionList().firstOrNull { + it.mcc == mcc + } + region ?: getDefaultRegion() + } + } + + /** + * 获取地区选择器列表 + */ + suspend fun getRegionSelectorList(groupItemType: Int): List { + return withContext(Dispatchers.IO) { + val list = ArrayList() + list.addAll(getHotRegionList()) + var lastGroup: Char? = null + list.addAll(getAllRegionList() + .map { + val firstName = it.name?.firstOrNull()?.uppercaseChar() ?: '#' + if (firstName in 'A'..'Z') { + it.groupName = firstName + it.sortedBy = "$firstName${it.name?.uppercase()}" + } else { + it.groupName = '#' + it.sortedBy = "${'Z' + 1}${it.name?.uppercase()}" + } + it + } + .sortedBy { + it.sortedBy + }.map { + val groupName = it.groupName ?: '#' + if (groupName != lastGroup) { + it.itemType = groupItemType + } + lastGroup = groupName + it + } + ) + list + } + } + + /** + * 获取热门地区 + */ + suspend fun getHotRegionList(): List { + return getRegionListFromAssets("hot_region.json") + } + + /** + * 获取全部地区 + */ + suspend fun getAllRegionList(): List { + return getRegionListFromAssets("region.json") + } + + /** + * 从资源文件中获取地区列表 + */ + private fun getRegionListFromAssets(fileName: String): MutableList { + //获取IO流 + try { + val inputStream: InputStream = + AppUtils.getApp().applicationContext.assets.open(fileName) + val json: String + inputStream.use { + json = it.bufferedReader().readText() + } + return Gson().fromJson(json, object : TypeToken>() {}.type) + } catch (e: Exception) { + e.printStackTrace() + } + return mutableListOf() + } +} \ No newline at end of file diff --git a/core/src/main/java/com/yizhuan/xchat_android_core/region/bean/RegionBean.kt b/core/src/main/java/com/yizhuan/xchat_android_core/region/bean/RegionBean.kt new file mode 100644 index 000000000..0294278ee --- /dev/null +++ b/core/src/main/java/com/yizhuan/xchat_android_core/region/bean/RegionBean.kt @@ -0,0 +1,48 @@ +package com.yizhuan.xchat_android_core.region.bean + +import com.chad.library.adapter.base.entity.MultiItemEntity +import com.netease.nim.uikit.business.ait.selector.model.ItemType + +/** + * Created by Max on 2023/12/7 18:48 + * Desc:地区 + **/ +data class RegionBean( + // 名称(英文) + val name: String?, + // 简称 + val abbr: String?, + // 区号 + val code: String?, + // MCC + val mcc: String? +) : MultiItemEntity { + + val fullCode: String? + get() { + if (code == null) { + return null + } + return if (code.startsWith("+")) { + code + } else { + "+$code" + } + } + + // 本地分组用到 + var groupName: Char? = null + + // 本地排序用到 + var sortedBy: String? = null + + private var itemType: Int = 0 + + fun setItemType(itemType: Int) { + this.itemType = itemType + } + + override fun getItemType(): Int { + return itemType + } +} \ No newline at end of file diff --git a/libs/lib_utils/src/main/java/com/example/lib_utils/TelephonyUtils.kt b/libs/lib_utils/src/main/java/com/example/lib_utils/TelephonyUtils.kt index 2fb5cc9d5..210b4ba69 100644 --- a/libs/lib_utils/src/main/java/com/example/lib_utils/TelephonyUtils.kt +++ b/libs/lib_utils/src/main/java/com/example/lib_utils/TelephonyUtils.kt @@ -14,23 +14,27 @@ object TelephonyUtils : ILog { * 是否为中国运营商(任意卡属于中国就为true) */ fun isChinaOperator(): Boolean { - val tm = - AppUtils.getApp().getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager - ?: return false - if (tm.simState == TelephonyManager.SIM_STATE_READY) { - if (!tm.simOperator.isNullOrEmpty() && tm.simOperator.startsWith("460")) { - return true + try { + val tm = + AppUtils.getApp().getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager + ?: return false + if (tm.simState == TelephonyManager.SIM_STATE_READY) { + if (!tm.simOperator.isNullOrEmpty() && tm.simOperator.startsWith("460")) { + return true + } + if (isChainOperator(tm.simOperatorName)) { + return true + } } - if (isChainOperator(tm.simOperatorName)) { - return true - } - } - if (!tm.networkOperator.isNullOrEmpty() && tm.networkOperator.startsWith("460")) { - return true - } - if (isChainOperator(tm.networkOperatorName)) { - return true + if (!tm.networkOperator.isNullOrEmpty() && tm.networkOperator.startsWith("460")) { + return true + } + if (isChainOperator(tm.networkOperatorName)) { + return true + } + } catch (e: Exception) { + e.printStackTrace() } return false } @@ -51,33 +55,44 @@ object TelephonyUtils : ILog { * 获取SIM运营商名称 */ fun getSimOperator(): String? { - val tm = - AppUtils.getApp().getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager - ?: return null - if (tm.simState != TelephonyManager.SIM_STATE_READY) { - logD("SIM状态不对:${tm.simState}") + try { + val tm = + AppUtils.getApp().getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager + ?: return null + if (tm.simState != TelephonyManager.SIM_STATE_READY) { + logD("SIM状态不对:${tm.simState}") + return null + } + val simOperator = tm.simOperator + logD("getSimOperator()获取的MCC+MNC为:$simOperator") + logD("getOperatorName()方法获取的运营商名称为:${tm.simOperatorName} ") + logD("通过getSimOperator()人为判断的运营商名称是: ${getOperatorName(simOperator)}") + return simOperator + } catch (e: Exception) { + e.printStackTrace() return null } - val simOperator = tm.simOperator - logD("getSimOperator()获取的MCC+MNC为:$simOperator") - logD("getOperatorName()方法获取的运营商名称为:${tm.simOperatorName} ") - logD("通过getSimOperator()人为判断的运营商名称是: ${getOperatorName(simOperator)}") - return simOperator } /** * 获取网络运营商 */ fun getNetWorkOperator(): String? { - val tm = AppUtils.getApp().getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager - ?: return null - //用于判断拨号那张卡的运营商 - val networkOperator = tm.networkOperator - logD("getNetWorkOperator() 获取的MCC+MNC为:$networkOperator") - logD("getNetWorkOperator() phoneType:${tm.phoneType}") - logD("getNetworkOperatorName()方法获取的网络类型名称是: ${tm.networkOperatorName}") - logD("通过getNetWorkOperator()人为判断的运营商名称是: ${getOperatorName(networkOperator)}") - return tm.networkOperator + try { + val tm = + AppUtils.getApp().getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager + ?: return null + //用于判断拨号那张卡的运营商 + val networkOperator = tm.networkOperator + logD("getNetWorkOperator() 获取的MCC+MNC为:$networkOperator") + logD("getNetWorkOperator() phoneType:${tm.phoneType}") + logD("getNetworkOperatorName()方法获取的网络类型名称是: ${tm.networkOperatorName}") + logD("通过getNetWorkOperator()人为判断的运营商名称是: ${getOperatorName(networkOperator)}") + return tm.networkOperator + } catch (e: Exception) { + e.printStackTrace() + return null + } } /**