kotlin 尝试对空对象引用调用虚拟方法“int androidx.constraintlayout.widget.ConstraintLayout.getChildCount()”[重复]

thtygnil  于 2023-05-07  发布在  Kotlin
关注(0)|答案(1)|浏览(132)

此问题已在此处有答案

Null pointer Exception - findViewById()(12个回答)
findViewById returns NULL when using Fragment(7个回答)
What is a NullPointerException, and how do I fix it?(12个回答)
12小时前关闭。

class ClubCardsPricesFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_club_cards_prices, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val items = listOf(
            ClubCardPrices(R.drawable.some_people, "Друзья", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта"),
            ClubCardPrices(R.drawable.some_people, "Индивидуальная", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта"),
            ClubCardPrices(R.drawable.some_people, "Индивидуальная", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта"),
            ClubCardPrices(R.drawable.some_people, "Индивидуальная", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта"),
            ClubCardPrices(R.drawable.some_people, "Индивидуальная", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта"),
            ClubCardPrices(R.drawable.some_people, "Индивидуальная", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта"),
            ClubCardPrices(R.drawable.some_people, "Индивидуальная", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта"),
            ClubCardPrices(R.drawable.some_people, "Индивидуальная", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта"),
            ClubCardPrices(R.drawable.some_people, "Индивидуальная", "", "1 год", "с 7:00 до 23:00", "Тренажерный зал, залы групповых программ, бассейн, турецкая и русская бани, фитнес тестирование", "60 дней", "3 водных инструктажа", "3 гостевых визизта")
        )
        val clubCardsPricesRecyclerView = view.findViewById<RecyclerView>(R.id.card_types_recyclerview1)
        clubCardsPricesRecyclerView.layoutManager = GridLayoutManager(activity, 2)
        clubCardsPricesRecyclerView.adapter = ClubCardPricesAdapter(items) { item, cardImage, cardName ->
            val constraintLayout = view.findViewById<ConstraintLayout>(R.id.club_card_description_constraintlayout)
            val descriptionTitle = view.findViewById<TextView>(R.id.cc_description_title)
            val descriptionTime = view.findViewById<TextView>(R.id.cc_description_time)
            val descriptionAbilities = view.findViewById<TextView>(R.id.cc_description_abilities)
            val descriptionFreezing = view.findViewById<TextView>(R.id.cc_description_freezing)
            val descriptionInductionTrainings = view.findViewById<TextView>(R.id.cc_description_induction_trainings)
            val descriptionGuestVisits = view.findViewById<TextView>(R.id.cc_description_guestvisits)
            val descriptionProgressBar = view.findViewById<ProgressBar>(R.id.cc_description_progressbar)
            val descriptionMonths = view.findViewById<TextView>(R.id.cc_description_months)

            descriptionTitle.text = item.title
            descriptionTime.text = item.time
            descriptionAbilities.text = item.abilities
            descriptionFreezing.text = item.freezing
            descriptionInductionTrainings.text = item.inductionTrainings
            descriptionGuestVisits.text = item.guestVisits

        }
        val cardsCategories = view.findViewById<TextView>(R.id.cards_categories_textview)
        val initialHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 170.toFloat(), resources.displayMetrics).toInt()
        val constraintLayout = view.findViewById<ConstraintLayout>(R.id.card_prices_constraintlayout)
        var isExpanded = false
        cardsCategories.setOnClickListener{
            val targetHeight = if (isExpanded) initialHeight else 80
            isExpanded = !isExpanded
            ClubCardPricesAdapter(items) { item, cardImage, cardName ->
//
            }.toggle()
            val dpValue = 160f
            val density = resources.displayMetrics.density
            val pxValue = dpValue * density
            val floatPxValue = pxValue.toFloat()
            for (i in 0 until items.size) {
                if (isExpanded) {
                    val viewHolder =
                        clubCardsPricesRecyclerView.findViewHolderForAdapterPosition(i) as? ClubCardPricesAdapter.ViewHolder
                    val anim = ValueAnimator.ofFloat(viewHolder?.itemView?.translationY ?: 0f, -1f * i)
                    anim.addUpdateListener { valueAnimator ->
                        val animatedValue = valueAnimator.animatedValue as Float
                        viewHolder?.itemView?.translationY = animatedValue
                    }
                    anim.duration = 1000
                    anim.start()
                } else {
                    val viewHolder =
                        clubCardsPricesRecyclerView.findViewHolderForAdapterPosition(i) as? ClubCardPricesAdapter.ViewHolder
                    val anim = ValueAnimator.ofFloat(viewHolder?.itemView?.translationY ?: 0f, -floatPxValue * i)
                    anim.addUpdateListener { valueAnimator ->
                        val animatedValue = valueAnimator.animatedValue as Float
                        viewHolder?.itemView?.translationY = animatedValue
                    }
                    anim.duration = 1000
                    anim.start()
                }
            }

            val anim = ValueAnimator.ofInt(cardsCategories.height, targetHeight)
            anim.addUpdateListener { valueAnimator ->
                val value = valueAnimator.animatedValue as Int
                cardsCategories.layoutParams.height = value
                cardsCategories.requestLayout()
            }
            anim.duration = 1000
            anim.start()

        }
        val ktpConstraintLayout = view.findViewById<ConstraintLayout>(R.id.know_the_prices_constraintlayout)
        val ktpTextView = view.findViewById<TextView>(R.id.know_the_prices_textview)
        val ktpButton = view.findViewById<TextView>(R.id.know_the_prices_button)
        val ktpEnterName = view.findViewById<EditText>(R.id.card_prices_entername)
        val ktpEnterPhone = view.findViewById<EditText>(R.id.card_prices_enterphonenumber)
        val ktpError = view.findViewById<TextView>(R.id.card_prices_error)
        var ktpIsExpanded = false
        val db = FirebaseFirestore.getInstance()
        val priceListRef = db.collection("priceList")

        ktpConstraintLayout.setOnClickListener {
            ktpIsExpanded = !ktpIsExpanded
            if (ktpIsExpanded) {
                ktpTextView.visibility = View.GONE
                ktpButton.visibility = View.VISIBLE
                ktpEnterName.visibility = View.VISIBLE
                ktpEnterPhone.visibility = View.VISIBLE
                ktpError.visibility = View.INVISIBLE
                val anim = ValueAnimator.ofInt(
                    ktpConstraintLayout.measuredHeight,
                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 160.toFloat(), resources.displayMetrics).toInt()
                )
                anim.addUpdateListener { valueAnimator ->
                    val value = valueAnimator.animatedValue as Int
                    val layoutParams: ViewGroup.LayoutParams = ktpConstraintLayout.layoutParams
                    layoutParams.height = value
                    ktpConstraintLayout.layoutParams = layoutParams
                }
                anim.duration = 1000
                anim.start()
            } else {
                ktpTextView.visibility = View.VISIBLE
                ktpButton.visibility = View.GONE
                ktpEnterName.visibility = View.GONE
                ktpEnterPhone.visibility = View.GONE
                ktpError.visibility = View.GONE
                val anim = ValueAnimator.ofInt(
                    ktpConstraintLayout.measuredHeight,
                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30.toFloat(), resources.displayMetrics).toInt()
                )
                anim.addUpdateListener { valueAnimator ->
                    val value = valueAnimator.animatedValue as Int
                    val layoutParams: ViewGroup.LayoutParams = ktpConstraintLayout.layoutParams
                    layoutParams.height = value
                    ktpConstraintLayout.layoutParams = layoutParams
                }
                anim.duration = 1000
                anim.start()
            }

        }
        val descriptionCloseButton = view.findViewById<ImageButton>(R.id.cc_description_closebutton)
        descriptionCloseButton?.setOnClickListener {
            val constraintLayout = view.findViewById<ConstraintLayout>(R.id.club_card_description_constraintlayout)
            val constraintSet = ConstraintSet()
            val layout = view.findViewById<ConstraintLayout>(R.id.card_prices_constraintlayout)
            constraintSet.clone(layout)
            constraintSet.connect(constraintLayout.id, ConstraintSet.TOP, ClubCardsPricesFragment().id, ConstraintSet.BOTTOM)
            constraintSet.applyTo(layout)
        }

        ktpButton.setOnClickListener {
            val name = ktpEnterName.text.toString()
            val phoneNumber = ktpEnterPhone.text.toString()

            val data = hashMapOf(
                "name" to name,
                "phoneNumber" to phoneNumber
            )
            if (ktpEnterName.text.isNotEmpty() && ktpEnterPhone.text.isNotEmpty()) {
                priceListRef.add(data)
                    .addOnSuccessListener { documentReference ->
                        Toast.makeText(getActivity(),"Заявка отправлена успешно",Toast.LENGTH_LONG).show()
                        ktpTextView.visibility = View.VISIBLE
                        ktpButton.visibility = View.GONE
                        ktpEnterName.visibility = View.GONE
                        ktpEnterPhone.visibility = View.GONE
                        ktpError.visibility = View.GONE
                    }
                    .addOnFailureListener { e ->
                        ktpError.text = "Ошибка отправки"
                        ktpError.visibility = View.VISIBLE
                    }
            }
            else {
                ktpError.text = "Заполните все поля"
                ktpError.visibility = View.VISIBLE
            }
        }

    }

    companion object {
        fun newInstance() = ClubCardsPricesFragment()
    }
}

class ClubCardPricesAdapter(private val items: List<ClubCardPrices>, private val listener: (ClubCardPrices, ImageView, TextView) -> Unit) : RecyclerView.Adapter<ClubCardPricesAdapter.ViewHolder>() {

    private var isExpanded = false

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.card_type_element, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = items[position]
        holder.bind(item, listener)
        val layoutParams = holder.itemView.layoutParams as RecyclerView.LayoutParams
        holder.itemView.layoutParams = layoutParams
        val dpValue = 160f
        val density = holder.itemView.resources.displayMetrics.density
        val pxValue = dpValue * density
        val floatPxValue = pxValue.toFloat()

        if (isExpanded) {
            holder.itemView.translationY = 0f
            val animation = TranslateAnimation(0f, 0f, holder.itemView.translationY, 0f)
            animation.duration = 1000
            holder.itemView.startAnimation(animation)
            holder.bind(item, listener)
        } else {
            holder.itemView.translationY = -position*floatPxValue
            val animation = TranslateAnimation(0f, 0f, holder.itemView.translationY, 0f)
            animation.duration = 1000
            holder.itemView.startAnimation(animation)
            holder.bind(item, listener)
        }
    }

    fun toggle() {
        isExpanded = !isExpanded
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int {
        return items.size
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: ClubCardPrices, listener: (ClubCardPrices, ImageView, TextView) -> Unit) = with(itemView) {
            val cardImage = findViewById<ImageView>(R.id.card_type_image)
            val cardName = findViewById<TextView>(R.id.card_type_name)
            val cardPersonsAmount = findViewById<TextView>(R.id.card_type_personamount)
            val cardTerm = findViewById<TextView>(R.id.card_type_term)
            val cardLayout = findViewById<LinearLayout>(R.id.card_type_linearlayout)
            cardImage?.let{
                it.setImageResource(item.image)
            }
            cardName?.let{
                it.text = item.title
            }
            cardPersonsAmount?.let{
                it.text = item.personosAmount
            }
            cardTerm?.let{
                it.text = item.term
            }

            setOnClickListener {
                val constraintLayout = itemView.findViewById<ConstraintLayout>(R.id.club_card_description_constraintlayout)
                val ccTextView = itemView.findViewById<TextView>(R.id.cards_categories_textview)
                val constraintSet = ConstraintSet()
                val layout = itemView.findViewById<ConstraintLayout>(R.id.card_prices_constraintlayout)
                constraintSet.clone(layout)
                constraintSet.connect(constraintLayout.id, ConstraintSet.TOP, ccTextView.id, ConstraintSet.BOTTOM, 100)
                constraintSet.applyTo(layout)
                listener(item, cardImage, cardName)
            }
        }
    }
}

data class ClubCardPrices(val image: Int, val title: String, val personosAmount: String, val term: String, val time: String, val abilities: String, val freezing: String, val inductionTrainings: String, val guestVisits: String) : Serializable

单击RecyclerView中的项目时,SetOnSlickListener中出现错误。我在单击ImageButton时执行了完全相同的设置约束的实现,一切正常,但当单击元素时,出现了一个致命错误。我还尝试通过getChild()实现它,但这也没有帮助。会有什么问题呢?

2ic8powd

2ic8powd1#

您应该发布实际的堆栈跟踪(错误消息及其后面描述导致错误的调用的行)-这是一个需要仔细查看并猜测问题所在的大量代码。如果要我猜的话,你是在这里得到的:

setOnClickListener {
    ...
    val constraintSet = ConstraintSet()
    val layout = itemView.findViewById<ConstraintLayout>(R.id.card_prices_constraintlayout)
    constraintSet.clone(layout)

因为最后一个方法调用了invokes getChildCount on the layout you provide

public void clone(ConstraintLayout constraintLayout) {
    int count = constraintLayout.getChildCount();

(我不得不查找ConstraintSet的源代码来确认这一点--这就是为什么发布堆栈跟踪总是有帮助的原因!)
因此,如果这就是你得到错误的地方,你的问题是你的layout(在那个方法中被称为constraintLayout)是 null,你不能在 null 上调用getChildCount()。这意味着您的findViewById查找失败,结果是 null。您确定card_type_element.xml有一个ID为card_prices_constraintlayoutConstraintLayout吗?

相关问题