Android 警报对话框故障
Android alert dialog glitch
我无法理解这种奇怪的行为。
这在某些设备上随机发生,并且总是在 Honor 9 STF-L9(gif 动画上的那个)上发生。
如果您查看此 gif,您可以看到从拾取选择器返回时,对话框再次可见,即使没有人显示它(通过单击它查看完整图像 gif 以查看视频) ).
我有一个 Activity
应用程序(我使用新的 Navigation jetpack 组件)并且我的 MainActivity
中有一个自定义 AlertDialog
:
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
private lateinit var inflater: LayoutInflater
private lateinit var dialogView: View
private lateinit var messageTextView: TextView
private val progressHud: AlertDialog by lazy {
val dialogBuilder =
AlertDialog.Builder(this, R.style.ProgressHudTheme)
messageTextView.visibility = View.GONE
dialogBuilder.setView(dialogView)
dialogBuilder.setCancelable(false)
dialogBuilder.create()
}
fun showProgressHud(message: String?) {
messageTextView.visibility = View.GONE
message?.let {
messageTextView.text = it
messageTextView.visibility = View.VISIBLE
}
progressHud.show()
}
fun hideProgressHud() {
progressHud.hide()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.fab.setOnClickListener { view ->
dispatchChoosePictureFromGalleryAppIntentIntent()
}
setupProgressHud()
}
private fun dispatchChoosePictureFromGalleryAppIntentIntent() {
Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
).apply {
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
resolveActivity(packageManager)?.also {
requestImageChooserLauncher.launch(this)
}
}
}
private var requestImageChooserLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
val resultCode = result.resultCode
val data = result.data
// TODO ...
}
private fun setupProgressHud() {
inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
dialogView = inflater.inflate(R.layout.progress_hud, null)
messageTextView = dialogView.findViewById(R.id.progressHudTextView)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> true
else -> super.onOptionsItemSelected(item)
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_main)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
}
对话框在 FirstFragment
中以这种方式显示和隐藏:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonFirst.setOnClickListener {
(activity as? MainActivity)?.showProgressHud("Loading...")
Handler().postDelayed({
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
(activity as? MainActivity)?.hideProgressHud()
}, 5000)
}
}
您可以在此处找到完整的工作示例:https://github.com/shadowsheep1/android-alert-dialog-glitch
我还是不明白为什么会这样。
如果有人以前遇到过这个问题或有任何线索,我们将不胜感激。
尝试替换
progressHud.hide()
来自
progressHud.dismiss().
那应该没问题。
使用 dismiss()
而不是 hide()
有一个更重要的原因:使用 hide()
可能会导致 Leaked Window Error,因为它并没有真正删除视图,只是隐藏了它,然后如果你完成 activity 可能会导致泄漏。
我无法理解这种奇怪的行为。
这在某些设备上随机发生,并且总是在 Honor 9 STF-L9(gif 动画上的那个)上发生。
如果您查看此 gif,您可以看到从拾取选择器返回时,对话框再次可见,即使没有人显示它(通过单击它查看完整图像 gif 以查看视频) ).
我有一个 Activity
应用程序(我使用新的 Navigation jetpack 组件)并且我的 MainActivity
中有一个自定义 AlertDialog
:
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
private lateinit var inflater: LayoutInflater
private lateinit var dialogView: View
private lateinit var messageTextView: TextView
private val progressHud: AlertDialog by lazy {
val dialogBuilder =
AlertDialog.Builder(this, R.style.ProgressHudTheme)
messageTextView.visibility = View.GONE
dialogBuilder.setView(dialogView)
dialogBuilder.setCancelable(false)
dialogBuilder.create()
}
fun showProgressHud(message: String?) {
messageTextView.visibility = View.GONE
message?.let {
messageTextView.text = it
messageTextView.visibility = View.VISIBLE
}
progressHud.show()
}
fun hideProgressHud() {
progressHud.hide()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.fab.setOnClickListener { view ->
dispatchChoosePictureFromGalleryAppIntentIntent()
}
setupProgressHud()
}
private fun dispatchChoosePictureFromGalleryAppIntentIntent() {
Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
).apply {
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
resolveActivity(packageManager)?.also {
requestImageChooserLauncher.launch(this)
}
}
}
private var requestImageChooserLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
val resultCode = result.resultCode
val data = result.data
// TODO ...
}
private fun setupProgressHud() {
inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
dialogView = inflater.inflate(R.layout.progress_hud, null)
messageTextView = dialogView.findViewById(R.id.progressHudTextView)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> true
else -> super.onOptionsItemSelected(item)
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_main)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
}
对话框在 FirstFragment
中以这种方式显示和隐藏:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonFirst.setOnClickListener {
(activity as? MainActivity)?.showProgressHud("Loading...")
Handler().postDelayed({
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
(activity as? MainActivity)?.hideProgressHud()
}, 5000)
}
}
您可以在此处找到完整的工作示例:https://github.com/shadowsheep1/android-alert-dialog-glitch
我还是不明白为什么会这样。
如果有人以前遇到过这个问题或有任何线索,我们将不胜感激。
尝试替换
progressHud.hide()
来自
progressHud.dismiss().
那应该没问题。
使用 dismiss()
而不是 hide()
有一个更重要的原因:使用 hide()
可能会导致 Leaked Window Error,因为它并没有真正删除视图,只是隐藏了它,然后如果你完成 activity 可能会导致泄漏。