androidtextviewandroid-linearlayout

Textview getting out of the parent layout in Android XML


Im having some issue with keeping the textview visible and in center of the parent layout

This is some what an expected output i want (this is a image an not a ui layout itself)
[Image](https://i.sstatic.net/KM2Ai.jpg)

but as im not using this image, im trying replicate it with layouts and textview
but im not getting a expected output

this is what im actually getting
[current output](https://i.sstatic.net/gQ6j1.jpg)

As you can see the dots/text is missing

Here is the code im using

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/appToolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="#e7e7e7"
        android:minHeight="?attr/actionBarSize"
        android:theme="?attr/actionBarTheme"
        app:layout_scrollFlags="scroll|enterAlways">


        <LinearLayout
            android:id="@+id/aboutPage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end|center"
            android:layout_margin="10dp"
            android:background="@drawable/border"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="#fffdf6"
                android:orientation="vertical">


                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_margin="15dp"
                    android:text="...."
                    android:textAlignment="center"
                    android:textColor="#36332c"
                    android:textSize="30sp"
                    android:textStyle="bold" />


            </LinearLayout>

        </LinearLayout>


    </androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>

i know its mostly due to the margins I'm giving to the parent linear layout, but that is necessary


Solution

  • You can create simple custom view for this. I know you might think it's overcomplicated, but let me explain.

    Problem

    The main problems are margins and the textSize. Margins are clipping out the space and don't forget that dots belongs on the bottom of the line, so even with margins removed, you will have hard time centering the dots (textAlignment="center" and gravity="center" won't help).

    Solution

    Using custom view you can easily measure and calculate exact center position for dots based on view size and actual text size (which means only size of dots is measured).

    class DotsTextView @JvmOverloads constructor(
        context: Context,
        attributeSet: AttributeSet? = null,
        style: Int = 0
    ) : View(
        context,
        attributeSet,
        style
    ) {
    
        private val text = "...."
    
        //Paint used for set text formatting (like color, size, ..)
        private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            color = Color.parseColor("#36332c")
            textSize = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_SP,
                30f,
                context.resources.displayMetrics,
            )
    
            textAlign = Paint.Align.CENTER
        }
    
        //text bounds to store text measures
        private val textBounds: Rect = Rect()
    
        //Padding replacing the margin
        private val padding = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            15f,
            context.resources.displayMetrics,
        )
    
    
        override fun onDraw(canvas: Canvas) {
            super.onDraw(canvas)
    
            //Draw the text in the centre of view,
            canvas.drawText(
                text,
                measuredWidth / 2f,
                measuredHeight / 2f + textBounds.height() / 2f
                textPaint
            )
        }
    
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            //measure the text so we can properly set view size 
            //and get exact center for placing the text 
            textPaint.getTextBounds(text, 0, text.length, textBounds)
            //Set view size based on paddings and text size
            setMeasuredDimension(
                ((padding * 2) + textBounds.width()).toInt(),
                ((padding * 2) + textBounds.height()).toInt()
            )
        }
    }
    

    And use it in xml layout like this, don't forget to replace com.your.app with your actual package name.

    <com.your.app.DotsTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center" />