feat:初步完成发红包接口对接
feat:增加服务器时间字段
This commit is contained in:
@@ -65,6 +65,7 @@ import com.yizhuan.xchat_android_core.im.custom.bean.OpenSignInAttachment;
|
||||
import com.yizhuan.xchat_android_core.initial.InitialModel;
|
||||
import com.yizhuan.xchat_android_core.interceptor.NoParamsInterceptor;
|
||||
import com.yizhuan.xchat_android_core.interceptor.ParamsInterceptor;
|
||||
import com.yizhuan.xchat_android_core.interceptor.TimeSyncInterceptor;
|
||||
import com.yizhuan.xchat_android_core.manager.IMMessageManager;
|
||||
import com.yizhuan.xchat_android_core.manager.IMSystemMsgManager;
|
||||
import com.yizhuan.xchat_android_core.market_verify.MarketVerifyModel;
|
||||
@@ -407,6 +408,7 @@ public class XChatApplication extends BaseApp {
|
||||
.setBaseUrl(url)
|
||||
.addInterceptors(new ParamsInterceptor(httpParams))
|
||||
.addInterceptors(new NoParamsInterceptor())//注意:拦截器的添加顺序,请求的拦截顺序
|
||||
.addInterceptors(new TimeSyncInterceptor())
|
||||
.certificates()
|
||||
.build();
|
||||
//单例的model 初始化
|
||||
|
@@ -47,6 +47,7 @@ import com.yizhuan.erban.avroom.dialog.RoomOperationDialog
|
||||
import com.yizhuan.erban.avroom.firstcharge.FirstChargeDialog
|
||||
import com.yizhuan.erban.avroom.presenter.BaseRoomPresenter
|
||||
import com.yizhuan.erban.avroom.redpackage.RedPackageSendDialog
|
||||
import com.yizhuan.erban.avroom.redpackage.send.RedPackageSendDialog2
|
||||
import com.yizhuan.erban.avroom.room_album.RoomAlbumModel
|
||||
import com.yizhuan.erban.avroom.view.IBaseRoomView
|
||||
import com.yizhuan.erban.avroom.widget.BottomView
|
||||
@@ -162,7 +163,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
|
||||
* 是否開啟禮物值顯示
|
||||
*/
|
||||
private var showGiftValue = false
|
||||
private var redPackageSendDialog: RedPackageSendDialog? = null
|
||||
private var redPackageSendDialog: RedPackageSendDialog2? = null
|
||||
private val mOnSoftKeyBoardChangeListener: OnSoftKeyBoardChangeListener =
|
||||
object : OnSoftKeyBoardChangeListener {
|
||||
override fun keyBoardShow(height: Int) {
|
||||
@@ -1289,7 +1290,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
|
||||
override fun onMoreBtnClick() {
|
||||
val dialog = RoomOperationDialog(mContext)
|
||||
dialog.setOnActionListener {
|
||||
redPackageSendDialog = RedPackageSendDialog()
|
||||
redPackageSendDialog = RedPackageSendDialog2()
|
||||
redPackageSendDialog?.show(activity)
|
||||
}
|
||||
dialog.show()
|
||||
|
@@ -529,6 +529,11 @@ public class HomePartyRoomFragment extends BaseRoomFragment<IHomePartyView, Home
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
gameBinding.redPackageWidget.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
|
@@ -28,6 +28,7 @@ import com.yizhuan.xchat_android_core.pay.PayModel
|
||||
import com.yizhuan.xchat_android_core.pay.event.UpdateWalletInfoEvent
|
||||
import com.yizhuan.xchat_android_core.redpackage.*
|
||||
import com.yizhuan.xchat_android_core.user.UserModel
|
||||
import com.yizhuan.xchat_android_core.utils.LogUtils
|
||||
import com.yizhuan.xchat_android_core.utils.toIntOrDef
|
||||
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
|
||||
import com.yizhuan.xchat_android_library.common.util.DeviceUtil
|
||||
@@ -219,23 +220,24 @@ class RedPackageSendDialog : BaseDialog<DialogRedPackageSendBinding>(), GridPass
|
||||
override fun onTextChanged(psw: String) {
|
||||
val password = passWordFragment?.password?.password ?: ""
|
||||
if (password.length == 6) {
|
||||
dialogManager.showProgressDialog(context)
|
||||
RedPackageModel.sendRedPackage(binding?.editGoldNum?.text.toString(),
|
||||
binding?.editRedText?.text.toString().ifEmpty { "恭喜發財,大吉大利!" },
|
||||
binding?.editRedNum?.text.toString(),
|
||||
AvRoomDataManager.get().mCurrentRoomInfo?.uid.toString(), getRedType(), DESUtils.DESAndBase64(password))
|
||||
.doOnError {
|
||||
dialogManager.dismissDialog()
|
||||
SingleToastUtil.showToast(it.message)
|
||||
passWordFragment?.password?.clearPassword()
|
||||
}
|
||||
.subscribe { _ ->
|
||||
PayModel.get().getWalletInfo(AuthModel.get().currentUid).subscribe()
|
||||
dialogManager.dismissDialog()
|
||||
SingleToastUtil.showToast("發送成功")
|
||||
passWordFragment?.dismissAllowingStateLoss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
LogUtils.d("onTextChanged() editGoldNum:${binding?.editGoldNum?.text.toString()} NUM:${binding?.editRedNum?.text.toString()}")
|
||||
// dialogManager.showProgressDialog(context)
|
||||
// RedPackageModel.sendRedPackage(binding?.editGoldNum?.text.toString(),
|
||||
// binding?.editRedText?.text.toString().ifEmpty { "恭喜發財,大吉大利!" },
|
||||
// binding?.editRedNum?.text.toString(),
|
||||
// AvRoomDataManager.get().mCurrentRoomInfo?.uid.toString(), getRedType(), DESUtils.DESAndBase64(password))
|
||||
// .doOnError {
|
||||
// dialogManager.dismissDialog()
|
||||
// SingleToastUtil.showToast(it.message)
|
||||
// passWordFragment?.password?.clearPassword()
|
||||
// }
|
||||
// .subscribe { _ ->
|
||||
// PayModel.get().getWalletInfo(AuthModel.get().currentUid).subscribe()
|
||||
// dialogManager.dismissDialog()
|
||||
// SingleToastUtil.showToast("發送成功")
|
||||
// passWordFragment?.dismissAllowingStateLoss()
|
||||
// dismissAllowingStateLoss()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -9,10 +9,10 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.xchat_android_core.redpackage.RedPackageNotifyInfo
|
||||
import com.yizhuan.xchat_android_core.utils.LogUtils
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.functions.Predicate
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.TimeZone
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -52,6 +52,7 @@ class RedPackageWidget : ConstraintLayout {
|
||||
LayoutInflater.from(context)
|
||||
.inflate(R.layout.red_package_widget, this, true)
|
||||
textView = findViewById(R.id.tv_text)
|
||||
this.setBackgroundResource(R.drawable.red_package_widget_bg)
|
||||
}
|
||||
|
||||
fun loadData(data: RedPackageNotifyInfo?) {
|
||||
|
@@ -2,34 +2,60 @@ package com.yizhuan.erban.avroom.redpackage.send
|
||||
|
||||
import android.graphics.Color
|
||||
import androidx.core.view.isVisible
|
||||
import com.chuhai.utils.ktx.addDisableFilter
|
||||
import com.chuhai.utils.ktx.getColorById
|
||||
import com.chuhai.utils.ktx.singleClick
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.erban.base.BaseBindingFragment
|
||||
import com.yizhuan.erban.databinding.RedPackagePrivateFragmentBinding
|
||||
import com.yizhuan.erban.pay.password.GiveGoldPassWordFragment
|
||||
import com.yizhuan.erban.pay.widget.GridPasswordNoFocusView
|
||||
import com.yizhuan.erban.ui.setting.ModifyPwdActivity
|
||||
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil
|
||||
import com.yizhuan.erban.ui.widget.recyclerview.decoration.ColorDecoration
|
||||
import com.yizhuan.xchat_android_core.auth.AuthModel
|
||||
import com.yizhuan.xchat_android_core.initial.InitialModel
|
||||
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager
|
||||
import com.yizhuan.xchat_android_core.pay.PayModel
|
||||
import com.yizhuan.xchat_android_core.redpackage.RedPackageModel
|
||||
import com.yizhuan.xchat_android_core.user.UserModel
|
||||
import com.yizhuan.xchat_android_core.utils.toIntOrDef
|
||||
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
|
||||
import com.yizhuan.xchat_android_library.utils.keyboard.KeyboardUtil
|
||||
import com.yizhuan.xchat_android_library.utils.ResUtil
|
||||
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
|
||||
import com.yizhuan.xchat_android_library.utils.codec.DESUtils
|
||||
import okhttp3.internal.toLongOrDefault
|
||||
|
||||
/**
|
||||
* Created by Max on 2023/10/23 12:14
|
||||
* Desc:
|
||||
* Desc: 厅内红包
|
||||
**/
|
||||
@ActLayoutRes(R.layout.red_package_private_fragment)
|
||||
class PrivateRedPackageEditorFragment : BaseBindingFragment<RedPackagePrivateFragmentBinding>() {
|
||||
|
||||
private var passWordFragment: GiveGoldPassWordFragment? = null
|
||||
|
||||
private var typeAdapter: RedPackageTypeItemAdapter? = null
|
||||
|
||||
// 生效时间类型 0 立即生效 1 限时生效
|
||||
private var timeType = 0
|
||||
override fun initiate() {
|
||||
mBinding.etText.addDisableFilter(" ", "\n")
|
||||
initTypeView()
|
||||
updateTimeView(true)
|
||||
}
|
||||
|
||||
override fun onSetListener() {
|
||||
super.onSetListener()
|
||||
mBinding.tvNow.setOnClickListener {
|
||||
mBinding.tvNow.singleClick {
|
||||
updateTimeView(true)
|
||||
}
|
||||
mBinding.tvDelay.setOnClickListener {
|
||||
mBinding.tvDelay.singleClick {
|
||||
updateTimeView(false)
|
||||
}
|
||||
mBinding.tvSend.singleClick {
|
||||
checkSend()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initTypeView() {
|
||||
@@ -41,33 +67,34 @@ class PrivateRedPackageEditorFragment : BaseBindingFragment<RedPackagePrivateFra
|
||||
val list = ArrayList<RedPackageTypeItemAdapter.ItemData>()
|
||||
list.add(
|
||||
RedPackageTypeItemAdapter.ItemData(
|
||||
"UNLIMITED",
|
||||
1,
|
||||
R.string.red_package_type_unlimited_name,
|
||||
R.string.red_package_type_unlimited_tips
|
||||
)
|
||||
)
|
||||
list.add(
|
||||
RedPackageTypeItemAdapter.ItemData(
|
||||
"FOLLOW",
|
||||
2,
|
||||
R.string.red_package_type_follow_name,
|
||||
R.string.red_package_type_follow_tips
|
||||
)
|
||||
)
|
||||
list.add(
|
||||
RedPackageTypeItemAdapter.ItemData(
|
||||
"SHARE",
|
||||
3,
|
||||
R.string.red_package_type_share_name,
|
||||
R.string.red_package_type_share_tips
|
||||
)
|
||||
)
|
||||
list.add(
|
||||
RedPackageTypeItemAdapter.ItemData(
|
||||
"MSG",
|
||||
4,
|
||||
R.string.red_package_type_msg_name,
|
||||
R.string.red_package_type_msg_tips
|
||||
)
|
||||
)
|
||||
val adapter = RedPackageTypeItemAdapter(list)
|
||||
typeAdapter = adapter
|
||||
adapter.setOnItemClickListener { _, view, position ->
|
||||
adapter.select(position)
|
||||
updateTypeView(adapter.getSelect()?.type)
|
||||
@@ -81,15 +108,15 @@ class PrivateRedPackageEditorFragment : BaseBindingFragment<RedPackagePrivateFra
|
||||
/**
|
||||
* 更新红包类型对应的视图
|
||||
*/
|
||||
private fun updateTypeView(type: String?) {
|
||||
private fun updateTypeView(type: Int?) {
|
||||
when (type) {
|
||||
"UNLIMITED" -> {
|
||||
1 -> {
|
||||
mBinding.tvNow.isVisible = true
|
||||
mBinding.tvDelay.isVisible = true
|
||||
mBinding.etText.isVisible = false
|
||||
}
|
||||
|
||||
"MSG" -> {
|
||||
4 -> {
|
||||
mBinding.tvNow.isVisible = false
|
||||
mBinding.tvDelay.isVisible = false
|
||||
mBinding.etText.isVisible = true
|
||||
@@ -108,15 +135,128 @@ class PrivateRedPackageEditorFragment : BaseBindingFragment<RedPackagePrivateFra
|
||||
*/
|
||||
private fun updateTimeView(nowOrDelay: Boolean) {
|
||||
if (nowOrDelay) {
|
||||
timeType = 0
|
||||
mBinding.tvNow.setBackgroundResource(R.drawable.red_package_bg_type_selected)
|
||||
mBinding.tvDelay.setBackgroundResource(R.drawable.shape_f8f8fa_8)
|
||||
mBinding.tvNow.setTextColor(mBinding.root.context.getColorById(R.color.color_FF285C))
|
||||
mBinding.tvDelay.setTextColor(mBinding.root.context.getColorById(R.color.color_767585))
|
||||
} else {
|
||||
timeType = 1
|
||||
mBinding.tvNow.setBackgroundResource(R.drawable.shape_f8f8fa_8)
|
||||
mBinding.tvDelay.setBackgroundResource(R.drawable.red_package_bg_type_selected)
|
||||
mBinding.tvNow.setTextColor(mBinding.root.context.getColorById(R.color.color_767585))
|
||||
mBinding.tvDelay.setTextColor(mBinding.root.context.getColorById(R.color.color_FF285C))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSend() {
|
||||
val initInfo = InitialModel.get().cacheInitInfo
|
||||
if (initInfo == null) {
|
||||
SingleToastUtil.showToast(ResUtil.getString(R.string.avroom_redpackage_redpackagesenddialog_01))
|
||||
return
|
||||
}
|
||||
val typeItem = typeAdapter?.getSelect()
|
||||
if (typeItem?.type == 4) {
|
||||
if (mBinding.etText.text.toString().trim().isEmpty()) {
|
||||
toast(R.string.red_package_msg_empty_tips)
|
||||
return
|
||||
}
|
||||
}
|
||||
val minNum = initInfo.redEnvelopeConfig.roomRedEnvelopeMinNum
|
||||
val maxNum = initInfo.redEnvelopeConfig.roomRedEnvelopeMaxNum
|
||||
val minGold = initInfo.redEnvelopeConfig.roomRedEnvelopeMinAmount
|
||||
val maxGold = initInfo.redEnvelopeConfig.roomRedEnvelopeMaxAmount
|
||||
val rate =
|
||||
if (initInfo.redEnvelopeConfig.exchangeDiamondsRate == 0.0) 0.68 else initInfo.redEnvelopeConfig.exchangeDiamondsRate
|
||||
|
||||
val redNum = mBinding?.etNum?.text.toString().toIntOrDef()
|
||||
if (redNum < minNum || redNum > maxNum) {
|
||||
SingleToastUtil.showToast("紅包數量不能小於${minNum}或大於${maxNum}!")
|
||||
return
|
||||
}
|
||||
val goldNum = mBinding?.etMoney?.text.toString().toIntOrDef()
|
||||
if (goldNum % 10 != 0) {
|
||||
SingleToastUtil.showToast("鉆石數必須為10的倍數!")
|
||||
return
|
||||
}
|
||||
|
||||
if (goldNum < minGold || goldNum > maxGold) {
|
||||
SingleToastUtil.showToast("鉆石數量不能小於${minGold}或大於${maxGold}!")
|
||||
return
|
||||
}
|
||||
if (goldNum.toFloat() / redNum * rate < 0.1) {//單個手氣紅包價值不低於0.1水晶
|
||||
SingleToastUtil.showToast("單個紅包金額過低")
|
||||
return
|
||||
}
|
||||
UserModel.get().cacheLoginUserInfo?.let {
|
||||
if (!it.isBindPaymentPwd) {
|
||||
ModifyPwdActivity.start(context, ModifyPwdActivity.PAY_PWD)
|
||||
return
|
||||
}
|
||||
}
|
||||
GiveGoldPassWordFragment.newInstance(
|
||||
childFragmentManager,
|
||||
mBinding?.etMoney?.text.toString()
|
||||
).apply {
|
||||
setListener(object : GridPasswordNoFocusView.OnPasswordChangedListener {
|
||||
override fun onTextChanged(psw: String?) {
|
||||
val password = passWordFragment?.password?.password ?: ""
|
||||
if (password.length == 6) {
|
||||
send(password)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInputFinish(psw: String?) {
|
||||
}
|
||||
})
|
||||
passWordFragment = this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码输入完成
|
||||
*/
|
||||
private fun send(password: String) {
|
||||
dialogManager.showProgressDialog(context)
|
||||
val kind = typeAdapter?.getSelect()?.type ?: 1
|
||||
val message = if (kind == 4) {
|
||||
mBinding.etText.text.trim().toString()
|
||||
} else {
|
||||
""
|
||||
}
|
||||
val validityType = if (kind == 1) {
|
||||
timeType
|
||||
} else {
|
||||
0
|
||||
}
|
||||
RedPackageModel.sendRedPackage(
|
||||
goldNum = mBinding.etMoney.text.trim().toString().toLongOrDefault(0),
|
||||
message = message,
|
||||
num = mBinding.etNum.text.trim().toString().toLongOrDefault(0),
|
||||
roomUId = AvRoomDataManager.get().mCurrentRoomInfo?.uid.toString(),
|
||||
type = 1,
|
||||
kind = kind,
|
||||
validityType = validityType,
|
||||
password = DESUtils.DESAndBase64(password)
|
||||
)
|
||||
.compose(bindToLifecycle())
|
||||
.doOnError {
|
||||
dialogManager.dismissDialog()
|
||||
SingleToastUtil.showToast(it.message)
|
||||
passWordFragment?.password?.clearPassword()
|
||||
}
|
||||
.subscribe { _ ->
|
||||
PayModel.get().getWalletInfo(AuthModel.get().currentUid).subscribe()
|
||||
dialogManager.dismissDialog()
|
||||
SingleToastUtil.showToast("發送成功")
|
||||
passWordFragment?.dismissAllowingStateLoss()
|
||||
(parentFragment as? RedPackageSendDialog2)?.dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
passWordFragment?.dismissAllowingStateLoss()
|
||||
passWordFragment = null
|
||||
}
|
||||
}
|
@@ -1,17 +1,139 @@
|
||||
package com.yizhuan.erban.avroom.redpackage.send
|
||||
|
||||
import com.chuhai.utils.ktx.addDisableFilter
|
||||
import com.chuhai.utils.ktx.setOnInputChangedListener
|
||||
import com.chuhai.utils.ktx.singleClick
|
||||
import com.chuhai.utils.ktx.toStringRes
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.erban.base.BaseBindingFragment
|
||||
import com.yizhuan.erban.databinding.RedPackagePrivateFragmentBinding
|
||||
import com.yizhuan.erban.databinding.RedPackagePublicFragmentBinding
|
||||
import com.yizhuan.erban.pay.password.GiveGoldPassWordFragment
|
||||
import com.yizhuan.erban.pay.widget.GridPasswordNoFocusView
|
||||
import com.yizhuan.erban.ui.setting.ModifyPwdActivity
|
||||
import com.yizhuan.xchat_android_core.auth.AuthModel
|
||||
import com.yizhuan.xchat_android_core.initial.InitialModel
|
||||
import com.yizhuan.xchat_android_core.initial.bean.InitInfo
|
||||
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager
|
||||
import com.yizhuan.xchat_android_core.pay.PayModel
|
||||
import com.yizhuan.xchat_android_core.redpackage.RedPackageModel
|
||||
import com.yizhuan.xchat_android_core.user.UserModel
|
||||
import com.yizhuan.xchat_android_core.utils.toIntOrDef
|
||||
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
|
||||
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
|
||||
import com.yizhuan.xchat_android_library.utils.codec.DESUtils
|
||||
import okhttp3.internal.toLongOrDefault
|
||||
|
||||
/**
|
||||
* Created by Max on 2023/10/23 12:14
|
||||
* Desc:
|
||||
* Desc:全服红包
|
||||
**/
|
||||
@ActLayoutRes(R.layout.red_package_public_fragment)
|
||||
class PublicRedPackageEditorFragment : BaseBindingFragment<RedPackagePublicFragmentBinding>() {
|
||||
|
||||
private var passWordFragment: GiveGoldPassWordFragment? = null
|
||||
|
||||
override fun initiate() {
|
||||
mBinding.etText.addDisableFilter("\n")
|
||||
mBinding.etText.setOnInputChangedListener {
|
||||
mBinding.tvTextLength.text =
|
||||
R.string.red_package_opened_count_format.toStringRes().format(this, 20)
|
||||
true
|
||||
}
|
||||
|
||||
mBinding.tvSend.singleClick {
|
||||
checkSend()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSend() {
|
||||
val initInfo = InitialModel.get().cacheInitInfo ?: InitInfo()
|
||||
val minNum = initInfo.redEnvelopeConfig.serverRedEnvelopeMinNum
|
||||
val maxNum = initInfo.redEnvelopeConfig.serverRedEnvelopeMaxNum
|
||||
val minGold = initInfo.redEnvelopeConfig.serverRedEnvelopeMinAmount
|
||||
val maxGold = initInfo.redEnvelopeConfig.serverRedEnvelopeMaxAmount
|
||||
val rate =
|
||||
if (initInfo.redEnvelopeConfig.exchangeDiamondsRate == 0.0) 0.68 else initInfo.redEnvelopeConfig.exchangeDiamondsRate
|
||||
|
||||
val redNum = mBinding?.etNum?.text.toString().toIntOrDef()
|
||||
if (redNum < minNum || redNum > maxNum) {
|
||||
SingleToastUtil.showToast("紅包數量不能小於${minNum}或大於${maxNum}!")
|
||||
return
|
||||
}
|
||||
val goldNum = mBinding?.etMoney?.text.toString().toIntOrDef()
|
||||
if (goldNum % 100 != 0) {
|
||||
SingleToastUtil.showToast("鉆石數必須為100的倍數!")
|
||||
return
|
||||
}
|
||||
if (goldNum < minGold || goldNum > maxGold) {
|
||||
SingleToastUtil.showToast("鉆石數量不能小於${minGold}或大於${maxGold}!")
|
||||
return
|
||||
}
|
||||
if (goldNum.toFloat() / redNum * rate < 0.1) {//單個手氣紅包價值不低於0.1水晶
|
||||
SingleToastUtil.showToast("單個紅包金額過低")
|
||||
return
|
||||
}
|
||||
UserModel.get().cacheLoginUserInfo?.let {
|
||||
if (!it.isBindPaymentPwd) {
|
||||
ModifyPwdActivity.start(context, ModifyPwdActivity.PAY_PWD)
|
||||
return
|
||||
}
|
||||
}
|
||||
GiveGoldPassWordFragment.newInstance(
|
||||
childFragmentManager,
|
||||
mBinding?.etMoney?.text.toString()
|
||||
).apply {
|
||||
setListener(object : GridPasswordNoFocusView.OnPasswordChangedListener {
|
||||
override fun onTextChanged(psw: String?) {
|
||||
val password = passWordFragment?.password?.password ?: ""
|
||||
if (password.length == 6) {
|
||||
send(password)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInputFinish(psw: String?) {
|
||||
}
|
||||
})
|
||||
passWordFragment = this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码输入完成
|
||||
*/
|
||||
private fun send(password: String) {
|
||||
dialogManager.showProgressDialog(context)
|
||||
var message = mBinding.etText.text.trim().toString()
|
||||
if (message.isEmpty()) {
|
||||
message = R.string.red_package_msg_def.toStringRes()
|
||||
}
|
||||
RedPackageModel.sendRedPackage(
|
||||
goldNum = mBinding.etMoney.text.trim().toString().toLongOrDefault(0),
|
||||
message = message,
|
||||
num = mBinding.etNum.text.trim().toString().toLongOrDefault(0),
|
||||
roomUId = AvRoomDataManager.get().mCurrentRoomInfo?.uid.toString(),
|
||||
type = 2,
|
||||
kind = 0,
|
||||
validityType = 0,
|
||||
password = DESUtils.DESAndBase64(password)
|
||||
)
|
||||
.compose(bindToLifecycle())
|
||||
.doOnError {
|
||||
dialogManager.dismissDialog()
|
||||
SingleToastUtil.showToast(it.message)
|
||||
passWordFragment?.password?.clearPassword()
|
||||
}
|
||||
.subscribe { _ ->
|
||||
PayModel.get().getWalletInfo(AuthModel.get().currentUid).subscribe()
|
||||
dialogManager.dismissDialog()
|
||||
SingleToastUtil.showToast("發送成功")
|
||||
passWordFragment?.dismissAllowingStateLoss()
|
||||
(parentFragment as? RedPackageSendDialog2)?.dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
passWordFragment?.dismissAllowingStateLoss()
|
||||
passWordFragment = null
|
||||
}
|
||||
}
|
@@ -4,16 +4,30 @@ package com.yizhuan.erban.avroom.redpackage.send
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.Gravity
|
||||
import android.view.WindowManager
|
||||
import com.bumptech.glide.manager.Lifecycle
|
||||
import com.chuhai.utils.ktx.singleClick
|
||||
import com.chuhai.utils.ktx.toStringRes
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.erban.avroom.redpackage.RedPackageEvent
|
||||
import com.yizhuan.erban.base.BaseDialog
|
||||
import com.yizhuan.erban.common.ViewPagerAdapter
|
||||
import com.yizhuan.erban.databinding.RedPackageSendDialogBinding
|
||||
import com.yizhuan.erban.ui.pay.ChargeActivity
|
||||
import com.yizhuan.erban.ui.webview.CommonWebViewActivity
|
||||
import com.yizhuan.erban.ui.webview.DialogWebViewActivity
|
||||
import com.yizhuan.erban.ui.widget.magicindicator.ViewPagerHelper
|
||||
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator
|
||||
import com.yizhuan.xchat_android_core.Constants
|
||||
import com.yizhuan.xchat_android_core.UriProvider
|
||||
import com.yizhuan.xchat_android_core.initial.InitialModel
|
||||
import com.yizhuan.xchat_android_core.pay.PayModel
|
||||
import com.yizhuan.xchat_android_core.pay.event.UpdateWalletInfoEvent
|
||||
import com.yizhuan.xchat_android_core.redpackage.*
|
||||
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
|
||||
import com.yizhuan.xchat_android_library.common.util.DeviceUtil
|
||||
import com.yizhuan.xchat_android_library.utils.AppMetaDataUtil
|
||||
import com.yizhuan.xchat_android_library.utils.ResUtil
|
||||
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
@@ -35,7 +49,24 @@ class RedPackageSendDialog2 : BaseDialog<RedPackageSendDialogBinding>() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun init() {
|
||||
EventBus.getDefault().register(this)
|
||||
val tabTitles = arrayListOf(R.string.red_package_room.toStringRes(), R.string.red_package_public.toStringRes())
|
||||
if (InitialModel.get().cacheInitInfo == null) {
|
||||
InitialModel.get().init(true)
|
||||
SingleToastUtil.showToast(ResUtil.getString(R.string.avroom_redpackage_redpackagesenddialog_01))
|
||||
dismissAllowingStateLoss()
|
||||
return
|
||||
}
|
||||
initView()
|
||||
initEvent()
|
||||
PayModel.get().currentWalletInfo?.let {
|
||||
binding.tvBalance.text = it.diamondNum.toLong().toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
val tabTitles = arrayListOf(
|
||||
R.string.red_package_room.toStringRes(),
|
||||
R.string.red_package_public.toStringRes()
|
||||
)
|
||||
val topMagicIndicatorAdapter = TabIndicatorAdapter(context, tabTitles)
|
||||
topMagicIndicatorAdapter.setOnItemSelectListener {
|
||||
binding.viewPager.currentItem = it
|
||||
@@ -54,11 +85,42 @@ class RedPackageSendDialog2 : BaseDialog<RedPackageSendDialogBinding>() {
|
||||
ViewPagerHelper.bind(binding.tabLayout, binding.viewPager)
|
||||
}
|
||||
|
||||
private fun initEvent() {
|
||||
binding.ivHelp.singleClick {
|
||||
DialogWebViewActivity.start(
|
||||
context,
|
||||
UriProvider.getRedPacketRule()
|
||||
)
|
||||
}
|
||||
|
||||
binding.tvBalance.singleClick {
|
||||
if (AppMetaDataUtil.getChannelID() == Constants.GOOGLE) {
|
||||
ChargeActivity.start(context)
|
||||
} else {
|
||||
CommonWebViewActivity.start(
|
||||
context, UriProvider.getOfficialPay(
|
||||
4,
|
||||
DeviceUtil.getDeviceId(context)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
EventBus.getDefault().unregister(this)
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onWalletInfoUpdate(event: UpdateWalletInfoEvent?) {
|
||||
if (!isViewLoaded) {
|
||||
return
|
||||
}
|
||||
binding.tvBalance.text = PayModel.get().currentWalletInfo?.diamondNum?.toString()
|
||||
?: "0"
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun handleRedPackageDialog(event: RedPackageEvent?) {
|
||||
dismissAllowingStateLoss()
|
||||
|
@@ -19,7 +19,12 @@ class RedPackageTypeItemAdapter(list: List<ItemData>) :
|
||||
private var selectPosition = -1
|
||||
|
||||
@Keep
|
||||
data class ItemData(val type: String, val name: Int, val tips: Int)
|
||||
data class ItemData(
|
||||
/**
|
||||
* 红包种类 0 旧版本 1 无门槛红包 2 关注红包 3 分享红包 4 弹幕红包
|
||||
*/
|
||||
val type: Int, val name: Int, val tips: Int
|
||||
)
|
||||
|
||||
override fun convert(helper: BaseViewHolder, item: ItemData) {
|
||||
helper.setText(R.id.tv_name, item.name)
|
||||
|
@@ -14,6 +14,7 @@ import java.lang.reflect.ParameterizedType
|
||||
|
||||
abstract class BaseDialog<T : ViewBinding> : RxDialogFragment() {
|
||||
|
||||
val isViewLoaded: Boolean get() = _binding != null
|
||||
private var _binding: T? = null
|
||||
private var onDismissListener: (() -> Unit)? = null
|
||||
val binding get() = _binding!!
|
||||
|
@@ -80,7 +80,6 @@ class SettingActivity : BaseViewBindingActivity<ActivitySettingBinding>(), View.
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
binding.titleBar.setOnTitleClickListener {
|
||||
// RedPackageSendDialog2().show(this)
|
||||
RedPackageOpenDialog2().show(this)
|
||||
}
|
||||
}
|
||||
|
@@ -189,6 +189,7 @@
|
||||
android:gravity="center"
|
||||
android:hint="@string/red_package_msg_hint"
|
||||
android:maxLength="10"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/color_322F4D"
|
||||
android:textColorHint="@color/color_B3B3C3"
|
||||
android:textSize="16sp"
|
||||
|
@@ -130,13 +130,14 @@
|
||||
android:maxLength="20"
|
||||
android:paddingHorizontal="10dp"
|
||||
android:paddingVertical="10dp"
|
||||
android:text="@string/red_package_msg_def"
|
||||
android:hint="@string/red_package_msg_def"
|
||||
android:textColorHint="@color/color_B3B3C3"
|
||||
android:textColor="@color/color_322F4D"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/et_num" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_text_langth"
|
||||
android:id="@+id/tv_text_length"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
|
@@ -18,8 +18,6 @@
|
||||
android:id="@+id/iv_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/red_package_send_bg"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
@@ -34,9 +32,10 @@
|
||||
app:layout_constraintTop_toTopOf="@id/iv_top" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_help"
|
||||
android:layout_width="44dp"
|
||||
android:layout_height="44dp"
|
||||
android:layout_marginTop="71dp"
|
||||
android:layout_marginTop="64dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/red_package_ic_help"
|
||||
@@ -47,7 +46,7 @@
|
||||
android:id="@+id/tv_balance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/red_package_bg_balance"
|
||||
android:gravity="center"
|
||||
android:paddingStart="25dp"
|
||||
|
@@ -5170,4 +5170,5 @@
|
||||
<string name="red_package_opened_money_tips">已存入錢包,請到我的收益確認</string>
|
||||
<string name="red_package_opened_count_format">已領取%s/%s個</string>
|
||||
<string name="red_package_widget_get">抢红包</string>
|
||||
<string name="red_package_msg_empty_tips">请输入弹幕内容</string>
|
||||
</resources>
|
@@ -0,0 +1,57 @@
|
||||
package com.yizhuan.xchat_android_core.interceptor
|
||||
|
||||
import com.chuhai.utils.AppUtils
|
||||
import com.chuhai.utils.ServiceTime
|
||||
import com.yizhuan.xchat_android_core.utils.LogUtils
|
||||
import com.yizhuan.xchat_android_library.utils.NetworkUtils
|
||||
import okhttp3.Headers
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
|
||||
/**
|
||||
* Created by Max on 2023/10/25 14:17 AM
|
||||
* Desc:服务器时间同步器
|
||||
*/
|
||||
class TimeSyncInterceptor : Interceptor {
|
||||
|
||||
private var minResponseTime = Long.MAX_VALUE
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
val startTime = System.nanoTime()
|
||||
val proceed = chain.proceed(request)
|
||||
val lastTime = System.nanoTime() - startTime
|
||||
val headers = proceed.headers
|
||||
calibration(lastTime, headers)
|
||||
return proceed
|
||||
}
|
||||
|
||||
private fun calibration(responseTime: Long, headers: Headers?) {
|
||||
if (headers == null) {
|
||||
return
|
||||
}
|
||||
|
||||
//如果这一次的请求响应时间小于上一次,则更新本地维护的时间
|
||||
if (responseTime >= minResponseTime) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 网络无法使用时,不能同步时间
|
||||
if (!NetworkUtils.isNetworkAvailable(AppUtils.getApp())) {
|
||||
return
|
||||
}
|
||||
// 网络响应头包含Date字段(世界时间)
|
||||
// 利用Interceptor记录每次请求响应时间,如果本次网络操作的时间小于上一次网络操作的时间,则获取Date字段,转换时区后更新本地
|
||||
val date = headers.getDate("Date")
|
||||
LogUtils.d("TimeSyncInterceptor date:$date time:${date?.time}")
|
||||
date?.let {
|
||||
//客户端请求过程一般大于比收到响应时间耗时,所以没有简单的除2 加上去,而是直接用该时间
|
||||
ServiceTime.refreshServiceTime(it.time)
|
||||
minResponseTime = responseTime
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
package com.yizhuan.xchat_android_core.redpackage
|
||||
|
||||
|
||||
|
||||
import com.yizhuan.xchat_android_core.bean.response.ServiceResult
|
||||
import com.yizhuan.xchat_android_core.utils.net.handleBeanData
|
||||
import com.yizhuan.xchat_android_core.utils.net.handleStringData
|
||||
@@ -20,32 +19,53 @@ object RedPackageModel {
|
||||
api = RxNet.create(Api::class.java)
|
||||
}
|
||||
|
||||
fun sendRedPackage(goldNum: String, message: String, num: String, roomUId: String, type: Int, password: String): Single<String> {
|
||||
return api.sendRedPackage(goldNum, message, num, roomUId, type, password)
|
||||
.io2main()
|
||||
.handleStringData()
|
||||
fun sendRedPackage(
|
||||
goldNum: Long, message: String, num: Long, roomUId: String, type: Int,
|
||||
kind: Int, validityType: Int, password: String
|
||||
): Single<String> {
|
||||
return api.sendRedPackage(
|
||||
goldNum,
|
||||
message,
|
||||
num,
|
||||
roomUId,
|
||||
type,
|
||||
kind,
|
||||
validityType,
|
||||
password
|
||||
)
|
||||
.io2main()
|
||||
.handleStringData()
|
||||
}
|
||||
|
||||
|
||||
fun openRedPackage(redEnvelopeId: String): Single<RedPackageInfo> {
|
||||
return api.openRedPackage(redEnvelopeId)
|
||||
.io2main()
|
||||
.handleBeanData()
|
||||
.io2main()
|
||||
.handleBeanData()
|
||||
}
|
||||
|
||||
fun getRedPackage(uid: Long): Observable<RedPackageNotifyInfo> {
|
||||
return api.getRedPackage(uid)
|
||||
.io2main()
|
||||
.handleBeanData()
|
||||
.toObservable()
|
||||
.flatMap { Observable.fromIterable(it) }
|
||||
.map { RedPackageNotifyInfo(it.id, it.type, it.message, it.userVO?.avatar?:"", it.userVO?.nick?:"", it.roomUId, "") }
|
||||
.io2main()
|
||||
.handleBeanData()
|
||||
.toObservable()
|
||||
.flatMap { Observable.fromIterable(it) }
|
||||
.map {
|
||||
RedPackageNotifyInfo(
|
||||
it.id,
|
||||
it.type,
|
||||
it.message,
|
||||
it.userVO?.avatar ?: "",
|
||||
it.userVO?.nick ?: "",
|
||||
it.roomUId,
|
||||
""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setRedPackageSwitch(roomUid: Long):Single<Boolean> {
|
||||
fun setRedPackageSwitch(roomUid: Long): Single<Boolean> {
|
||||
return api.setRedPackageSwitch(roomUid)
|
||||
.io2main()
|
||||
.handleBeanData()
|
||||
.io2main()
|
||||
.handleBeanData()
|
||||
}
|
||||
|
||||
private interface Api {
|
||||
@@ -57,12 +77,16 @@ object RedPackageModel {
|
||||
*/
|
||||
@FormUrlEncoded
|
||||
@POST("/red-envelope")
|
||||
fun sendRedPackage(@Field("goldNum") goldNum: String,
|
||||
@Field("message") message: String,
|
||||
@Field("num") num: String,
|
||||
@Field("roomUId") roomUId: String,
|
||||
@Field("type") type: Int,
|
||||
@Field("password") password: String): Single<ServiceResult<String>>
|
||||
fun sendRedPackage(
|
||||
@Field("goldNum") goldNum: Long,
|
||||
@Field("message") message: String,
|
||||
@Field("num") num: Long,
|
||||
@Field("roomUId") roomUId: String,
|
||||
@Field("type") type: Int,
|
||||
@Field("kind") kind: Int,
|
||||
@Field("validityType") validityType: Int,
|
||||
@Field("password") password: String
|
||||
): Single<ServiceResult<String>>
|
||||
|
||||
/**
|
||||
* 开红包
|
||||
|
@@ -0,0 +1,25 @@
|
||||
package com.chuhai.utils
|
||||
|
||||
import android.os.SystemClock
|
||||
|
||||
/**
|
||||
* Created by Max on 3/4/21 5:00 PM
|
||||
* Desc:服务器时间
|
||||
*/
|
||||
object ServiceTime {
|
||||
|
||||
// 服务器时间与系统开机时间的时差
|
||||
private var serviceTimeDiff: Long? = null
|
||||
|
||||
val time
|
||||
get() = if (serviceTimeDiff == null) System.currentTimeMillis()
|
||||
else SystemClock.elapsedRealtime() + serviceTimeDiff!!
|
||||
|
||||
/**
|
||||
* 刷新服务器时间
|
||||
*/
|
||||
fun refreshServiceTime(time: Long) {
|
||||
//serviceTimeDiff = 服务器时间 - 此刻系统启动时间
|
||||
serviceTimeDiff = time - SystemClock.elapsedRealtime()
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package com.chuhai.utils
|
||||
|
||||
import android.graphics.Outline
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Created by Max on 2/25/21 1:50 PM
|
||||
* Desc:
|
||||
*/
|
||||
class ShapeViewOutlineProvider {
|
||||
|
||||
/**
|
||||
* Created by Max on 2/25/21 1:48 PM
|
||||
* Desc:圆角
|
||||
*/
|
||||
class Round(var corner: Float) : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, outline: Outline) {
|
||||
outline.setRoundRect(
|
||||
0,
|
||||
0,
|
||||
view.width,
|
||||
view.height,
|
||||
corner
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by Max on 2/25/21 1:48 PM
|
||||
* Desc:圆形
|
||||
*/
|
||||
class Circle : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, outline: Outline) {
|
||||
val min = min(view.width, view.height)
|
||||
val left = (view.width - min) / 2
|
||||
val top = (view.height - min) / 2
|
||||
outline.setOval(left, top, min, min)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
package com.chuhai.utils.ktx
|
||||
|
||||
import android.text.Editable
|
||||
import android.text.InputFilter
|
||||
import android.text.InputFilter.LengthFilter
|
||||
import android.text.Spanned
|
||||
import android.text.TextWatcher
|
||||
import android.text.method.HideReturnsTransformationMethod
|
||||
import android.text.method.PasswordTransformationMethod
|
||||
import android.widget.EditText
|
||||
|
||||
|
||||
/**
|
||||
* 设置editText输入监听
|
||||
* @param onChanged 改变事件
|
||||
* @return 是否接受此次文本的改变
|
||||
*/
|
||||
inline fun EditText.setOnInputChangedListener(
|
||||
/**
|
||||
* @param Int:当前长度
|
||||
* @return 是否接受此次文本的改变
|
||||
*/
|
||||
crossinline onChanged: (Int).() -> Boolean
|
||||
) {
|
||||
this.addTextChangedListener(object : TextWatcher {
|
||||
|
||||
var flag = false
|
||||
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
if (flag) {
|
||||
return
|
||||
}
|
||||
if (!onChanged(p0?.length ?: 0)) {
|
||||
flag = true
|
||||
this@setOnInputChangedListener.setText(
|
||||
this@setOnInputChangedListener.getTag(
|
||||
1982329101
|
||||
) as? String
|
||||
)
|
||||
this@setOnInputChangedListener.setSelection(this@setOnInputChangedListener.length())
|
||||
flag = false
|
||||
} else {
|
||||
flag = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
this@setOnInputChangedListener.setTag(1982329101, p0?.toString())
|
||||
}
|
||||
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换密码可见度
|
||||
*/
|
||||
fun EditText.switchPasswordVisibility(visibility: Boolean) {
|
||||
transformationMethod =
|
||||
if (!visibility) HideReturnsTransformationMethod.getInstance() else PasswordTransformationMethod.getInstance()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置输入功能是否启用(不启用就相当于TextView)
|
||||
*/
|
||||
fun EditText.setInputEnabled(isEnabled: Boolean) {
|
||||
if (isEnabled) {
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
isClickable = true
|
||||
} else {
|
||||
isFocusable = false
|
||||
isFocusableInTouchMode = false
|
||||
isClickable = false
|
||||
keyListener = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加输入长度限制过滤器
|
||||
*/
|
||||
fun EditText.addLengthFilter(maxLength: Int) {
|
||||
val newFilters = filters.copyOf(filters.size + 1)
|
||||
newFilters[newFilters.size - 1] = LengthFilter(maxLength)
|
||||
filters = newFilters
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加禁用文本过滤器
|
||||
* @param disableText 不允许输入该文本
|
||||
*/
|
||||
fun EditText.addDisableFilter(vararg disableText: CharSequence) {
|
||||
val newFilters = filters.copyOf(filters.size + 1)
|
||||
newFilters[newFilters.size - 1] = InputFilter { source, p1, p2, p3, p4, p5 ->
|
||||
disableText.forEach {
|
||||
if (source.equals(it)) {
|
||||
return@InputFilter ""
|
||||
}
|
||||
}
|
||||
return@InputFilter null
|
||||
}
|
||||
filters = newFilters
|
||||
}
|
192
library/src/module_utils/java/com/chuhai/utils/ktx/ViewKtx.kt
Normal file
192
library/src/module_utils/java/com/chuhai/utils/ktx/ViewKtx.kt
Normal file
@@ -0,0 +1,192 @@
|
||||
package com.chuhai.utils.ktx
|
||||
|
||||
import android.graphics.*
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Checkable
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.ScrollingView
|
||||
import com.chuhai.utils.ShapeViewOutlineProvider
|
||||
import com.chuhai.utils.UiUtils
|
||||
|
||||
|
||||
/**
|
||||
* 是否右-左布局
|
||||
*/
|
||||
fun View.isRtl(): Boolean {
|
||||
return UiUtils.isRtl(this)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 展示or隐藏
|
||||
*/
|
||||
fun View.visibleOrGone(isShow: Boolean) {
|
||||
visibility = if (isShow) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示or隐藏
|
||||
*/
|
||||
inline fun View.visibleOrGone(show: View.() -> Boolean = { true }) {
|
||||
visibility = if (show(this)) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示or不可见
|
||||
*/
|
||||
inline fun View.visibleOrInvisible(show: View.() -> Boolean = { true }) {
|
||||
visibility = if (show(this)) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击事件
|
||||
*/
|
||||
inline fun <T : View> T.singleClick(time: Long = 800, crossinline block: (T) -> Unit) {
|
||||
setOnClickListener(object : View.OnClickListener {
|
||||
private var lastClickTime: Long = 0L
|
||||
override fun onClick(v: View?) {
|
||||
val currentTimeMillis = SystemClock.elapsedRealtime()
|
||||
if (currentTimeMillis - lastClickTime > time || this is Checkable) {
|
||||
lastClickTime = currentTimeMillis
|
||||
block(this@singleClick)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击事件
|
||||
*/
|
||||
fun <T : View> T.singleClick(onClickListener: View.OnClickListener, time: Long = 800) {
|
||||
setOnClickListener(object : View.OnClickListener {
|
||||
private var lastClickTime: Long = 0L
|
||||
override fun onClick(v: View?) {
|
||||
val currentTimeMillis = SystemClock.elapsedRealtime()
|
||||
if (currentTimeMillis - lastClickTime > time || this is Checkable) {
|
||||
lastClickTime = currentTimeMillis
|
||||
onClickListener.onClick(v)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置View圆角矩形
|
||||
*/
|
||||
fun <T : View> T.roundCorner(corner: Int) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (outlineProvider == null || outlineProvider !is ShapeViewOutlineProvider.Round) {
|
||||
outlineProvider = ShapeViewOutlineProvider.Round(corner.toFloat())
|
||||
} else if (outlineProvider != null && outlineProvider is ShapeViewOutlineProvider.Round) {
|
||||
(outlineProvider as ShapeViewOutlineProvider.Round).corner = corner.toFloat()
|
||||
}
|
||||
clipToOutline = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置View为圆形
|
||||
*/
|
||||
fun <T : View> T.circle() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (outlineProvider == null || outlineProvider !is ShapeViewOutlineProvider.Circle) {
|
||||
outlineProvider = ShapeViewOutlineProvider.Circle()
|
||||
}
|
||||
clipToOutline = true
|
||||
}
|
||||
}
|
||||
|
||||
fun View.getBitmap(): Bitmap {
|
||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.translate(scrollX.toFloat(), scrollY.toFloat())
|
||||
draw(canvas)
|
||||
return bitmap
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置边距
|
||||
*/
|
||||
fun View?.setMargin(start: Int? = null, top: Int? = null, end: Int? = null, bottom: Int? = null) {
|
||||
(this?.layoutParams as? ViewGroup.MarginLayoutParams)?.apply {
|
||||
start?.let {
|
||||
this.marginStart = start
|
||||
}
|
||||
top?.let {
|
||||
this.topMargin = top
|
||||
}
|
||||
end?.let {
|
||||
this.marginEnd = end
|
||||
}
|
||||
bottom?.let {
|
||||
this.bottomMargin = bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置内边距
|
||||
*/
|
||||
fun View?.setPadding2(start: Int? = null, top: Int? = null, end: Int? = null, bottom: Int? = null) {
|
||||
if (this == null) return
|
||||
this.setPadding(
|
||||
start ?: paddingStart, top ?: paddingTop, end ?: paddingEnd, bottom ?: paddingBottom
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 描边宽度
|
||||
*/
|
||||
fun TextView.strokeWidth(width: Float) {
|
||||
this.paint?.style = Paint.Style.FILL_AND_STROKE
|
||||
this.paint?.strokeWidth = width
|
||||
this.invalidate()
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟点击并取消
|
||||
*/
|
||||
fun ScrollingView.simulateClickAndCancel() {
|
||||
val view = this as? View ?: return
|
||||
val downEvent = MotionEvent.obtain(
|
||||
System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_DOWN, (view.right - view.left) / 2f, (view.bottom - view.top) / 2f, 0
|
||||
)
|
||||
view.dispatchTouchEvent(downEvent)
|
||||
val cancelEvent = MotionEvent.obtain(
|
||||
System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_CANCEL, (view.right - view.left) / 2f, (view.bottom - view.top) / 2f, 0
|
||||
)
|
||||
view.dispatchTouchEvent(cancelEvent)
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用灰色滤镜
|
||||
*/
|
||||
fun View.applyGrayFilter(isGray: Boolean) {
|
||||
try {
|
||||
val paint = Paint()
|
||||
val colorMatrix = ColorMatrix()
|
||||
colorMatrix.setSaturation(if (isGray) 0f else 1f)
|
||||
paint.colorFilter = ColorMatrixColorFilter(colorMatrix)
|
||||
setLayerType(View.LAYER_TYPE_HARDWARE, paint)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user