首页 > 解决方案 > 如何在两个视图不正确时自动翻转它们

问题描述

我正在寻找创建一个记忆游戏,我现在正在研究这个功能。我已经大致了解了项目的逻辑,但我想补充一点细节。我想补充的细节之一是,当两张选择的卡片不正确时,它们会在 1 秒后自行转动。我尝试使用 Handler().postDelay 但它似乎没有用。

这是代码

class GamePlay1Fragment : Fragment() {

//    lateinit var front_anim: AnimatorSet
//    lateinit var back_anim: AnimatorSet

    private lateinit var pieces: List<ImageView>
    private lateinit var gameCards: List<GameCard>
    private var indexOfSelectedPiece: Int? = null


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding: Gameplay1FragmentBinding = DataBindingUtil.inflate(
            inflater,
            R.layout.gameplay1_fragment,
            container, false)


        binding.backButtonView.setOnClickListener { v: View ->
            v.findNavController().navigate(GamePlay1FragmentDirections.actionGamePlay1FragmentToLobbyFragment())
        }


        val images = mutableListOf(memorybatcardfront, memorycatcardfront, memorycowcardfront,
            memorydragonfront, memorygarbagemancardfront, memoryghostdogcardfront)

        images.addAll(images)

        images.shuffle()

        pieces = listOf(binding.card1back, binding.card2back, binding.card3back, binding.card4back, binding.card5back,binding.card6back, binding.card7back,
                        binding.card8back, binding.card9back, binding.card10back, binding.card11back, binding.card12back)

        gameCards = pieces.indices.map { index ->
            GameCard(images[index])
        }


            pieces.forEachIndexed { index, piece ->
                piece.setOnClickListener {

                    updatingModels(index)

                    updatingViews()
                }
            }



        return binding.root
    }

    private fun updatingViews() {
        gameCards.forEachIndexed { index, gameCard ->
          val piece = pieces[index]
            piece.setImageResource(if (gameCard.isFacedUp) gameCard.id else allcardbacks)
        }
    }

    private fun updatingModels(position: Int) {
        val gameCard = gameCards[position]

        if (gameCard.isFacedUp) return


        if (indexOfSelectedPiece == null) {
            restoreGameCards()
            indexOfSelectedPiece = position

        }
        else {
            checkingForMatch(indexOfSelectedPiece!!, position)
            indexOfSelectedPiece = null
        }
        gameCard.isFacedUp = !gameCard.isFacedUp
    }

    private fun restoreGameCards() {
        val handler = Handler()
        for (gameCard in gameCards) {
            if (!gameCard.isMatched) {
                handler.postDelayed(runnable, 1000)
                gameCard.isFacedUp = false

            }

        }
    }

    private fun checkingForMatch(position1: Int, position2: Int) {
        if (gameCards[position1].id == gameCards[position2].id) {
          gameCards[position1].isMatched = true
            gameCards[position2].isMatched = true
        }
    }

    private val runnable = Runnable(){
        kotlin.run {
        }
    }

}

如果有其他方法可以做到这一点,我会全力以赴。欣赏它。

标签: androidkotlinandroid-layoutandroid-fragments

解决方案


The issue is that you filp the card synchronously with invoking the handler (i.e. they execute at the same time), but instead you need to flip the card whenever the handler delay is over.

To fix this you need to transfer the card flipping within the Runnable of the Handler:

private fun restoreGameCards() {
    val handler = Handler(Looper.getMainLooper())
    for (gameCard in gameCards) {
        if (!gameCard.isMatched) {
            handler.postDelayed({
                gameCard.isFacedUp = false // Executes after 1000 millisec
            }, 1000)
        }
    }
}

推荐阅读