android 当设置Activity状态栏为透明时,键盘弹出ScrollView滚动无效解决方案

当在Android应用中设置Activity状态栏为透明,遇到键盘弹出导致ScrollView无法正常滚动的问题,可以通过监听布局变化,计算键盘高度并调整ScrollView的marginBottom来解决。具体实现是获取窗口装饰视图,并在全局布局改变时更新ScrollView的布局参数,使其能适应键盘弹出的状态。
final View decorView = getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        Rect rect = new Rect();
        decorView.getWindowVisibleDisplayFrame(rect);
        int screenHeight = decorView.getRootView().getHeight();
        int heightDifference = screenHeight - rect.bottom;//计算软键盘占有的高度  = 屏幕高度 - 视图可见高度
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) loginBinding.scrollView.getLayoutParams();
        layoutParams.setMargins(0, 0, 0, heightDifference);//设置ScrollView的marginBottom的值为软键盘占有的高度即可
        loginBinding.scrollView.requestLayout();
    }
});
lass DataSettingAlertActivity : BaseMvvmActivity<ActivityDataSettingAlertBinding>(), View.OnClickListener { private lateinit var mAdapter: SettingCheckAdapter private lateinit var mItemCheck: String private var mDoneItem: MenuItem? = null private var mNotification: Boolean = true private var mSms: Boolean = true private var mPhone: String = "" private var mThreshold: Int = 10 private var mTimer: CountDownTimer? = null private val mViewModel: SMSViewModel by mercusysViewModels() private val mActivityLauncher = StartActivityForResultLauncher(this) companion object { const val NOTIFICATION = "notification" const val SMS = "sms" const val PHONE = "phone" const val THRESHOLD = "threshold" private const val PERCENTAGE_THRESHOLD = 90 private const val TIME_MILLIS_BASE = 1000 } override fun bindContentView(savedInstanceState: Bundle?): ActivityDataSettingAlertBinding { window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN) return ActivityDataSettingAlertBinding.inflate(layoutInflater) } override fun subscribeViewModel(savedInstanceState: Bundle?) { initInfo() initView() initCheckView() subscribe() } override fun onClick(v: View?) { when (v) { viewBinding.line2DataPercentage -> startDataSettingPercentageActivity() viewBinding.sendMessageBtn -> { val phone = viewBinding.tfPhone.getText() val smsSendParams = SMSSendParams( getString(R.string.data_setting_sms_test_message), phone, System.currentTimeMillis() / 1000 ) if (checkLegitimate(phone)) { mViewModel.sendMessage(smsSendParams) } } } } override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.common_done, menu) mDoneItem = menu.findItem(R.id.common_done) mDoneItem?.isEnabled = false return super.onCreateOptionsMenu(menu) } override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.common_done -> { val phoneNumber = viewBinding.tfPhone.getText() val percentageNum = viewBinding.line2DataPercentage.content.text.substring( 0, viewBinding.line2DataPercentage.content.text.length - 1 ) backToDataSettingActivity(phoneNumber, percentageNum.toInt()) return true } android.R.id.home -> { finish() return true } } return super.onOptionsItemSelected(item) } override fun onBackPressed() = finish() override fun onDestroy() { mTimer?.cancel() super.onDestroy() } private fun initCheckView() { val selectionList: MutableList<String> = ArrayList() selectionList.add(getString(R.string.ddns_status_off)) selectionList.add(getString(R.string.advanced_data_setting_usage_alert_sms_notifications)) mAdapter = SettingCheckAdapter( this, selectionList ) viewBinding.settingItemList.layoutManager = LinearLayoutManager(this) viewBinding.settingItemList.adapter = mAdapter mAdapter.setItemCheck(mItemCheck) mAdapter.setOnItemSelectListener { mItemCheck = it.tag as String setAlertSwitch(mItemCheck) checkParamsChange() } } private fun initInfo() { mNotification = intent.getBooleanExtra(NOTIFICATION, false) mSms = intent.getBooleanExtra(SMS, true) mPhone = intent.getStringExtra(PHONE) ?: "" mThreshold = intent.getIntExtra(THRESHOLD, PERCENTAGE_THRESHOLD) } private fun initView() { viewBinding.toolbar.toolbar.setTitle(R.string.advanced_data_setting_sms_alert) viewBinding.tfPhone.setText(mPhone) viewBinding.tfPhone.editText?.setSelection(mPhone.length) viewBinding.line2DataPercentage.setContentText( getString( R.string.common_percent_format, mThreshold ) ) viewBinding.sendMessageBtn.isAllCaps = false viewBinding.sendMessageBtn.isEnabled = mPhone.isNotEmpty() /** * 由于设备不支持切换开关,因此mItemCheck默认设置sms开启,并且xml对应view设置为gone * 数据返回到dataSettings主页面,并且不下发该字段 */ mItemCheck = getString(R.string.advanced_data_setting_usage_alert_sms_notifications) setAlertSwitch(mItemCheck) viewBinding.line2DataPercentage.setOnClickListener(this) viewBinding.sendMessageBtn.setOnClickListener(this) viewBinding.tfPhone.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { if (viewBinding.tfPhone.getText().isNotEmpty()) { when { viewBinding.tfPhone.getText().first() != '+' && !Character.isDigit( viewBinding.tfPhone.getText().first() ) -> { viewBinding.tfPhone.error = getString(R.string.common_phone_input_start_with) } !checkLegitimate(viewBinding.tfPhone.getText()) -> { viewBinding.tfPhone.error = getString(R.string.common_invalid_format) } else -> { viewBinding.tfPhone.error = null viewBinding.tfPhone.helperText = getString(R.string.advanced_data_setting_usage_alert_phone_tips_mercusys) } } } checkParamsChange() } }) } private fun subscribe() { mViewModel.getSendResult().observe(this) { handleSendSmsResult(it) } } private fun handleSendSmsResult(errorCode: Int?) { if (errorCode == null) { TPToastDialog.showLoading(this, null, getString(R.string.common_sending)) } else { TPToastDialog.dismiss() when (errorCode) { SMSConstants.REASON_CODE_NO_ERROR -> { TPToastDialog.showSucceed(this, null, getString(R.string.common_succeeded)) startCountDownTimer() } SMSConstants.REASON_CODE_DEVICE_MEMORY_INSUFFICIENT -> { TPToastDialog.showFailed( this, null, getString(R.string.sms_send_error_code_memory) ) } SMSConstants.REASON_CODE_SIM_CARD_COMMON_ERROR -> { TPToastDialog.showFailed( this, null, getString(R.string.sms_send_error_code_sim) ) } SMSConstants.REASON_CODE_COMMON_NETWORK_ERROR -> { TPToastDialog.showFailed( this, null, getString(R.string.sms_send_error_code_network) ) } SMSConstants.REASON_CODE_MESSAGE_BOX_FULL -> { TPToastDialog.showFailed( this, null, getString(R.string.sms_send_error_code_capacity) ) } else -> { TPToastDialog.showFailed( this, null, getString(R.string.sms_send_error_code_unknown) ) } } } } private fun checkParamsChange() { if ((mItemCheck == getString(R.string.advanced_data_setting_usage_alert_sms_notifications) || mItemCheck == getString( R.string.advanced_data_setting_usage_alert_push_sms_notifications )) && (viewBinding.tfPhone.getText() .isEmpty() || !checkLegitimate(viewBinding.tfPhone.getText())) ) { enableDoneText(false) } else { enableDoneText(true) } } private fun enableDoneText(enable: Boolean) { mDoneItem?.isEnabled = enable viewBinding.sendMessageBtn.isEnabled = enable } private fun checkLegitimate(phone: String): Boolean { val pattern: Pattern = Pattern.compile(SMSConstants.PHONE_REGEX) val matcher: Matcher = pattern.matcher(phone) return matcher.matches() } private fun setAlertSwitch(alertWay: String) { viewBinding.line2DataPercentage.visibility = if (alertWay == getString(R.string.ddns_status_off)) View.GONE else View.VISIBLE val isEnableSms = alertWay == getString(R.string.advanced_data_setting_usage_alert_sms_notifications) || alertWay == getString( R.string.advanced_data_setting_usage_alert_push_sms_notifications ) viewBinding.tfPhone.visibility = if (isEnableSms) View.VISIBLE else View.GONE viewBinding.sendMessageBtn.visibility = if (isEnableSms) View.VISIBLE else View.GONE } private fun startCountDownTimer() { mTimer = object : CountDownTimer(60000, 1000) { override fun onTick(millisUntilFinished: Long) { viewBinding.sendMessageBtn.isEnabled = false viewBinding.sendMessageBtn.text = getString( R.string.advanced_data_setting_usage_sms_send_timer, (millisUntilFinished / TIME_MILLIS_BASE).toInt() ) } override fun onFinish() { viewBinding.sendMessageBtn.isEnabled = true viewBinding.sendMessageBtn.text = getString(R.string.advanced_data_setting_usage_sms_send_test) } }.start() } private fun startDataSettingPercentageActivity() { val intent = Intent(this, DataSettingPercentageActivity::class.java) .putExtra( DataSettingPercentageActivity.PERCENTAGE, viewBinding.line2DataPercentage.content.text ) mActivityLauncher.launch(intent) { it.takeIf { it.resultCode == RESULT_OK }?.run { viewBinding.line2DataPercentage.setContentText( data?.getStringExtra( DataSettingPercentageActivity.PERCENTAGE ) ?: "" ) checkParamsChange() } } } private fun backToDataSettingActivity(phone: String, threshold: Int) { setResult(RESULT_OK, Intent().putExtra(PHONE, phone).putExtra(THRESHOLD, threshold)) finish() } } 如上是对应deactivity 修改后 仍有问题 帮我进一步芬妮下
最新发布
10-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值