Commit bc52f167 authored by shiyl's avatar shiyl

Merge branch 'dev' of https://git.yidian-inc.com:8021/bp/ShenghuoquanBusiness into dev

# Conflicts:
#	Components/newscontent/src/main/java/com/yidian/shenghuoquan/newscontent/ui/LoginLifeCircleActivity.kt
parents 603713fd f67b7820
......@@ -9,6 +9,7 @@ import com.yidian.framework.mobile.xdiamond.SecretUtil
import com.yidian.utils.LogUtil
import com.yidian.utils.ToastUtil
import com.yidian.yac.ftdevicefinger.core.FtDeviceFingerManager
import java.lang.reflect.Type
class HttpParamsUtils{
companion object{
......@@ -42,7 +43,7 @@ class HttpParamsUtils{
}
}
fun<T> rsaDecryptResult(res: HttpResult<Any?>): HttpResult<T>{
fun<T> rsaDecryptResult(res: HttpResult<Any?>, type: Type): HttpResult<T>{
val rsaResult = res.result
val decodeResult = HttpResult<T>()
decodeResult.code = res.code
......@@ -59,7 +60,8 @@ class HttpParamsUtils{
val verify = SecretUtil.verifySign(verifyParams, secretNet)
return if(verify){
LogUtil.show("===============验签成功==================")
decodeResult.result = decryptResult.data
val resultJson = gson.toJson(decryptResult.data)
decodeResult.result = gson.fromJson<T>(resultJson, type)
decodeResult
}else {
ToastUtil.showToast(YdBaseApplication.context, "验签失败")
......@@ -67,7 +69,7 @@ class HttpParamsUtils{
}
}else{
val resultJson = gson.toJson(rsaResult)
decodeResult.result = gson.fromJson<T>(resultJson, object: TypeToken<T>(){}.type)
decodeResult.result = gson.fromJson<T>(resultJson, type)
return decodeResult
}
}
......
......@@ -10,6 +10,7 @@ import com.yidian.common.YdBaseApplication
import com.yidian.utils.ToastUtil
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import java.lang.reflect.ParameterizedType
import kotlin.reflect.typeOf
abstract class HttpResultSubscriber<T>(private var showProgress: Boolean = false): Observer<HttpResult<Any?>> {
......@@ -50,7 +51,8 @@ abstract class HttpResultSubscriber<T>(private var showProgress: Boolean = false
override fun onNext(res: HttpResult<Any?>) {
if (res.code == 0) {
val decodeResult = HttpParamsUtils.rsaDecryptResult<T>(res)
val type = (this.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
val decodeResult = HttpParamsUtils.rsaDecryptResult<T>(res, type)
onRequestSuccess(decodeResult)
}else{
val decodeResult = HttpResult<T>()
......@@ -74,7 +76,7 @@ abstract class HttpResultSubscriber<T>(private var showProgress: Boolean = false
}
@SuppressLint("NewApi")
fun onRequestSuccess(result: HttpResult<T>) {
fun onRequestSuccess(result: HttpResult<T>?) {
onSuccess(result)
}
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.http
import com.google.gson.reflect.TypeToken
import com.yidian.common.YdBaseApplication
import com.yidian.common.http.HttpParamsUtils
import com.yidian.common.http.HttpResult
......@@ -117,7 +118,7 @@ class ApiService {
.getKSYunToken(publicParamsMap, privateParamsMap)
.execute().body()
if (res?.code == 0) {
return HttpParamsUtils.rsaDecryptResult(res)
return HttpParamsUtils.rsaDecryptResult(res, object: TypeToken<GetKSYunTokenBean.Response>(){}.type)
}else{
val decodeResult = HttpResult<GetKSYunTokenBean.Response>()
decodeResult.code = res?.code!!
......
......@@ -3,7 +3,8 @@ package com.yidian.shenghuoquan.newscontent.ui.auth
import com.yidian.shenghuoquan.newscontent.bean.LifeAccountMerchantAuthData
import com.yidian.shenghuoquan.newscontent.bean.LifeAccountPersonalAuthData
import com.yidian.shenghuoquan.newscontent.constant.Constant
import com.yidian.shenghuoquan.newscontent.http.httpbean.*
import com.yidian.shenghuoquan.newscontent.http.httpbean.BusinessLicenseOCRBean
import com.yidian.shenghuoquan.newscontent.http.httpbean.GetIDCardOCRBean
/**
* author: yinjiacheng
......@@ -38,8 +39,10 @@ object LifeAccountAuthDataManager {
val requestMap = HashMap<String, String?>()
requestMap["front_img"] = personalAuthData.idCardPortraitFaceObjectKey
requestMap["bak_img"] = personalAuthData.idCardNationalEmblemFaceObjectKey
requestMap["front_completeness"] = personalAuthData.idCardPortraitFaceCompleteness.toString()
requestMap["bak_completeness"] = personalAuthData.idCardNationalEmblemFaceCompleteness.toString()
requestMap["front_completeness"] =
personalAuthData.idCardPortraitFaceCompleteness.toString()
requestMap["bak_completeness"] =
personalAuthData.idCardNationalEmblemFaceCompleteness.toString()
requestMap["id_card"] = personalAuthData.idCardNum
requestMap["gender"] = personalAuthData.gender
requestMap["name"] = personalAuthData.realName
......@@ -77,9 +80,9 @@ object LifeAccountAuthDataManager {
* 生成营业执照上传接口请求体
*/
fun generateAuthBusinessLicenseCommitRequest(
userId: Long,
dataType: Int,
lifeAccountId: Long?
userId: Long,
dataType: Int,
lifeAccountId: Long?
): HashMap<String, String?> {
val requestMap = HashMap<String, String?>()
requestMap["user_id"] = userId.toString()
......@@ -112,15 +115,17 @@ object LifeAccountAuthDataManager {
* 生成个体工商户身份上传接口请求体
*/
fun generateAuthIndividualBusinessIdentityCommitRequest(
dataType: Int
dataType: Int
): HashMap<String, String?> {
val requestMap = HashMap<String, String?>()
requestMap["code"] = merchantAuthData.registrationCode
requestMap["data_type"] = dataType.toString()
requestMap["front_img"] = personalAuthData.idCardPortraitFaceObjectKey
requestMap["bak_img"] = personalAuthData.idCardNationalEmblemFaceObjectKey
requestMap["front_completeness"] = personalAuthData.idCardPortraitFaceCompleteness.toString()
requestMap["bak_completeness"] = personalAuthData.idCardNationalEmblemFaceCompleteness.toString()
requestMap["front_completeness"] =
personalAuthData.idCardPortraitFaceCompleteness.toString()
requestMap["bak_completeness"] =
personalAuthData.idCardNationalEmblemFaceCompleteness.toString()
requestMap["idcard_number"] = personalAuthData.idCardNum
requestMap["gender"] = personalAuthData.gender
requestMap["name"] = personalAuthData.realName
......@@ -139,15 +144,17 @@ object LifeAccountAuthDataManager {
* 生成普通企业法人身份信息上传接口请求体
*/
fun generateAuthEnterpriseLegalIdentityCommitRequest(
authRecordId: Long,
lifeAccountId: Long?
authRecordId: Long,
lifeAccountId: Long?
): HashMap<String, String?> {
val requestMap = HashMap<String, String?>()
requestMap["record_id"] = authRecordId.toString()
requestMap["front_img"] = personalAuthData.idCardPortraitFaceObjectKey
requestMap["bak_img"] = personalAuthData.idCardNationalEmblemFaceObjectKey
requestMap["front_completeness"] = personalAuthData.idCardPortraitFaceCompleteness.toString()
requestMap["bak_completeness"] = personalAuthData.idCardNationalEmblemFaceCompleteness.toString()
requestMap["front_completeness"] =
personalAuthData.idCardPortraitFaceCompleteness.toString()
requestMap["bak_completeness"] =
personalAuthData.idCardNationalEmblemFaceCompleteness.toString()
requestMap["idcard_number"] = personalAuthData.idCardNum
requestMap["gender"] = personalAuthData.gender
requestMap["name"] = personalAuthData.realName
......
......@@ -4,7 +4,6 @@ import android.app.Activity
import android.content.ContentResolver
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Bundle
......@@ -42,6 +41,7 @@ import com.yidian.shenghuoquan.newscontent.utils.FileUtil
import com.yidian.shenghuoquan.newscontent.utils.KS3Core
import com.yidian.shenghuoquan.newscontent.widget.LifeAccountAuthIdentityInfoEditView
import com.yidian.shenghuoquan.newscontent.widget.LifeAccountAuthImageView
import com.yidian.shenghuoquan.newscontent.widget.LifeAccountFaceAuthView
import com.yidian.utils.ToastUtil
import java.io.File
import java.io.FileOutputStream
......@@ -57,7 +57,8 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
DetectCallback, KS3Core.OnKS3TaskListener, IAuthPersonalCheckCallback,
IAuthLiveIdentityCallback, LifeAccountAuthImageView.OnLifeAccountAuthImageViewCallback,
LifeAccountAuthIdentityInfoEditView.OnLifeAccountAuthIdentityInfoEditViewCallback,
IAuthIndividualBusinessIdentityCommitCallback, IAuthEnterpriseLiveIdentityCallback {
IAuthIndividualBusinessIdentityCommitCallback, IAuthEnterpriseLiveIdentityCallback,
LifeAccountFaceAuthView.OnLifeAccountFaceAuthCallback {
companion object {
// 身份证采集页面回传数据
......@@ -96,7 +97,7 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
/**
* 当前认证类型
*/
private var authType: Int? = 0
private var authType: Int? = null
override fun createViewBinding(
inflater: LayoutInflater,
......@@ -121,7 +122,7 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
}
private fun initView() {
authType = arguments?.getInt(Constant.TYPE_AUTH, 0)
authType = arguments?.getInt(Constant.TYPE_AUTH, -1) ?: Constant.TYPE_AUTH_PERSONAL
when (authType) {
Constant.TYPE_AUTH_PERSONAL -> {
viewBinding.evRealName.setTitleContent(resources.getString(R.string.real_name))
......@@ -134,18 +135,19 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
}
}
viewBinding.evMobile.isVisible = authType == Constant.TYPE_AUTH_COMMON_ENTERPRISE
viewBinding.clFaceAuth.isVisible = authType == Constant.TYPE_AUTH_INDIVIDUAL_BUSINESS
viewBinding.avFaceAuth.isVisible =
(authType == Constant.TYPE_AUTH_PERSONAL) or (authType == Constant.TYPE_AUTH_INDIVIDUAL_BUSINESS)
}
private fun initListener() {
viewBinding.ivIdCardPortraitFace.setOnClickListener(this)
viewBinding.ivIdCardNationalEmblemFace.setOnClickListener(this)
viewBinding.ivFaceAuthStart.setOnClickListener(this)
viewBinding.ivIdCardPortraitFace.setOnLifeAccountAuthImageViewCallback(this)
viewBinding.ivIdCardNationalEmblemFace.setOnLifeAccountAuthImageViewCallback(this)
viewBinding.evRealName.setOnLifeAccountAuthIdentityInfoEditViewCallback(this)
viewBinding.evIdCardNumber.setOnLifeAccountAuthIdentityInfoEditViewCallback(this)
viewBinding.evMobile.setOnLifeAccountAuthIdentityInfoEditViewCallback(this)
viewBinding.avFaceAuth.setOnLifeAccountFaceAuthCallback(this)
}
/**
......@@ -224,26 +226,6 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
).show()
}
}
R.id.iv_face_auth_start -> {
// 判断是否满足条件进行活体检测
if (!checkFaceAuthCondition()) return
when (authType) {
Constant.TYPE_AUTH_PERSONAL -> {
ApiService.authPersonalCheck(
this,
LifeAccountAuthDataManager.generateAuthPersonalCheckRequest()
)
}
Constant.TYPE_AUTH_INDIVIDUAL_BUSINESS -> {
ApiService.authIndividualBusinessIdentityCommit(
this,
LifeAccountAuthDataManager.generateAuthIndividualBusinessIdentityCommitRequest(
Constant.TYPE_INDIVIDUAL_BUSINESS
)
)
}
}
}
}
}
......@@ -452,9 +434,12 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
*/
private fun startIDCardOCR() {
val requestParams = HashMap<String, String?>()
requestParams["posit_image_objectid"] = LifeAccountAuthDataManager.personalAuthData.idCardPortraitFaceObjectKey
requestParams["back_image_objectid"] = LifeAccountAuthDataManager.personalAuthData.idCardNationalEmblemFaceObjectKey
requestParams["bucket"] = LifeAccountAuthDataManager.personalAuthData.idCardPortraitFaceBucket
requestParams["posit_image_objectid"] =
LifeAccountAuthDataManager.personalAuthData.idCardPortraitFaceObjectKey
requestParams["back_image_objectid"] =
LifeAccountAuthDataManager.personalAuthData.idCardNationalEmblemFaceObjectKey
requestParams["bucket"] =
LifeAccountAuthDataManager.personalAuthData.idCardPortraitFaceBucket
ApiService.getIDCardOCR(this, requestParams)
}
......@@ -495,7 +480,7 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
// 保存人脸验证结果
LifeAccountAuthDataManager.personalAuthData.isFaceAuthPass = true
// 人脸验证通过UI
changeFaceAuthUI(true)
viewBinding.avFaceAuth.showFaceAuthResult(true)
// 删除活体检测数据
File(cachePath + Constant.FILE_PATH_ALIVE_DETECT_VERIFY_DATA).delete()
// 锁定当前输入状态 即完成人脸验证后无法修改身份证照片、姓名、身份证号
......@@ -523,7 +508,7 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
Log.e(Constant.LIFE_ACCOUNT_AUTH_TAG, "live detect failure, message: ${t?.reason}")
LifeAccountAuthDataManager.personalAuthData.isFaceAuthPass = false
// 人脸验证未通过UI
changeFaceAuthUI(false)
viewBinding.avFaceAuth.showFaceAuthResult(false)
}
override fun onPreStart() {
......@@ -564,7 +549,7 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
Constant.LIFE_ACCOUNT_AUTH_TAG,
"alive detect detect failure, errorCode: $errorCode, errorMessage: $errorMessage"
)
changeFaceAuthUI(false)
viewBinding.avFaceAuth.showFaceAuthResult(false)
}
}
......@@ -590,7 +575,8 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
}
val requestParams = HashMap<String, String?>()
requestParams["biz_token"] = LifeAccountAuthDataManager.personalAuthData.liveDetectBizToken
requestParams["meglive_objectid"] = LifeAccountAuthDataManager.personalAuthData.liveDetectObjectKey
requestParams["meglive_objectid"] =
LifeAccountAuthDataManager.personalAuthData.liveDetectObjectKey
ApiService.identifyIdOcrVerify(this, requestParams)
}
......@@ -684,6 +670,27 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
}
}
override fun onStartFaceAuth() {
// 判断是否满足条件进行活体检测
if (!checkFaceAuthCondition()) return
when (authType) {
Constant.TYPE_AUTH_PERSONAL -> {
ApiService.authPersonalCheck(
this,
LifeAccountAuthDataManager.generateAuthPersonalCheckRequest()
)
}
Constant.TYPE_AUTH_INDIVIDUAL_BUSINESS -> {
ApiService.authIndividualBusinessIdentityCommit(
this,
LifeAccountAuthDataManager.generateAuthIndividualBusinessIdentityCommitRequest(
Constant.TYPE_INDIVIDUAL_BUSINESS
)
)
}
}
}
override fun authIndividualBusinessIdentityCommitSuccess() {
// 身份信息校验成功后才允许进行人脸验证
// 若存在上一次活体检测数据则删除 处理活体检测失败 再次进入
......@@ -714,24 +721,6 @@ class LifeAccountIDCardAuthFragment : BaseFragment<FragmentLifeAccountIdCardAuth
)
}
/**
* 人脸验证结果UI
* @param result true为验证通过 false为验证未通过
*/
private fun changeFaceAuthUI(result: Boolean) {
if (result) {
viewBinding.tvFaceAuthResult.text = resources.getText(R.string.face_auth_success)
viewBinding.tvFaceAuthResult.setTextColor(Color.parseColor("#FF6BB81F"))
viewBinding.ivFaceAuthStart.visibility = View.GONE
viewBinding.tvFaceAuthErrorTips.visibility = View.GONE
} else {
viewBinding.tvFaceAuthResult.text = resources.getText(R.string.face_auth_fail)
viewBinding.tvFaceAuthResult.setTextColor(Color.parseColor("#FFFF3A3A"))
viewBinding.tvFaceAuthErrorTips.visibility = View.VISIBLE
viewBinding.tvFaceAuthErrorTips.text = resources.getText(R.string.face_auth_error_tips)
}
}
/**
* 本地校验是否可以进行人脸验证
* 必须同时满足真实姓名已填、身份证号已填、身份证两面已上传、职业标签已选
......
package com.yidian.shenghuoquan.newscontent.widget
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.View
import com.yidian.nightmode.widget.YdConstraintLayout
import com.yidian.shenghuoquan.newscontent.R
import com.yidian.shenghuoquan.newscontent.databinding.ViewLifeAccountFaceAuthBinding
/**
* author: yinjiacheng
* date: 6/6/21 3:57 PM
* description: 生活号认证 人脸认证
*/
class LifeAccountFaceAuthView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : YdConstraintLayout(context, attrs, defStyle), View.OnClickListener {
private val viewBinding = ViewLifeAccountFaceAuthBinding.bind(
View.inflate(
getContext(), R.layout.view_life_account_face_auth, this
)
)
private var callback: OnLifeAccountFaceAuthCallback? = null
init {
viewBinding.ivFaceAuthStart.setOnClickListener(this)
}
/**
* 人脸验证结果UI
* @param result true为验证通过 false为验证未通过
*/
fun showFaceAuthResult(result: Boolean) {
if (result) {
viewBinding.tvFaceAuthResult.text = resources.getText(R.string.face_auth_success)
viewBinding.tvFaceAuthResult.setTextColor(Color.parseColor("#FF6BB81F"))
viewBinding.ivFaceAuthStart.visibility = View.GONE
viewBinding.tvFaceAuthErrorTips.visibility = View.GONE
} else {
viewBinding.tvFaceAuthResult.text = resources.getText(R.string.face_auth_fail)
viewBinding.tvFaceAuthResult.setTextColor(Color.parseColor("#FFFF3A3A"))
viewBinding.tvFaceAuthErrorTips.visibility = View.VISIBLE
viewBinding.tvFaceAuthErrorTips.text = resources.getText(R.string.face_auth_error_tips)
}
}
override fun onClick(v: View?) {
if (v?.id == R.id.iv_face_auth_start) {
callback?.onStartFaceAuth()
}
}
fun setOnLifeAccountFaceAuthCallback(callback: OnLifeAccountFaceAuthCallback) {
this.callback = callback
}
interface OnLifeAccountFaceAuthCallback {
/**
* 进行人脸验证
*/
fun onStartFaceAuth()
}
}
\ No newline at end of file
......@@ -88,65 +88,13 @@
app:LifeAccountAuthIdentityInfoEditView_hint_text="@string/input_id_card_number"
app:layout_constraintTop_toBottomOf="@id/ev_id_card_number" />
<com.yidian.nightmode.widget.YdConstraintLayout
android:id="@+id/cl_face_auth"
<com.yidian.shenghuoquan.newscontent.widget.LifeAccountFaceAuthView
android:id="@+id/av_face_auth"
android:layout_width="match_parent"
android:layout_height="85dp"
android:layout_height="wrap_content"
android:paddingStart="19dp"
android:paddingTop="17dp"
android:paddingEnd="12dp"
android:paddingBottom="6dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/ev_id_card_number">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_face_auth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="@string/face_auth"
android:textColor="#FF333333"
android:textSize="15sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_face_auth_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:includeFontPadding="false"
android:text="@string/start_face_auth"
android:textColor="#FF1852F1"
android:textSize="15sp"
app:layout_constraintEnd_toStartOf="@id/iv_face_auth_start"
app:layout_constraintTop_toTopOf="parent" />
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_face_auth_start"
android:layout_width="23dp"
android:layout_height="23dp"
android:src="@mipmap/icon_next"
app:layout_constraintBottom_toBottomOf="@id/tv_face_auth"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_face_auth" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_marginTop="17dp"
android:background="#FFF2F2F2"
app:layout_constraintTop_toBottomOf="@id/tv_face_auth" />
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_face_auth_error_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:textColor="#FFFF3A3A"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent" />
</com.yidian.nightmode.widget.YdConstraintLayout>
app:layout_constraintTop_toBottomOf="@id/ev_id_card_number" />
</com.yidian.nightmode.widget.YdConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.yidian.nightmode.widget.YdConstraintLayout 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:paddingTop="17dp"
android:paddingBottom="6dp">
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_face_auth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="@string/face_auth"
android:textColor="#FF333333"
android:textSize="15sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_face_auth_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:includeFontPadding="false"
android:text="@string/start_face_auth"
android:textColor="#FF1852F1"
android:textSize="15sp"
app:layout_constraintEnd_toStartOf="@id/iv_face_auth_start"
app:layout_constraintTop_toTopOf="parent" />
<com.yidian.nightmode.widget.YdImageView
android:id="@+id/iv_face_auth_start"
android:layout_width="23dp"
android:layout_height="23dp"
android:src="@mipmap/icon_next"
app:layout_constraintBottom_toBottomOf="@id/tv_face_auth"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_face_auth" />
<View
android:id="@+id/view_divider"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_marginTop="17dp"
android:background="#FFF2F2F2"
app:layout_constraintTop_toBottomOf="@id/tv_face_auth" />
<com.yidian.nightmode.widget.YdTextView
android:id="@+id/tv_face_auth_error_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:includeFontPadding="false"
android:textColor="#FFFF3A3A"
android:textSize="12sp"
app:layout_constraintTop_toBottomOf="@id/view_divider" />
</com.yidian.nightmode.widget.YdConstraintLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment