package com.dlc.eboard.ui import android.app.AlertDialog import android.content.ComponentName import android.content.Intent import android.content.ServiceConnection import android.os.Bundle import android.os.Handler import android.os.IBinder import android.os.Looper import android.view.KeyEvent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.ImageView import android.widget.TextView import androidx.core.content.ContextCompat import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView import com.blankj.utilcode.util.AppUtils import com.bumptech.glide.Glide import com.chad.library.adapter.base.BaseQuickAdapter import com.chad.library.adapter.base.viewholder.BaseViewHolder import com.dlc.eboard.BuildConfig import com.dlc.eboard.LabApp import com.dlc.eboard.R import com.dlc.eboard.common.AuthTypeConfig import com.dlc.eboard.common.CommonUtils import com.dlc.eboard.common.SensorEnum import com.dlc.eboard.databinding.ActivityHomeBinding import com.dlc.eboard.databinding.ItemHomePersonFlipperBinding import com.dlc.eboard.event.OnlineUserEvent import com.dlc.eboard.finger.FingerHelper import com.dlc.eboard.finger.OnFingerListener import com.dlc.eboard.mqtt.AudioService import com.dlc.eboard.mqtt.MqttService import com.dlc.eboard.mqtt.entity.BulletinBoardEntity import com.dlc.eboard.mqtt.event.* import com.dlc.eboard.serial.OnSerialScanListener import com.dlc.eboard.serial.SerialPortHelper import com.dlc.eboard.ui.auth.* import com.dlc.eboard.ui.common.BaseCountDownActivity import com.dlc.eboard.ui.dialog.WaringDialog import com.dlc.eboard.ui.home.AccessPersonFragment import com.dlc.eboard.ui.home.DutyPersonFragment import com.dlc.eboard.ui.home.HomeFragmentCallback import com.dlc.eboard.ui.home.LabBasicFragment import com.dlc.eboard.ui.lib.LabDescActivity import com.dlc.eboard.ui.settings.PasswordDialog import com.dlc.eboard.ui.settings.SettingsActivity import com.dlc.eboard.ui.widget.LooperLayoutManager import com.dlc.eboard.ui.widget.ItemBoardView import com.dlc.eboard.ui.widget.NavViewCompat import com.dlc.eboard.ui.widget.ITitleBar import com.rc.core.log.RcLog import com.rc.core.ui.widget.decoration.NoLastLineItemDecoration import com.rc.core.util.ApkUpdater import com.rc.core.util.DeviceUtils import com.rc.core.util.FastClickDelegate import com.rc.httpcore.client.ApiRepository import com.rc.httpcore.vo.response.* import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import org.json.JSONObject /** * 主页 * * @author ReiChin_ */ class HomeActivity : BaseCountDownActivity(), HomeFragmentCallback { companion object { private const val SENSOR_SPLASH_TIME = 3000L // 传感器面板1.5s自动滚动 } override val mTitleBar: ITitleBar by lazy { viewBinding.titleBar } override val mNavView: NavViewCompat? = null private val mBulletinBoardAdapter = HomeBoardAdapter() private var handler: Handler = Handler(Looper.getMainLooper()) private lateinit var runnable: Runnable override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) bindService(Intent(this, MqttService::class.java), mConnection, BIND_AUTO_CREATE) // startService(Intent(this, HeartService::class.java)) bindService(Intent(this, AudioService::class.java), mAudioConnection, BIND_AUTO_CREATE) mSerialPortHelper.bindService() mFingerHelper = generateFingerHelper() lifecycle.addObserver(mFingerHelper) // 创建定时任务 runnable = object : Runnable { override fun run() { // 每隔一个小时执行一次操作 // 这里可以添加你需要执行的代码 listenIn() // 重新启动定时任务 handler.postDelayed(this, 30000) // 30000 毫秒为一小时 } } // 第一次启动定时任务 handler.post(runnable) // queryLabConfig() } private fun queryLabConfig() { RcLog.info("============CommonUtils.getAndroidId()" + CommonUtils.getAndroidId()) val disposable = ApiRepository.queryLabConfig(CommonUtils.getAndroidId()) .subscribe({ data -> RcLog.info("===========" + data.authType) LabApp.sLabConfig = data }, { throwable -> // dismissLoading() throwable.printStackTrace() showNetError(throwable) }) addDisposable(disposable) } fun listenIn() { val disposable = ApiRepository.heartbeat(CommonUtils.getAndroidId()) .subscribe({ }, { }) addDisposable(disposable) } override fun onDestroy() { unbindService(mConnection) // stopService(Intent(this, HeartService::class.java)) unbindService(mAudioConnection) mSerialPortHelper.unbindService() lifecycle.removeObserver(mFingerHelper) viewBinding.bulletinBoardView.stopAuto() handler.removeCallbacks(runnable) handler.removeCallbacksAndMessages(null) super.onDestroy() AppUtils.exitApp() } private val mConnection: ServiceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName, service: IBinder) { LabApp.sLabConfig?.let { config -> service as MqttService.MqttBinder service.initMqtt(config.labId) } } override fun onServiceDisconnected(name: ComponentName) { } } private var mAudioBinder: AudioService.AudioBinder? = null private val mAudioConnection: ServiceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName, service: IBinder) { mAudioBinder = service as AudioService.AudioBinder } override fun onServiceDisconnected(name: ComponentName) { } } override fun createViewBinding() = ActivityHomeBinding.inflate(layoutInflater) override fun initViews(savedInstanceState: Bundle?) { val transaction = supportFragmentManager.beginTransaction() transaction.add( R.id.container, LabBasicFragment.newInstance(), LabBasicFragment.TAG ) transaction.commitAllowingStateLoss() viewBinding.bulletinBoardView.layoutManager = LooperLayoutManager(RecyclerView.HORIZONTAL) val decor = NoLastLineItemDecoration(this, DividerItemDecoration.HORIZONTAL) decor.setDrawable(ContextCompat.getDrawable(this, R.drawable.shape_item_divider_middle)!!) viewBinding.bulletinBoardView.addItemDecoration(decor) viewBinding.bulletinBoardView.adapter = mBulletinBoardAdapter } override fun initListener() { viewBinding.titleBar.setTitleListener(this) viewBinding.titleBar.setOnLongClickListener { PasswordDialog(this) { val intent = Intent(this, SettingsActivity::class.java) startActivity(intent) }.show() true } // 值班人员 viewBinding.dutyExpand.setOnClickListener(FastClickDelegate { if (null == LabApp.sLabConfig) return@FastClickDelegate val fragment = supportFragmentManager.findFragmentByTag(DutyPersonFragment.TAG) as? DutyPersonFragment ?: DutyPersonFragment() fragment.arguments = Bundle().apply { putString("labId", LabApp.sLabConfig!!.labId) } supportFragmentManager.beginTransaction().apply { // setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right) replace(R.id.container, fragment, DutyPersonFragment.TAG) addToBackStack(null) commit() } switchPersonPanel(View.GONE) }) // 实验人员 viewBinding.experimentExpand.setOnClickListener(FastClickDelegate { if (null == LabApp.sLabConfig) return@FastClickDelegate val fragment = supportFragmentManager.findFragmentByTag(AccessPersonFragment.TAG_EXPERIMENT) as? AccessPersonFragment ?: AccessPersonFragment() fragment.arguments = Bundle().apply { putInt("type", AccessPersonFragment.TYPE_EXPERIMENT) putString("labId", LabApp.sLabConfig!!.labId) } supportFragmentManager.beginTransaction().apply { // setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right) replace(R.id.container, fragment, AccessPersonFragment.TAG_EXPERIMENT) addToBackStack(null) commit() } switchPersonPanel(View.GONE) }) // 准入人员 viewBinding.accessExpand.setOnClickListener(FastClickDelegate { if (null == LabApp.sLabConfig) return@FastClickDelegate val fragment = supportFragmentManager.findFragmentByTag(AccessPersonFragment.TAG_ACCESS) as? AccessPersonFragment ?: AccessPersonFragment() fragment.arguments = Bundle().apply { putInt("type", AccessPersonFragment.TYPE_ACCESS) putString("labId", LabApp.sLabConfig!!.labId) } supportFragmentManager.beginTransaction().apply { // setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right) // setCustomAnimations(R.anim.from_right, R.anim.out_right) replace(R.id.container, fragment, AccessPersonFragment.TAG_ACCESS) addToBackStack(null) commit() } switchPersonPanel(View.GONE) }) // 实验室简介 viewBinding.labDesc.setOnClickListener(FastClickDelegate { startActivity(Intent(this, LabDescActivity::class.java)) }) RcLog.info("==================LabApp.sLabConfig?.authType:" + LabApp.sLabConfig?.authType) // 身份验证 viewBinding.accessVerify.setOnClickListener(FastClickDelegate { RcLog.info("==================LabApp.sLabConfig?.authType:" + LabApp.sLabConfig?.authType) val authType = LabApp.sLabConfig?.authType ?: return@FastClickDelegate RcLog.info("==================authType:$authType") when (authType) { "1" -> { Intent(this, FingerAuthActivity::class.java) } "2" -> { Intent(this, FourChoiceAuthActivity::class.java) } "3" -> { Intent(this, TwoChoiceAuthActivity::class.java) } "4", "5", "6" -> { Intent(this, DualAuthActivity::class.java) } else -> { null } }?.let { startActivity(it) } }) } override fun initData() { if (null == LabApp.sLabConfig) { showToast("暂无实验室信息,即将重新获取") CommonUtils.restartApp(this) return } viewBinding.titleBar.setTitleInfoFromSp() queryBulletinBoard() queryPerson() queryNoticeMsgList() } private fun queryNoticeMsgList() { val disposable = ApiRepository.newMsgGroup(LabApp.sLabConfig!!.labId) .subscribe({ response -> LabApp.sNoticeList = response viewBinding.titleBar.updateNotice(response) }, { throwable -> throwable.printStackTrace() showNetError(throwable) }) addDisposable(disposable) } private var mHomeRightResp: HomeRightResp? = null private fun queryPerson() { val disposable = ApiRepository.homeRightInfo(LabApp.sLabConfig!!.labId) .subscribe({ response -> dismissLoading() mHomeRightResp = response dispatchLabPerson(response) }, { throwable -> dismissLoading() mHomeRightResp = null showNetError(throwable) throwable.printStackTrace() }) addDisposable(disposable) } private fun dispatchLabPerson(data: HomeRightResp) { // 值班人员 val dutyAdapter = PersonFlipperAdapter(1, data.dutyUser) viewBinding.dutyPerson.adapter = dutyAdapter viewBinding.dutyPerson.flipInterval = 3000 viewBinding.dutyPerson.setInAnimation(this, R.animator.anim_in) viewBinding.dutyPerson.setOutAnimation(this, R.animator.anim_out) if (!data.dutyUser.isNullOrEmpty()) { viewBinding.dutyPerson.startFlipping() } // 实验人员 val experimentAdapter = ExperimentPersonAdapter() viewBinding.experimentPerson.layoutManager = LooperLayoutManager(RecyclerView.VERTICAL) viewBinding.experimentPerson.adapter = experimentAdapter experimentAdapter.setNewInstance(data.tentativeUser) if (!data.tentativeUser.isNullOrEmpty()) { viewBinding.experimentPerson.initTimer(4, data.tentativeUser.size) viewBinding.experimentPerson.startAuto(SENSOR_SPLASH_TIME) } else { experimentAdapter.setEmptyView(R.layout.view_list_empty) } // 准入人员 val accessAdapter = PersonFlipperAdapter(2, data.securityUser) viewBinding.accessPerson.adapter = accessAdapter viewBinding.accessPerson.flipInterval = 3000 viewBinding.accessPerson.setInAnimation(this, R.animator.anim_in) viewBinding.accessPerson.setOutAnimation(this, R.animator.anim_out) if (!data.securityUser.isNullOrEmpty()) { viewBinding.accessPerson.startFlipping() } } private fun queryBulletinBoard() { showLoading("加载中...") val disposable = ApiRepository.functionList(LabApp.sLabConfig!!.labId) .subscribe({ data -> dismissLoading() if (data.isNotEmpty()) { mBulletinBoardAdapter.setNewInstance(data.toMutableList()) viewBinding.bulletinBoardView.initTimer(4, data.size) viewBinding.bulletinBoardView.startAuto(SENSOR_SPLASH_TIME) if (data.isNullOrEmpty()) { mBulletinBoardAdapter.setEmptyView(R.layout.view_list_empty) } queryWarning() } }, { throwable -> dismissLoading() throwable.printStackTrace() showNetError(throwable) mBulletinBoardAdapter.setEmptyView(R.layout.view_list_empty) }) addDisposable(disposable) } private fun queryWarning() { val disposable = ApiRepository.warnList(LabApp.sLabConfig!!.labId) .subscribe({ data -> mBulletinBoardAdapter.updateWaringValue(data) }, { throwable -> throwable.printStackTrace() showNetError(throwable) }) addDisposable(disposable) } private fun switchPersonPanel(visibility: Int) { viewBinding.dutyExpandGroup.visibility = visibility viewBinding.experimentExpandGroup.visibility = visibility viewBinding.accessExpandGroup.visibility = visibility } override fun closePersonPanel() { switchPersonPanel(View.VISIBLE) } override fun onBackPressed() { if (supportFragmentManager.backStackEntryCount >= 1) { supportFragmentManager.popBackStack() closePersonPanel() } else { super.onBackPressed() } } override fun onStop() { backCountDownFinish() super.onStop() } override fun enabledBackCountDown() = true override fun backCountDownFinish() { // 显示LabBasicFragment if (supportFragmentManager.backStackEntryCount >= 1) { supportFragmentManager.popBackStack() closePersonPanel() } } private fun generateFingerHelper(): FingerHelper { return FingerHelper(object : OnFingerListener { override fun showToast(message: String) { if (isFinishing || !mFingerEnabled) return if ("设备忙" == message) { viewBinding.titleBar.postDelayed({ if (!isFinishing && mFingerEnabled) mFingerHelper.verify() }, 1000) } else { this.showToast(message) } } override fun onMatchSuccess(userVo: UserFingerVo): Boolean { if (isFinishing || !mFingerEnabled) return false onAuthSuccess(AuthType.FINGER, userVo) return true } override fun onMatchFailure(message: String) { if (isFinishing || !mFingerEnabled) return showMatchErrDialog(message) } override fun loopMatch() { if (isFinishing || !mFingerEnabled) return mFingerHelper.verify() } }) } private lateinit var mFingerHelper: FingerHelper private var mFingerEnabled = false private fun showMatchErrDialog(message: String) { AlertDialog.Builder(this) .setTitle("提示") .setMessage(message) .setCancelable(false) .setPositiveButton("重新验证") { _, _ -> mFingerHelper.verify() }.show() } override fun onResume() { // 刷卡+门禁 mSerialPortHelper.onResume() // 5s后开始验证指纹 viewBinding.titleBar.postDelayed({ mFingerHelper.lazyVerify() }, 1000) mFingerEnabled = true super.onResume() } override fun onPause() { // 刷卡+门禁 mSerialPortHelper.onPause() // 指纹 mFingerEnabled = false super.onPause() } override fun dispatchKeyEvent(event: KeyEvent?): Boolean { mSerialPortHelper.dispatchKeyEvent(event) return super.dispatchKeyEvent(event) } private val mSerialPortHelper by lazy { SerialPortHelper(this, object : OnSerialScanListener { override fun dispatchScanEvent(type: OnSerialScanListener.ScanType, content: String) { // 刷卡开门 dispatchReadCardResult(content) } }) } private fun dispatchReadCardResult(username: String) { showLoading() val disposable = ApiRepository.getCardIsOpen(LabApp.sLabConfig!!.labId, username) .subscribe({ userVo -> dismissLoading() onAuthSuccess(AuthType.CARD, userVo) }, { throwable -> dismissLoading() showNetError(throwable) throwable.printStackTrace() }) addDisposable(disposable) } private fun onAuthSuccess(authType: AuthType, userVo: UserVo) { // 在未登录首页验证成功后,判断用户是否有开门权限,登录+开门 val configAuthType = LabApp.sLabConfig?.authType ?: return // showToast("当前类型${LabApp.sLabConfig?.authType} 取值参数${AuthTypeConfig.FOUR_CHOICE.type}") RcLog.info("当前类型${LabApp.sLabConfig?.authType} 取值参数${AuthTypeConfig.FOUR_CHOICE.type}") // when (configAuthType) { // "1","2","3"->{ // openDoor(userVo) // } // "4"->{ // // 进入密码验证 // val intent = Intent(this, DualAuthActivity::class.java) // intent.putExtra("card_auth", true) // intent.putExtra("user", userVo) // startActivity(intent) // } // } when (configAuthType) { AuthTypeConfig.FINGER.type, AuthTypeConfig.FACE_OR_FINGER.type -> { if (AuthType.FINGER == authType) { openDoor(userVo) } } AuthTypeConfig.FOUR_CHOICE.type -> { openDoor(userVo) } AuthTypeConfig.CARD_PASSWORD.type -> { if (AuthType.CARD == authType) { // 进入密码验证 val intent = Intent(this, DualAuthActivity::class.java) intent.putExtra("card_auth", true) intent.putExtra("user", userVo) startActivity(intent) } } } } private fun openDoor(userVo: UserVo) { LabApp.sUserVo = userVo val intent = Intent(this, MainActivity::class.java) startActivity(intent) } @Subscribe(threadMode = ThreadMode.MAIN) fun onUpdateEventEvent(event: UpdateEvent) { if (CommonUtils.stringParseInt(event.data.version) > DeviceUtils.getVersionCode(this)) { // 显示版本更新 downloadApk(event.data.apkUploadFile) } } private var apkDownloading = false private fun downloadApk(downloadUrl: String) { if (apkDownloading) return apkDownloading = true callApkUpdateApi("2") ApkUpdater(this, BuildConfig.APPLICATION_ID, callback = object : ApkUpdater.DownloadCallback { override fun onProgress(progress: Int) { } override fun onFailed(errMsg: String?) { apkDownloading = false callApkUpdateApi("0") } override fun onSuccess(apkFile: String) { apkDownloading = false callApkUpdateApi("1") } }).downloadApk(downloadUrl) } /* * state 0:升级失败; 1:升级成功; 2:升级中 */ private fun callApkUpdateApi(state: String) { val disposable = ApiRepository.onepcApkUpdate(CommonUtils.getAndroidId(), state) .subscribe({ }, { }) addDisposable(disposable) } @Subscribe(threadMode = ThreadMode.MAIN) fun onBulletinBoardEvent(event: BulletinBoardEvent) { mBulletinBoardAdapter.updateSensorValue(event.data) } private var mWaringDialog: WaringDialog? = null @Subscribe(threadMode = ThreadMode.MAIN) fun onWarningEvent(event: WarningEvent) { if (null == mWaringDialog) { if (!event.data.isNullOrEmpty()) { mWaringDialog = WaringDialog(this, event.data).apply { setOnDismissListener { mWaringDialog = null } } mWaringDialog!!.show() } } else { if (event.data.isNullOrEmpty()) { mWaringDialog!!.dismiss() } else { mWaringDialog!!.updateWaringValue(event.data) } } mBulletinBoardAdapter.updateWaringValue(event.data) } @Subscribe(threadMode = ThreadMode.MAIN) fun onEmergencyEvent(event: EmergencyEvent) { when (event.type) { 1 -> textParseVideo(event.data) 2 -> mAudioBinder?.startPlayer(event.data) } } private fun textParseVideo(text: String?) { if (text.isNullOrEmpty()) return showLoading() val disposable = ApiRepository.textParseVideo(text) .subscribe({ data -> dismissLoading() mAudioBinder?.startPlayer(data.url) }, { throwable -> dismissLoading() throwable.printStackTrace() showNetError(throwable) }) addDisposable(disposable) } @Subscribe(threadMode = ThreadMode.MAIN) fun onLabInfoEvent(event: LabInfoEvent) { // {"msg":"5","sendDate":"2023-04-13 13:17:39"} if (event.message.isEmpty()) return LabApp.sLabConfig?.let { labConfig -> val authType = JSONObject(event.message).optString("msg", labConfig.authType) labConfig.authType = authType } } @Subscribe(threadMode = ThreadMode.MAIN) fun onOnlineUserEvent(event: OnlineUserEvent) { queryPerson() } } private class HomeBoardAdapter : BaseQuickAdapter(R.layout.item_home_board) { private val mValueMap = HashMap() private val mWarningSet = HashSet() private val mSensorMap = HashMap().apply { SensorEnum.values().forEach { put(it.funNum, it) } } private fun goneSensor(funNum: String?): Boolean { return SensorEnum.FIRE.funNum == funNum } override fun setNewInstance(list: MutableList?) { val newlyList = list?.filter { !goneSensor(it.funNum) } if (null != newlyList) { mValueMap.clear() newlyList.forEach { mValueMap[it.funNum] = BoardValue(it.`val`, it.unit, it.formatVal) } } super.setNewInstance(newlyList?.toMutableList()) } fun updateSensorValue(data: BulletinBoardEntity.Data?) { val newlyList = data?.functionStatuses?.filter { !goneSensor(it.funNum) } var valueChanged = mValueMap.size != newlyList?.size newlyList?.forEach { item -> val oldValue = mValueMap[item.funNum] if (!valueChanged) { valueChanged = oldValue?.value != item.`val` || oldValue?.unit != item.unit } mValueMap[item.funNum] = BoardValue(item.`val`, item.unit, item.formatVal) } if (valueChanged) { notifyDataSetChanged() } } fun updateWaringValue(data: List?) { val newlyList = data?.filter { !goneSensor(it.funNum) } var valueChanged = mWarningSet.size != newlyList?.size if (!valueChanged) { val changedItem = newlyList?.find { !mWarningSet.contains(it.funNum) } valueChanged = null != changedItem } mWarningSet.clear() newlyList?.forEach { item -> mWarningSet.add(item.funNum) } if (valueChanged) { notifyDataSetChanged() } } override fun convert(holder: BaseViewHolder, item: LabBulletinBoardVo) { val itemView = holder.itemView as ItemBoardView itemView.setSensorInfo( item.describe, mSensorMap[item.funNum]?.icon ?: R.mipmap.icon_sy_wzcgq ) val itemVal = mValueMap[item.funNum] itemView.setSensorValue(itemVal?.value, itemVal?.unit, mWarningSet.contains(item.funNum)) } private data class BoardValue(val value: String?, val unit: String?, val formatVal: String?) } // type 1-值班人员 2-准入人员 private class PersonFlipperAdapter( private val type: Int, private val data: List? ) : BaseAdapter() { override fun getCount() = data?.size ?: 0 override fun getItem(position: Int): LabPersonVo? { return data?.get(position) } override fun getItemId(position: Int) = position.toLong() override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val rootView: View val viewHolder: ViewHolder if (convertView == null) { val viewBinding = ItemHomePersonFlipperBinding.inflate(LayoutInflater.from(parent!!.context)) rootView = viewBinding.root viewHolder = ViewHolder(viewBinding.pPhoto, viewBinding.pName, viewBinding.pCardNumber) rootView.tag = viewHolder } else { rootView = convertView viewHolder = convertView.tag as ViewHolder } getItem(position)?.let { Glide.with(rootView.context) .load(it.avatar) .placeholder(R.mipmap.icon_sign_in_avatar) .error(R.mipmap.icon_sign_in_avatar) // .transform(RoundedCorners(DeviceUtils.dip2px(context, 6f))) .into(viewHolder.imageView) viewHolder.name.text = it.userName if (1 == type) { viewHolder.number.text = it.userPhone // 值班人员 } else { viewHolder.number.text = "准入期限:${formatValidTime(it.validEndTime)}" // 准入人员 } } return rootView } private fun formatValidTime(input: String?): String { // 2023-10-10 => 23-10-10 return if (input.isNullOrEmpty()) "" else input.substring(2, input.length) } class ViewHolder( val imageView: ImageView, val name: TextView, val number: TextView ) } // 实验人员Adapter private class ExperimentPersonAdapter : BaseQuickAdapter(R.layout.item_home_person_flipper) { override fun convert(holder: BaseViewHolder, item: LabPersonVo) { Glide.with(context) .load(item.avatar) .placeholder(R.mipmap.icon_sign_in_avatar) .error(R.mipmap.icon_sign_in_avatar) // .transform(RoundedCorners(DeviceUtils.dip2px(context, 6f))) .into(holder.getView(R.id.pPhoto)) // 签到时间:11-08 14:35 holder.setText(R.id.pName, item.userName) .setText(R.id.pCardNumber, "签到时间:${formatSignTime(item.signTime)}") .setVisible(R.id.bottom_line, true) } private fun formatSignTime(time: String?): CharSequence { // 2023-03-30 15:45:25 => 03-30 15:45 return if (time.isNullOrEmpty()) "" else time.subSequence(5, 16) } }