Home > front end >  My custom view is not being shown how should I fixed it?
My custom view is not being shown how should I fixed it?

Time:05-22

Hello I try to add view binding in my custom view but unfortunately my custom view is not visible, every thing works fine but when I open the activity the custom view is not displayed

my custom view 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)
    }
}

main 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

my customview layout 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>

I appreciate you guys if u help me sorry for my bad english

my custom view layout

my main activity layout

CodePudding user response:

You're overriding onLayout but there's no code in it. So when the view needs to lay itself out... it doesn't! Remove the onLayout function and it should work.


Also, don't call inflate in that init function. You already inflated the layout and added it to your custom view here:

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

If you inflate again, you create a new layout and replace the old one. binding was created from the old layout, and all its references point to the old views.

You also don't want this, it's a duplicate layout:

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

Just as an example of how I'd write this class with view binding - maybe it helps! It should be easier to work with anyway:

// 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() }
        }
        
    }

Personally, if you want the buttons to be named btn0 etc, I'd rename their IDs from appCompatButton to btn0 - that way you can refer to them as binding.btn0, if that's how you prefer to think about it! Give them the names you want to use.

Hope that helps!

  • Related