Reputation: 3801
In my app I have a header bar which consists of a single textview with fill_parent as width, which have a specific background color and some centered text. Now I want to add a drawable on the left side of the header bar, so I set the drawableLeft and sure enough the text and image is displayed. However the problem here is that the text is no longer properly centered, e.g., when the drawable is added the text is shifted a bit to the right as shown in the screenshots here:
Is there anyway I can center the text properly and have the drawable positioned as it is above without using an additional layout item (such as a LinearLayout)?
Upvotes: 65
Views: 76973
Reputation: 26442
Add this to your textview instead of wrapping with another layout
android:gravity="center|start"
Upvotes: 0
Reputation: 1136
Wrap your TextView inside a LinearLayout. Then set android:gravity="center_horizontal"
to your LinearLayout..
<LinearLayout
android:layout_width="0dp"
android:gravity="center_horizontal"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@drawable/your_drawable"
android:drawablePadding="5dp"
android:ellipsize="end"
android:maxLines="1"
android:textAlignment="center"
android:textColor="@color/ic_text_color"
android:textSize="15sp"
tools:text="Your Text.." />
</LinearLayout>
Upvotes: 1
Reputation: 1829
no test too much, another way
class CenterDrawableToggleButton @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatToggleButton(context, attrs, defStyleAttr) {
private val centerMatrix = Matrix()
override fun onDraw(canvas: Canvas?) {
canvas?.save()?:return
centerMatrix.reset()
centerMatrix.postTranslate(width / 2F - (getDrawWidth() / 2), 0F)
canvas.concat(centerMatrix)
super.onDraw(canvas)
canvas.restore()
}
private fun getDrawWidth(): Float {
return paint.measureText(text.toString()) + compoundPaddingRight + compoundPaddingLeft
}
}
Upvotes: 1
Reputation: 111
Try flowing:
public class DrawableCenterTextView extends AppCompatTextView {
public DrawableCenterTextView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public DrawableCenterTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawableCenterTextView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
// We want the icon and/or text grouped together and centered as a group.
// We need to accommodate any existing padding
final float buttonContentWidth = getWidth() - getPaddingLeft() - getPaddingRight();
float textWidth = 0f;
final Layout layout = getLayout();
if (layout != null) {
for (int i = 0; i < layout.getLineCount(); i++) {
textWidth = Math.max(textWidth, layout.getLineRight(i));
}
}
// Compute left drawable width, if any
Drawable[] drawables = getCompoundDrawables();
Drawable drawableLeft = drawables[0];
int drawableWidth = (drawableLeft != null) ? drawableLeft.getIntrinsicWidth() : 0;
// We only count the drawable padding if there is both an icon and text
int drawablePadding = ((textWidth > 0) && (drawableLeft != null)) ? getCompoundDrawablePadding() : 0;
// Adjust contents to center
float bodyWidth = textWidth + drawableWidth + drawablePadding;
int translate = (int) ((buttonContentWidth - bodyWidth));
if (translate != 0)
setPadding(translate, 0, translate, 0);
super.onDraw(canvas);
}
}
Upvotes: 4
Reputation: 1551
The accepted answer is not working for me, it fails if TextView width is match parent I did it using FrameLayout.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:background="#000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableStart="@drawable/ic_circle_check_white"
android:drawablePadding="10dp"
android:text="Header"
android:textColor="#fff"
android:textSize="14sp"/>
</FrameLayout>
Upvotes: 1
Reputation: 19
the best way is to use ConstraintLayout, to make the textview at the center of the layout and the width warp_content(don't use 0dp now) so that the drawable will follow the text.
<TextView
android:id="@+id/tv_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test"
android:drawableLeft="@drawable/you_drawable"
android:drawablePadding="5dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
Upvotes: -1
Reputation: 2308
If none of the above solutions did not work for you?. Then try below answer
Sample screen shot of the design.
For the above image please find the code below.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/my_card"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/bb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@color/gray"
android:orientation="horizontal"
android:weightSum="2">
<TextView
android:id="@+id/filter_tv"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_baseline_filter_list"
android:gravity="center|fill_horizontal"
android:paddingLeft="60dp"
android:text="Filter"
android:textAllCaps="false"
android:textStyle="normal" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_below="@+id/bb"
android:background="@color/gray" />
<TextView
android:id="@+id/sort_tv"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="center|center_horizontal"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_baseline_sort"
android:drawablePadding="20dp"
android:gravity="center|fill_horizontal"
android:paddingLeft="40dp"
android:text="Sort"
android:textAllCaps="false" />
</LinearLayout>
</android.support.v7.widget.CardView>
<View
android:layout_width="match_parent"
android:layout_height="0.9dp"
android:layout_below="@+id/my_card"
android:background="@color/gray" />
</RelativeLayout>
Upvotes: 1
Reputation: 81549
Remove the DrawableLeft and use a container FrameLayout.
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_gravity="center_vertical"
android:src="@drawable/image" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Text"
android:layout_gravity="center" />
</FrameLayout>
Upvotes: -2
Reputation: 61
> This line is important ->> android:gravity="start|center_vertical
<LinearLayout
android:layout_width="match_parent"
android:layout_margin="@dimen/marginplus2"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="@string/like"
android:gravity="start|center_vertical"
android:drawablePadding="@dimen/marginplus1"
android:drawableLeft="@drawable/ic_like"
android:layout_height="wrap_content" />
<TextView
android:layout_width="0dp"
android:layout_weight="1.5"
android:text="@string/comments"
android:drawablePadding="@dimen/marginplus1"
android:gravity="start|center_vertical"
android:drawableLeft="@drawable/ic_comment"
android:layout_height="wrap_content" />
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:text="@string/share"
android:drawablePadding="@dimen/marginplus1"
android:gravity="start|center_vertical"
android:drawableLeft="@drawable/ic_share"
android:layout_height="wrap_content" />
</LinearLayout>
Upvotes: 2
Reputation: 1010
Try following:
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:textAlignment="center" />
Upvotes: 5
Reputation: 533
One simple solution is to use a transparent image with the same size on the opposite side of the textview. In my example i copied my actual vector_image and changed the colors to be transparent.
<TextView
android:id="@+id/name"
style="@style/TextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableEnd="@drawable/ic_vector_caret_down_green"
android:drawableStart="@drawable/ic_vector_space_18"
android:gravity="center"
android:padding="12dp"
android:textColor="@color/green"/>
Upvotes: 1
Reputation: 1010
<TextView
android:id="@+id/distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:drawableLeft="@drawable/distance"
android:drawablePadding="10dp"
android:padding="10dp"
android:textAlignment="center"
android:textColor="#ffffff"
android:textSize="20sp" />
Upvotes: 0
Reputation: 5900
I've faced a similar problem. Solved it by using single TextView
with layout_width="wrap_content"
and layout_gravity="center"
parameters:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/some_drawable"
android:text="some text"
android:layout_gravity="center"
android:gravity="center"
/>
Upvotes: 6
Reputation: 10707
You can set the parent of the TextView as a RelativeLayout whose width is match_parent.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/edit_location_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/add_location_text_view"
android:gravity="start|center_vertical"
android:layout_centerHorizontal="true"
android:drawableStart="@android:drawable/ic_menu_edit"
android:text="Edit Location" />
</RelativeLayout>
Upvotes: 15
Reputation: 246
You can use android:gravity="center_vertical"
to center the text vertically with the image. Or it can be centered inside the textView using android:gravity="center"
.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:drawableLeft="@drawable/icon"
android:text="Your text here" />
Upvotes: 5
Reputation: 31
drawable is part of the TextView, so the textview's height will be the drawable's height if your text's height is smaller than drawable's height.
You can set TextView's gravity attribute to center_vertical, so the text will be in the center.
Upvotes: 1
Reputation: 1072
That work for me.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/trusted"
android:gravity="center"
android:text="@string/trusted"/>
</LinearLayout>
Upvotes: 4
Reputation: 29
simple as this.. try it..
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center|left"
android:drawableLeft="@drawable/icon"
android:text="something something" />
Upvotes: -1
Reputation: 406
I had same problem and I solved it with small changes in Textview,
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:drawableLeft="@drawable/search_red"
android:text="your text goes here"
/>
Upvotes: 1
Reputation: 34011
Though fragile, you can avoid the use of a wrapper Layout by setting a negative padding on the drawable:
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:drawableLeft="@drawable/icon"
android:drawablePadding="-20sp"
android:text="blah blah blah" />
You'll have to adjust the padding to the width of the drawable, but you're left with just a single TextView instead of an extra LinearLayout or etc.
Upvotes: 32
Reputation: 5326
The simplest way to obtain that is:
<RelativeLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/head" >
<ImageView
android:id="@+id/cat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:onClick="onClick"
android:layout_marginTop="10dp"
android:layout_alignParentLeft="true"
android:src="@drawable/btn_back_d" />
<TextView
android:id="@+id/TvTitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text=""
android:layout_centerHorizontal="true"
android:textColor="#000000"
android:textSize="20sp"/>
Where
Upvotes: -18
Reputation: 7605
use this way
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/White"
>
<RelativeLayout
android:id="@+id/rlheader"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:background="@color/HeaderColor"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Header_Title"
/>
<ImageView
android:id="@+id/ivSetting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:src="@drawable/setting" />
</RelativeLayout>
</RelativeLayout>
it look something like this snap of my demo project
Upvotes: 3
Reputation: 5784
u can set your header like this
<RelativeLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/head" >
<ImageView
android:id="@+id/cat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:onClick="onClick"
android:layout_marginTop="10dp"
android:src="@drawable/btn_back_" />
<RelativeLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<TextView
android:id="@+id/TvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:textColor="#000000"
android:textSize="20sp"/>
</RelativeLayout>
</RelativeLayout>
Just Give Hieght of Textview,image source as per your need
Upvotes: 0