我的自定义视图没有显示,我应该如何修复它?

My custom view is not being shown how should I fixed it?

您好,我尝试在我的自定义视图中添加视图绑定,但不幸的是我的自定义视图不可见,一切正常,但是当我打开 activity 时,自定义视图未显示

我的自定义视图class

    class StickerView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet?=null,
    defStyle:Int = 0
) : ConstraintLayout(context,attributeSet,defStyle),View.OnClickListener {

    private val binding = ItemStickerBinding.inflate(LayoutInflater.from(context),this,true)

    private var segmentedVerticalSeekBar: SegmentedVerticalSeekBar? = null

    private var btn1: ImageButton?=null
    private var btn2: ImageButton?=null
    private var btn3: ImageButton?=null
    private var btn4: ImageButton?=null
    private var btn5: ImageButton?=null
    private var btn6: ImageButton?=null
    private var btn0: ImageButton?=null

    init {
        init(context)
    }

    override fun onClick(v: View?) {

        when(v?.id){
            R.id.appCompatButton ->{

            }
            R.id.appCompatButton1 ->{

            }
            R.id.appCompatButton2 ->{

            }
            R.id.appCompatButton3 ->{

            }
            R.id.appCompatButton4 ->{

            }
            R.id.appCompatButton5 ->{

            }
            R.id.appCompatButton6 ->{

            }
        }
    }

    private fun init(context: Context){

        inflate(context,R.layout.item_sticker,this)

        segmentedVerticalSeekBar = binding.svsLevelView

        btn0 = binding.appCompatButton
        btn1 = binding.appCompatButton1
        btn2 = binding.appCompatButton2
        btn3 = binding.appCompatButton3
        btn4 = binding.appCompatButton4
        btn5 = binding.appCompatButton5
        btn6 = binding.appCompatButton6

        btn6?.setOnClickListener(this)

    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        setMeasuredDimension(Int.MAX_VALUE,400)
    }
}

主要activity

 <androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/background"
    tools:context=".MainActivity">

    <com.example.emoticker.StickerView
        android:id="@+id/stickerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <include layout="@layout/item_sticker"/>

    </com.example.emoticker.StickerView>

</androidx.constraintlayout.widget.Constraint

我的自定义视图布局 item_sticker.xml

<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        xmlns:tools="http://schemas.android.com/tools"
        android:background="@color/background"
        tools:context=".StickerView"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
            <com.ss.svs.SegmentedVerticalSeekBar
                android:id="@+id/svsLevelView"
                android:layout_width="60dp"
                android:layout_height="0dp"
                android:layout_gravity="center"
                android:layout_marginStart="20dp"
                android:layout_marginTop="15dp"
                android:layout_marginBottom="15dp"
                app:backgroundColor="@color/white"
                app:cornerRadius="10dp"
                app:currentValue="2"
                app:delimiterColor="@color/white"
                app:isAllRadius="true"
                app:layout_constraintBottom_toTopOf="@+id/appCompatButton6"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:maxValue="4"
                app:progressColor="@color/color_progress"
                app:pyramidViewEnable="true"
                app:step="1"
                app:touchDisabled="false" />
    
            <ImageView
                android:layout_width="100dp"
                android:layout_height="0dp"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                app:layout_constraintBottom_toTopOf="@+id/linearLayout"
                app:layout_constraintEnd_toEndOf="@+id/linearLayout"
                app:layout_constraintStart_toStartOf="@+id/linearLayout"
                app:layout_constraintTop_toTopOf="parent" />
    
            <LinearLayout
                android:id="@+id/linearLayout"
                android:layout_width="0dp"
                android:layout_height="30dp"
                android:layout_marginStart="20dp"
                android:layout_marginEnd="15dp"
                android:layout_marginBottom="5dp"
                android:orientation="horizontal"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/svsLevelView">
    
                <ImageButton
                    android:id="@+id/appCompatButton"
                    android:layout_width="0dp"
                    android:layout_height="40dp"
                    android:layout_gravity="center"
                    android:layout_marginStart="5dp"
                    android:layout_weight="1"
                    android:background="@color/white"
                    android:src="@drawable/laughing_emoji_svgrepo_com" />
    
                <ImageButton
                    android:id="@+id/appCompatButton1"
                    android:layout_width="0dp"
                    android:layout_height="40dp"
                    android:layout_gravity="center"
                    android:layout_marginStart="5dp"
                    android:layout_weight="1"
                    android:background="@color/white"
                    android:src="@drawable/scare_svgrepo_com" />
    
                <ImageButton
                    android:id="@+id/appCompatButton2"
                    android:layout_width="0dp"
                    android:layout_height="40dp"
                    android:layout_gravity="center"
                    android:layout_marginStart="5dp"
                    android:layout_weight="1"
                    android:background="@color/white"
                    android:src="@drawable/crying_emoji_svgrepo_com" />
    
                <ImageButton
                    android:id="@+id/appCompatButton3"
                    android:layout_width="0dp"
                    android:layout_height="40dp"
                    android:layout_gravity="center"
                    android:layout_marginStart="5dp"
                    android:layout_weight="1"
                    android:background="@color/white"
                    android:src="@drawable/sick_svgrepo_com" />
    
                <ImageButton
                    android:id="@+id/appCompatButton4"
                    android:layout_width="0dp"
                    android:layout_height="40dp"
                    android:layout_gravity="center"
                    android:layout_marginStart="5dp"
                    android:layout_weight="1"
                    android:background="@color/white"
                    android:src="@drawable/shocked_emoji_svgrepo_com" />
    
                <ImageButton
                    android:id="@+id/appCompatButton5"
                    android:layout_width="0dp"
                    android:layout_height="40dp"
                    android:layout_gravity="center"
                    android:layout_marginStart="5dp"
                    android:layout_marginEnd="5dp"
                    android:layout_weight="1"
                    android:background="@color/white"
                    android:src="@drawable/angry_svgrepo_com" />
    
            </LinearLayout>
    
            <ImageButton
                android:id="@+id/appCompatButton6"
                android:layout_width="50dp"
                android:layout_height="30dp"
                android:layout_gravity="center"
                android:layout_weight="1"
                android:background="@color/white"
                android:src="@drawable/ic_baseline_subdirectory_arrow_left_24"
                app:layout_constraintBottom_toBottomOf="@+id/linearLayout"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="@+id/linearLayout" />
    
</androidx.constraintlayout.widget.ConstraintLayout>

如果你帮助我,我很感激你们 抱歉我的英语不好

您正在覆盖 onLayout 但其中没有代码。因此,当视图需要自行布局时……它不需要!删除 onLayout 函数,它应该可以工作。


此外,不要在 init 函数中调用 inflate。您已经扩充了布局并将其添加到此处的自定义视图中:

private val binding = ItemStickerBinding.inflate(LayoutInflater.from(context),this,true)

如果您再次膨胀,您将创建一个新布局并替换旧布局。 binding 是从旧布局创建的,其所有引用都指向旧视图。

你也不想要这个,这是一个重复的布局:

<include layout="@layout/item_sticker"/>

作为我如何使用视图绑定编写此 class 的示例 - 也许它有帮助!无论如何,它应该更容易使用:

// subclass FrameLayout instead - you're inflating a layout and putting it -inside-
// your custom view, so a FrameLayout (which is meant to hold a single view) is better
// and safer than a ConstraintLayout (which you're not providing constraints for -
// it could break at some point, or act weird)

// I've removed the View.OnClickListener interface because I'm setting the listeners
// another way
class StickerView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet?=null,
    defStyle:Int = 0
) : FrameLayout(context,attributeSet,defStyle) {

    // this inflates your layout and adds it to the view - job done!
    private val binding =
        ItemStickerBinding.inflate(LayoutInflater.from(context),this,true)

    // If you need to refer to a view you've bound, you usually do it through
    // the binding object - so "binding.appCompatButton0" etc, and there are ways
    // to avoid saying "binding" all the time (see the init block below).
    // But if you really want aliases, you could do it this way:
    val btn0: ImageButton get() = binding.appCompatButton

    init {
        // this lets you avoid saying binding.this, binding.that - it can look neater
        with(binding) {
            // set a single click listener on multiple views
            listOf(
                appCompatButton, appCompatButton1, appCompatButton2,
                appCompatButton3, appCompatButton4, appCompatButton5, appCompatButton6
            ).forEach { button ->
                // call our onClick function with the clicked view
                button.setOnClickListener { view -> onClick(view)}
                // or setOnClickListener(::onClick)
            }

            // or you could set each button's action here, like this
            appCompatButton1.setOnClickListener { doThing() }
            appCompatButton2.setOnClickListener { doSomethingElse() }
        }
    }

    // handle all your button clicks in a function if you want - 
    // v doesn't need to be nullable
    private fun onClick(v: View) {
        // because you're using view binding, you have references to all the views -
        // so you don't need to use IDs at all
        when (v) {
            binding.appCompatButton -> { doThing() }
        }
        
    }

就个人而言,如果您希望将按钮命名为 btn0 等,我会将它们的 ID 从 appCompatButton 重命名为 btn0 - 这样您就可以将它们称为 binding.btn0,如果你喜欢这样想的话!给他们你想用的名字。

希望对您有所帮助!