fix 充值,登录

This commit is contained in:
cyh 2025-03-19 17:56:41 +08:00
parent bffda89385
commit 7ed4c780e0
7 changed files with 172 additions and 93 deletions

View File

@ -101,7 +101,7 @@ dependencies {
implementation("com.journeyapps:zxing-android-embedded:3.6.0")
// https://mvnrepository.com/artifact/com.google.zxing/core
implementation("com.google.zxing:core:3.5.3")
// implementation("com.google.zxing:core:3.5.3")
implementation("com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4")
// https://mvnrepository.com/artifact/com.airbnb.android/lottie
implementation("com.airbnb.android:lottie:5.2.0")

View File

@ -45,9 +45,11 @@ import com.yingmao.clash.util.CommonUtils
import com.yingmao.clash.util.PayUtils
import com.yingmao.clash.util.ThreadUtils
import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.dialog.DialogDoMainChoose
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import java.text.DecimalFormat
import java.text.SimpleDateFormat
@ -311,6 +313,7 @@ class MemberRechargeActivity: BaseActivity() {
override fun httpFailure(httpStatus: HttpStatus.Failure) {
when (httpStatus.reqType) {
HttpReqType.GET_RECHARGE_INFO -> {
showDomainList()
Logger.d("获取充值续费信息异常${httpStatus.msg}")
swipeLayout.isRefreshing = false
RxToast.error(resources.getString(R.string.DataError))
@ -334,6 +337,45 @@ class MemberRechargeActivity: BaseActivity() {
}
}
}
var dialogDoMainChoose: DialogDoMainChoose? = null
private fun showDomainList() {
try {
SplashHelper(viewModel).getHostWithFallback { success ->
MainScope().launch {
if (success) {
if (dialogDoMainChoose == null) {
dialogDoMainChoose = DialogDoMainChoose(this@MemberRechargeActivity)
}
if (dialogDoMainChoose?.isShowing == false) {
dialogDoMainChoose?.setOnTryButtonListener(object :
DialogDoMainChoose.OnTryButtonListener {
override fun tryButton() {
val username = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
// viewModel.getPointCardSurplus(username, phToken)
val userId = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
viewModel.getPhRechargeInfo(username, phToken, userId)
}
override fun cancel() {
com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN cancel")
dialogDoMainChoose?.dismiss()
}
})
dialogDoMainChoose?.show()
}
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun showLoadingDialog(content: String) {
apply {
if (!::rxDialogShapeLoading.isInitialized) {

View File

@ -238,7 +238,7 @@ class UIMainActivity : BaseActivity() {
mainAtyVM.getAirNodes()
RxToast.info(resources.getString(R.string.SuccessfullyUpdatedUserInformation))
} else {
RxToast.info(resources.getString(R.string.PaymentResultsStr))
// RxToast.info(resources.getString(R.string.PaymentResultsStr))
}
} else {
RxToast.info(resources.getString(R.string.QueryFailed))

View File

@ -22,6 +22,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity.RESULT_OK
import androidx.appcompat.widget.AppCompatImageView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@ -82,30 +83,31 @@ import java.util.concurrent.atomic.AtomicInteger
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatchers.IO){
private lateinit var llCustomer: LinearLayout
private lateinit var tvBinding:TextView
class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatchers.IO) {
private lateinit var llCustomer: LinearLayout
private lateinit var tvBinding: TextView
private lateinit var mainAtyVM: MainAtyVM
private lateinit var tvNotice: MarqueeTextView
private lateinit var llNoticeBackground:LinearLayout
private lateinit var llIntelligentMode:LinearLayout
private lateinit var acceleratedStartup: AppCompatImageView
private lateinit var countryIv:AppCompatImageView
private lateinit var nodeNameTv:TextView
private lateinit var tvNotice: MarqueeTextView
private lateinit var llNoticeBackground: LinearLayout
private lateinit var llIntelligentMode: LinearLayout
private lateinit var acceleratedStartup: AppCompatImageView
private lateinit var countryIv: AppCompatImageView
private lateinit var nodeNameTv: TextView
private lateinit var ivProxyMode:AppCompatImageView
private lateinit var tvProxyMode:TextView
private lateinit var tvExpirationTime:TextView
private lateinit var refreshExpire:ImageView
private lateinit var llLine:LinearLayout
private lateinit var clActivity: ConstraintLayout
private lateinit var clMember:ConstraintLayout
private lateinit var ivProxyMode: AppCompatImageView
private lateinit var tvProxyMode: TextView
private lateinit var tvExpirationTime: TextView
private lateinit var refreshExpire: ImageView
private lateinit var llLine: LinearLayout
private lateinit var clActivity: ConstraintLayout
private lateinit var clMember: ConstraintLayout
private val fragments = arrayListOf<Fragment>()
var proList: MutableList<ClashNodebBean>? = null
private val nextRequestKey = AtomicInteger(0)
private var reConnection = false
private var connectId=-1
private var connectId = -1
companion object {
const val REQUEST_CONNECT = 1
const val CHECK_NODE_REQUEST_CODE = 2
@ -118,6 +120,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
var clashRunning: Boolean = false
}
private lateinit var rxDialogShapeLoading: RxDialogShapeLoading
override fun init(
@ -125,7 +128,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
backIv: ImageView,
moreIv: TextView,
titleTv: TextView,
container: FrameLayout
container: FrameLayout,
) {
titleBarRl.visibility = View.GONE
titleTv.visibility = View.GONE
@ -137,43 +140,47 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
private fun initLanguage(view: View) {
view.findViewById<TextView>(R.id.tvCustomer).text = requireActivity().resources.getString(R.string.kefu)
view.findViewById<TextView>(R.id.tvCustomer).text =
requireActivity().resources.getString(R.string.kefu)
tvBinding.text = requireActivity().resources.getString(R.string.binding)
tvProxyMode.text = requireActivity().resources.getString(R.string.IntelligentMode)
nodeNameTv.text = requireActivity().resources.getString(R.string.AutomaticSelection)
view.findViewById<TextView>(R.id.tvExpirationTimeTxt).text = requireActivity().resources.getString(R.string.expire_date)
view.findViewById<TextView>(R.id.tvExpirationTimeTxt).text =
requireActivity().resources.getString(R.string.expire_date)
view.findViewById<TextView>(R.id.tvGetMember).text = requireActivity().resources.getString(R.string.getMember)
view.findViewById<TextView>(R.id.tvGetMemberStr).text = requireActivity().resources.getString(R.string.MoreWonderful)
view.findViewById<TextView>(R.id.tvGetMember).text =
requireActivity().resources.getString(R.string.getMember)
view.findViewById<TextView>(R.id.tvGetMemberStr).text =
requireActivity().resources.getString(R.string.MoreWonderful)
val userName =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
if(!(PayUtils.isEmail(userName)||PayUtils.isPhoneNumber(userName))){
tvBinding.visibility=View.VISIBLE
}else{
tvBinding.visibility=View.GONE
}
val userName =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
if (!(PayUtils.isEmail(userName) || PayUtils.isPhoneNumber(userName))) {
tvBinding.visibility = View.VISIBLE
} else {
tvBinding.visibility = View.GONE
}
}
private fun initView(view: View) {
llCustomer=view.findViewById(R.id.llCustomer)
tvBinding=view.findViewById(R.id.tvBinding)
tvNotice=view.findViewById(R.id.tvNotice)
llNoticeBackground=view.findViewById(R.id.llNoticeBackground)
llIntelligentMode=view.findViewById(R.id.llIntelligentMode)
acceleratedStartup=view.findViewById(R.id.acceleratedStartup)
countryIv=view.findViewById(R.id.countryIv)
nodeNameTv=view.findViewById(R.id.nodeNameTv)
ivProxyMode=view.findViewById(R.id.iv_proxy_mode)
tvProxyMode=view.findViewById(R.id.tv_proxy_model)
tvExpirationTime=view.findViewById(R.id.tvExpirationTime)
refreshExpire=view.findViewById(R.id.refresh_expire_iv)
llLine=view.findViewById(R.id.llLine)
clActivity=view.findViewById(R.id.clActivity)
clMember=view.findViewById(R.id.clMember)
llCustomer = view.findViewById(R.id.llCustomer)
tvBinding = view.findViewById(R.id.tvBinding)
tvNotice = view.findViewById(R.id.tvNotice)
llNoticeBackground = view.findViewById(R.id.llNoticeBackground)
llIntelligentMode = view.findViewById(R.id.llIntelligentMode)
acceleratedStartup = view.findViewById(R.id.acceleratedStartup)
countryIv = view.findViewById(R.id.countryIv)
nodeNameTv = view.findViewById(R.id.nodeNameTv)
ivProxyMode = view.findViewById(R.id.iv_proxy_mode)
tvProxyMode = view.findViewById(R.id.tv_proxy_model)
tvExpirationTime = view.findViewById(R.id.tvExpirationTime)
refreshExpire = view.findViewById(R.id.refresh_expire_iv)
llLine = view.findViewById(R.id.llLine)
clActivity = view.findViewById(R.id.clActivity)
clMember = view.findViewById(R.id.clMember)
llLine.setOnClickListener {
@ -219,7 +226,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
stopUpLoadTimer()
stopClash()
Log.d("NewAccFragment connectId${connectId}")
if(connectId!=-1){
if (connectId != -1) {
mainAtyVM.appStopStatus(connectId)
}
rxDialogSureCancel.cancel()
@ -248,6 +255,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
mact.goCheckLogin()
}
}
private fun initSS() {
val intentFilter = IntentFilter()
intentFilter.addAction(Intents.ACTION_CLASH_STARTED)
@ -265,6 +273,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
)
}
}
fun cleanUserInfo() {
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_PH_TOKEN)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN)
@ -282,6 +291,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java))
requireActivity().finish()
}
fun stopClash() {
context?.stopClashService()
}
@ -299,8 +309,9 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
uiMainActivity.stopUploadTimer()
}
}
private fun cleanProfile() {
launch(Dispatchers.IO) {
launch(Dispatchers.IO) {
profileBinder?.let { pm ->
pm.queryAll().forEach { profile ->
Log.d("cleanProfile go delete name==>${profile.name}, uuid==>${profile.uuid}")
@ -317,8 +328,8 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
override fun httpSuccess(httpStatus: HttpStatus.Success) {
when(httpStatus.reqType){
HttpReqType.GetRuningNotice->{
when (httpStatus.reqType) {
HttpReqType.GetRuningNotice -> {
(httpStatus.rsp as PhDownloadUrlRsp).let {
if (it.code == 1000) {
val data = it.data
@ -328,59 +339,67 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
}
}
HttpReqType.AppStartupStatus ->{
HttpReqType.AppStartupStatus -> {
Log.d("AppStartupStatus is Success ${httpStatus.rsp}")
val dataInfo = httpStatus.rsp as AppStartupStatus
if(dataInfo.data!=null){
if(dataInfo.data.id!=null){
connectId= dataInfo.data.id
if (dataInfo.data != null) {
if (dataInfo.data.id != null) {
connectId = dataInfo.data.id
MMKV.defaultMMKV().encode(BZYConstants.CONNECTID, dataInfo.data.id)
val serviceIntent= Intent(requireContext(), ConnectionService::class.java)
serviceIntent.putExtra("receiver",resultReceiver)
val serviceIntent = Intent(requireContext(), ConnectionService::class.java)
serviceIntent.putExtra("receiver", resultReceiver)
requireContext().startService(serviceIntent)
}
}
}
HttpReqType.AppUpStatus ->{
HttpReqType.AppUpStatus -> {
Log.d("AppUpStatus is Success ${httpStatus.rsp}")
}
HttpReqType.AppStopStatus ->{
HttpReqType.AppStopStatus -> {
Log.d("AppStopStatus is Success ${httpStatus.rsp}")
val serviceIntent= Intent(requireContext(), ConnectionService::class.java)
val serviceIntent = Intent(requireContext(), ConnectionService::class.java)
requireContext().stopService(serviceIntent)
}
else->{
else -> {
}
}
}
override fun httpFailure(httpStatus: HttpStatus.Failure) {
when(httpStatus.reqType){
HttpReqType.AppStartupStatus ->{
when (httpStatus.reqType) {
HttpReqType.AppStartupStatus -> {
Log.d("AppStartupStatus is Failure ${httpStatus.msg}")
}
HttpReqType.AppUpStatus ->{
HttpReqType.AppUpStatus -> {
Log.d("AppUpStatus is Failure ${httpStatus.msg}")
}
HttpReqType.AppStopStatus ->{
HttpReqType.AppStopStatus -> {
Log.d("AppStopStatus is Failure ${httpStatus.msg}")
}
else->{
else -> {
}
}
}
private val resultReceiver: ResultReceiver = object : ResultReceiver(null) {
override fun onReceiveResult(resultCode: Int, resultData: Bundle) {
val data = resultData.getString("data")
Log.d("ping to from Service: $data")
if(connectId!=-1){
if (connectId != -1) {
mainAtyVM.appUpStatus(connectId)
}
}
}
private fun initMainPageHorseRaceLamp(noticeData: String) {
if (noticeData.isNotEmpty()) {
tvNotice.text = noticeData
@ -431,6 +450,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
checkGlo()
}
}
private fun startClash() {
if (checkExpire()) {
if (isAdded) {
@ -438,11 +458,11 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
return
}
launch{
launch {
profileBinder?.let { pm ->
val active = pm.queryActive()
if (active == null) {
Log.d("startClash: 未选择")
Log.d("startClash: 未选择")
val pro = pm.queryAll().find {
it.name == Conf.getClashConfName(this@HomeFragment.context)
}
@ -480,7 +500,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
context?.startClashService()
mainAtyVM.appStartupStatus()
}
}else{
} else {
mainAtyVM.appStartupStatus()
}
} catch (e: Exception) {
@ -492,6 +512,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
}
private fun checkExpire(): Boolean {
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
if (validPeriod > 0) {
@ -518,6 +539,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
}
}
private fun stateChanged(state: Int, isShowToast: Boolean) {
Logger.i("!!!!!!!!!!:${state}")
when (state) {
@ -550,12 +572,13 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
}
}
else -> {}
}
}
private fun setNodeNameAndImg(it: String) {
launch(Dispatchers.Main) {
launch(Dispatchers.Main) {
nodeNameTv.text = it
when {
it.contains("中国", true) -> {
@ -623,7 +646,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
val isGlobal2 = MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_GLOBAL_MODEL, false)
Log.i("checkGlo isGlobal==>${isGlobal}, isGlobal2==>${isGlobal2}")
setProxyModeView(isGlobal)
launch(Dispatchers.IO) {
launch(Dispatchers.IO) {
if (isGlobal) {
if (clashRunning) {
getNodes()
@ -661,6 +684,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
}
}
private fun setProxyModeView(isGlobal: Boolean) {
if (isGlobal) {
ivProxyMode.setImageResource(R.drawable.ic_s_global)
@ -689,7 +713,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
proList?.let { proListItem ->
val nodeName = proListItem[0].name
if (!TextUtils.isEmpty(nodeName)) {
GlobalScope.launch(Dispatchers.IO) {
GlobalScope.launch(Dispatchers.IO) {
clashBinder?.let { cm ->
val o = cm.queryOverride(Clash.OverrideSlot.Session)
@ -758,6 +782,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
}
}
@SuppressLint("SimpleDateFormat")
fun setExpireDate() {
val isExpire = checkExpire()
@ -765,6 +790,13 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
if (isExpire) {
if (isAdded) {
endTimeInfo = resources.getString(R.string.AccountExpired)
this@HomeFragment.context?.let { mc ->
tvExpirationTime.setTextColor(
ContextCompat.getColor(
mc, R.color.red
)
)
}
}
} else {
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
@ -818,15 +850,17 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
tvExpirationTime.text = endTimeInfo
}
private fun goNewRecharge() {
if (activity != null) {
val uiMainActivity = activity as UIMainActivity
uiMainActivity.goBackupRechargeWeb()
}
}
inner class ClashBP : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.i("action==>" + intent?.action)
Log.i("action==>" + intent?.action)
when (intent?.action) {
Intents.ACTION_CLASH_STARTED -> {
if (::rxDialogShapeLoading.isInitialized) {
@ -869,6 +903,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
}
}
override fun onResume() {
super.onResume()
lifecycleScope.launch {
@ -880,6 +915,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
}
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
Logger.d("onActivityCreated")
@ -888,6 +924,7 @@ class HomeFragment: BaseFragment() , CoroutineScope by CoroutineScope(Dispatcher
mainAtyVM.getRuningNoticeInfo()
initSS()
}
private fun showBingDialogChoose() {
val dialog = DialogBandChoose(requireActivity())
dialog.setOnBandClickListener(object : DialogBandChoose.OnBandClickListener {

View File

@ -82,7 +82,7 @@
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:padding="10dp"
android:textSize="12sp"
android:textSize="16sp"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="新会员充值优惠,畅享未来更多精彩"
@ -176,7 +176,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:layout_marginTop="12dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="36dp"
android:background="@drawable/home_pay_bg"
app:layout_constraintEnd_toEndOf="parent"
@ -206,7 +206,7 @@
android:layout_marginStart="16dp"
android:text="@string/expire_date"
android:textColor="@color/blue_0136CB"
android:textSize="12sp"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/refresh_expire_iv"
app:layout_constraintStart_toStartOf="parent"
@ -219,7 +219,7 @@
android:layout_marginStart="8dp"
android:layout_marginEnd="@dimen/dp_10"
android:textColor="@color/blue_0136CB"
android:textSize="12sp"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/tvExpirationTimeTxt"
app:layout_constraintEnd_toStartOf="@+id/refresh_expire_iv"

View File

@ -249,6 +249,7 @@
android:text="@string/loginPagTips"
android:textColor="@color/gray_828282"
android:layout_marginEnd="@dimen/dp_40"
android:visibility="gone"
android:textSize="@dimen/layout_login_tv_register_textsize"
app:layout_constraintEnd_toStartOf="@+id/tv_forget_pwd"
app:layout_constraintStart_toStartOf="@+id/tv_login"
@ -258,44 +259,42 @@
android:id="@+id/tv_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/layout_login_tv_register_start_margin"
android:layout_marginTop="35dp"
android:layout_marginTop="@dimen/dp_15"
android:layout_marginBottom="@dimen/dp_10"
android:text="@string/register"
android:textColor="@drawable/loginlayout_register_text_color_selector"
android:textColor="@drawable/loginlayout_forget_text_color_selector"
android:textSize="@dimen/layout_login_tv_register_textsize"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_hongmeng_tip" />
android:visibility="visible"
app:layout_constraintStart_toStartOf="@+id/tv_login"
app:layout_constraintTop_toBottomOf="@+id/tv_login"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/tv_kefu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/layout_login_tv_register_start_margin"
android:layout_marginTop="35dp"
android:layout_marginBottom="@dimen/dp_10"
android:layout_marginTop="@dimen/dp_15"
android:text="@string/kefu"
android:textColor="@drawable/loginlayout_register_text_color_selector"
android:textColor="@drawable/loginlayout_forget_text_color_selector"
android:textSize="@dimen/layout_login_tv_register_textsize"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="visible"
app:layout_constraintStart_toEndOf="@+id/tv_register"
app:layout_constraintTop_toBottomOf="@+id/tv_hongmeng_tip" />
app:layout_constraintTop_toBottomOf="@+id/tv_login" />
<TextView
android:id="@+id/tv_forget_pwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/forget_pwd"
android:padding="5dp"
android:layout_marginTop="@dimen/dp_15"
android:textColor="@drawable/loginlayout_forget_text_color_selector"
android:textSize="@dimen/layout_login_forget_tv_textsize"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/tvTips"
app:layout_constraintEnd_toEndOf="@+id/tv_login"
app:layout_constraintTop_toTopOf="@+id/tvTips" />
app:layout_constraintTop_toBottomOf="@+id/tv_login" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -59,6 +59,7 @@
<dimen name="layout_register_tv_login_textsize">16sp</dimen>
<dimen name="def_height">50dp</dimen>
<dimen name="dp_10">10dp</dimen>
<dimen name="dp_15">15dp</dimen>
<dimen name="dp_4">4dp</dimen>
<dimen name="dp_40">40dp</dimen>
<dimen name="sp_14">14sp</dimen>