按下后退按钮导致的意外行为

Unintended behaviour as a result of pressing back button

我有两个活动。 Activity A 包含带有图像的卡片视图元素的回收器视图。在 Activity A 中选择一个元素。图像的完整横向版本显示在 Activity B 中。

Activity B 的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
    android:orientation="vertical">


    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

Activity B 的代码库如下:

class PosterViewActivity : AppCompatActivity()
{

    private lateinit var imageView: AppCompatImageView

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_poster_view)
        init()
    }

    private fun init()
    {
        findViewsByID()
        getBundle()
        toggleHide()
    }  

    private fun getBundle()
    {
        if (intent != null)
        {
            var imageUrl = intent.getStringExtra(ARG_IMAGE_URL)
            if (imageUrl != null)
            {
                Glide.with(this).load(imageUrl).centerInside().into(imageView)
            }
        }
    }

 private fun findViewsByID()
    {
        imageView = findViewById(R.id.imageView)
       }

    override fun onOptionsItemSelected(item: MenuItem): Boolean
    {
        if (item.itemId == android.R.id.home)
        {
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onBackPressed()
    {
        super.onBackPressed()
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    }

    override fun onWindowFocusChanged(hasFocus: Boolean)
    {
        super.onWindowFocusChanged(hasFocus)

}

    private fun toggleHide()
    {
        val uiOptions = window.decorView.systemUiVisibility
        var newUiOptions = uiOptions
        val isImmersiveModeEnabled = uiOptions or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY == uiOptions
        if (isImmersiveModeEnabled)
        {
            Log.i("PosterViewActivity", "Turning immersive mode mode off. ")
        }
        else
        {
            Log.i("PosterViewActivity", "Turning immersive mode mode on.")
        }

        if (Build.VERSION.SDK_INT >= 14)
        {
            newUiOptions = newUiOptions xor View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        }

        // Status bar hiding: Backwards compatible to Jellybean
        if (Build.VERSION.SDK_INT >= 16)
        {
            newUiOptions = newUiOptions xor View.SYSTEM_UI_FLAG_FULLSCREEN
        }

        if (Build.VERSION.SDK_INT >= 18)
        {
            newUiOptions = newUiOptions xor View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        }

        window.decorView.systemUiVisibility = newUiOptions
    }
}

但是,当我按下设备上的后退按钮而不是 return 转到 Activity A. 状态和导航按钮显示和隐藏,需要按 4 次后退按钮到 return 到 Activity A. 我检查了返回堆栈,堆栈中有两个活动,即 A 和 B

代码来自 Activity A 调用 Activity B:

if(promoList.size >0)
        {
            noPromoImageView.visibility = View.GONE
            noPromoTextView.visibility = View.GONE

            promoAdapter = PromotionsAdapter(this, promoList!!)
            promoRecyclerView.layoutManager = GridLayoutManager(this, 3)
            promoRecyclerView.adapter = promoAdapter
            promoRecyclerView.addOnItemTouchListener(
                RecyclerTouchListener(applicationContext,
                    promoRecyclerView,
                    object : ClickListener
                    {
                        override fun onClick(view: View, position: Int)
                        {
                            openPosterView(position)
                        }

                        override fun onLongClick(view: View?, position: Int)
                        {

                        }
                    }))
        }
        else
        {
            noPromoImageView.visibility = View.VISIBLE
            noPromoTextView.visibility = View.VISIBLE
        }
    }

 private fun openPosterView(position: Int)
    {
        val posterImageDetails = displayedRules!![position]!!.imageDetails
        if (posterImageDetails.isNotEmpty())
        {
            var cur = -1
            for ((pos, item) in posterImageDetails.withIndex())
            {
                val key = item.containsValue("Fullscreen")
                if (key)
                {
                    cur = pos
                }
            }
            var imagesLink: Map<String, String>
            if (cur > -1)
            {
                imagesLink = posterImageDetails[cur]
                var imageUrl = imagesLink?.get("ImageUrl")
                if (imageUrl!!.isNotEmpty())
                {
                    var intent = Intent(this, PosterViewActivity::class.java)
                    var bundle = Bundle()
                    bundle.putString(ARG_IMAGE_URL, imageUrl)
                    intent.putExtras(bundle)

                    this.startActivity(intent)
                }
            }
        }
    }

 internal class RecyclerTouchListener(context: Context, recyclerView: RecyclerView, private val clickListener: ClickListener) : RecyclerView.OnItemTouchListener
    {

        private val gestureDetector: GestureDetector

        init
        {
            gestureDetector = GestureDetector(
                context,
                object : GestureDetector.SimpleOnGestureListener()
                {
                    override fun onSingleTapUp(e: MotionEvent): Boolean
                    {
                        return true
                    }

                    override fun onLongPress(e: MotionEvent)
                    {
                        val child = recyclerView.findChildViewUnder(e.x, e.y)
                        if (child != null && clickListener != null)
                        {
                            clickListener.onLongClick(child, recyclerView.getChildPosition(child))
                        }
                    }
                })
        }

        override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean
        {

            val child = rv.findChildViewUnder(e.x, e.y)
            if (child != null && clickListener != null && gestureDetector.onTouchEvent(e))
            {
                clickListener.onClick(child, rv.getChildPosition(child))
            }
            return false
        }

        override fun onTouchEvent(rv: RecyclerView, e: MotionEvent)
        {
        }

        override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean)
        {

        }
    }

我认为ActivityA的clickListener是错误的。项目的数量可以是 4,当项目被点击时,项目的 onClickListener 可以调用 activity B 4 次。

正如 Farid 所建议的那样,通过扩展 recyclerview 的 ontouchlistener 它增加了更多的复杂性。我最初拥有并放弃的最简单的解决方案是在适配器中添加一个 OnClick 侦听器

 inner class PromoViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener
    {
        override fun onClick(v: View?)
        {
              openPosterView(adapterPosition)
        }

  private val description: JustifiedTextView
        private val duration: AppCompatTextView
        private val startDate: AppCompatTextView
        private val endDate: AppCompatTextView
        private val imageViewCompact: AppCompatImageView

        init
        {
            description = itemView.findViewById(R.id.textViewProductOnPromo)
            duration = itemView.findViewById(R.id.textViewPromoDates)
            imageViewCompact = itemView.findViewById(R.id.imageViewCompact)
            startDate = itemView.findViewById(R.id.textViewStartDate)
            endDate = itemView.findViewById(R.id.textViewEndDate)
            view.setOnClickListener(this)
        }
}