Как иметь центр изображения и текста внутри кнопки
Я хочу отображать TEXT
и Icon
на кнопке.
+----------------------------+
| Icon TEXT |
+----------------------------+
Я пробовал с помощью
<Button
android:id="@+id/Button01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="40dip"
android:text="TEXT"
android:drawableLeft="@drawable/Icon" />
Но TEXT
и Icon
не находятся в центре.
Мой размер TEXT
варьируется, в соответствии с размером текста Icon
и TEXT
должен быть настроен на центр.
Как мне это сделать?
Ответы
Ответ 1
Вы можете подделать его, сделав более сложную компоновку, но я не уверен, стоит ли это. Здесь что-то я взломал вместе:
<?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="wrap_content">
<Button
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_alignTop="@+id/foreground"
android:layout_alignBottom="@id/foreground"
android:layout_alignRight="@id/foreground"
android:layout_alignLeft="@id/foreground"
android:onClick="clickedMe" />
<RelativeLayout
android:id="@id/foreground"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/button_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/hello" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/button_text"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:src="@drawable/icon" />
</RelativeLayout>
</RelativeLayout>
Там может быть более сжатый способ сделать это. Я часто пытаюсь заставить RelativeLayout делать то, что хочу. Обратите внимание, что вам нужно обратить внимание на z-порядок (кнопка должна появиться сначала на верхнем уровне RelativeLayout), и вам может потребоваться отрегулировать отступ, чтобы заставить ее выглядеть так, как вы хотите.
Ответ 2
Как и некоторые другие подходы, я считаю, что хорошим решением является расширение Button
и добавление недостающей функциональности путем переопределения метода onLayout
:
public class CenteredIconButton extends Button {
private static final int LEFT = 0, TOP = 1, RIGHT = 2, BOTTOM = 3;
// Pre-allocate objects for layout measuring
private Rect textBounds = new Rect();
private Rect drawableBounds = new Rect();
public CenteredIconButton(Context context) {
this(context, null);
}
public CenteredIconButton(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.buttonStyle);
}
public CenteredIconButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (!changed) return;
final CharSequence text = getText();
if (!TextUtils.isEmpty(text)) {
TextPaint textPaint = getPaint();
textPaint.getTextBounds(text.toString(), 0, text.length(), textBounds);
} else {
textBounds.setEmpty();
}
final int width = getWidth() - (getPaddingLeft() + getPaddingRight());
final Drawable[] drawables = getCompoundDrawables();
if (drawables[LEFT] != null) {
drawables[LEFT].copyBounds(drawableBounds);
int leftOffset =
(width - (textBounds.width() + drawableBounds.width()) + getRightPaddingOffset()) / 2 - getCompoundDrawablePadding();
drawableBounds.offset(leftOffset, 0);
drawables[LEFT].setBounds(drawableBounds);
}
if (drawables[RIGHT] != null) {
drawables[RIGHT].copyBounds(drawableBounds);
int rightOffset =
((textBounds.width() + drawableBounds.width()) - width + getLeftPaddingOffset()) / 2 + getCompoundDrawablePadding();
drawableBounds.offset(rightOffset, 0);
drawables[RIGHT].setBounds(drawableBounds);
}
}
}
Образец работает только для левого и правого рисунков, но может быть расширен для настройки верхних и нижних чертежей.
Ответ 3
Как насчет этого?
<?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:background="@color/lovely_color"
android:clickable="true"
android:onClick="clickHandler">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="no?"
android:textColor="@color/white"
android:layout_centerHorizontal="true"
android:drawableLeft="@drawable/lovely_icon"
android:drawablePadding="10dp"
android:padding="10dp"
android:gravity="center"
android:textSize="21sp"/>
</RelativeLayout>
Ответ 4
Это должно работать
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<TextView
android:id="@+id/button_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="hello" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dip"
/>
</LinearLayout>
Ответ 5
Как использовать SpannableString в качестве текста с ImageSpan?
Button myButton = ...
SpannableString ss = new SpannableString(" " + getString(R.string.my_button_text));
Drawable d = getResources().getDrawable(R.drawable.myIcon);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, DynamicDrawableSpan.ALIGN_BOTTOM);
ss.setSpan(span, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
myButton.setText(ss);
Ответ 6
Вы можете просто установить дополнение в зависимости от размера и размера кнопки:
Button button1 = null;
//initialize button….
ViewGroup.LayoutParams params = button1.getLayoutParams();
int btn1Width = ((int) (0.33 * (double)ecranWidth));
params.width = btn1Width;
button1.setLayoutParams(params);
button1.setPadding((btn1Width/2-9), 0, 0, 0);
//where (btn1Width/2-9) = size of button divided on 2 minux half size of icon…
Ответ 7
Легкий способ (хотя и не идеальный) - установить paddingRight на ту же ширину, что и значок.
Ответ 8
Это то, что я сделал... Это можно улучшить. Текст центрирован, а значок - влево. Поэтому они оба не сосредоточены как группа.
public class CustomButton extends Button
{
Rect r = new Rect();
private Drawable buttonIcon = null;
private int textImageSeparation = 10;
public CustomButton(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public CustomButton(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public CustomButton(Context context)
{
super(context);
}
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Drawable icon = getButtonIcon();
if(icon != null)
{
int drawableHeight = icon.getIntrinsicHeight();
int drawableWidth = icon.getIntrinsicWidth();
if(icon instanceof BitmapDrawable)
{
Bitmap bitmap = ((BitmapDrawable)icon).getBitmap();
drawableWidth = (int) AndroidScreenUtils.dipToPixels(bitmap.getWidth());
drawableHeight = (int) AndroidScreenUtils.dipToPixels(bitmap.getHeight());
}
else
{
drawableWidth = (int) AndroidScreenUtils.dipToPixels(icon.getIntrinsicWidth());
drawableHeight = (int) AndroidScreenUtils.dipToPixels(icon.getIntrinsicHeight());
}
float textWidth = getLayout().getPaint().measureText(getText().toString());
float left = ((getWidth() - textWidth) / 2) - getTextImageSeparation() - drawableWidth;
int height = getHeight();
int top = (height - drawableHeight) /2;
int right = (int) (left + drawableWidth);
int bottom = top + drawableHeight;
r.set((int) left, top, right, bottom);
icon.setBounds(r);
icon.draw(canvas);
}
}
private Drawable getButtonIcon()
{
return buttonIcon;
}
public void setButtonIcon(Drawable buttonIcon)
{
this.buttonIcon = buttonIcon;
}
private int getTextImageSeparation()
{
return textImageSeparation;
}
public void setTextImageSeparation(int dips)
{
this.textImageSeparation = (int) AndroidScreenUtils.dipToPixels(dips);
}
}
Ответ 9
<LinearLayout
style="@style/Sonnen.Raised.Button.Transparent.LightBlueBorder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:orientation="horizontal"
android:padding="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/refresh"
android:drawablePadding="10dp"
android:drawableStart="@drawable/refresh"
android:gravity="center"
android:text="@string/generic_error_button_text"
android:textColor="@color/dark_sky_blue"
android:textSize="20sp"/>
</LinearLayout>
Ответ 10
Я сделал пользовательский компонент для решения этой проблемы.
Класс компонента:
class CustomImageButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr, defStyleRes) {
init {
inflate(context, R.layout.custom_image_button, this)
// Load the styled attributes and set their properties
val typedArray = context.obtainStyledAttributes(
attrs,
R.styleable.CustomImageButton, defStyleAttr, 0
)
val src = typedArray?.getDrawable(R.styleable.CustomImageButton_cib_src)
val text = typedArray?.getText(R.styleable.CustomImageButton_cib_text)
val contentDescription = typedArray?.getText(R.styleable.CustomImageButton_cib_contentDescription)
ivIcon.setImageDrawable(src)
tvText.text = text
ivIcon.contentDescription = contentDescription
typedArray?.recycle()
}
}
Компонент XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:toos="http://schemas.android.com/tools"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="fill_parent"
android:layout_height="@dimen/button_height">
<Button
android:id="@+id/bClick"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_alignTop="@+id/foreground"
android:layout_alignBottom="@id/foreground"
android:layout_alignEnd="@id/foreground"
android:layout_alignStart="@id/foreground"/>
<RelativeLayout
android:id="@id/foreground"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="@color/textWhite"
toos:text="Some text to test"
toos:ignore="RelativeOverlap"/>
<ImageView
android:id="@+id/ivIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/tvText"
android:paddingTop="1dip"
android:paddingBottom="1dip"
android:src="@mipmap/some_image_to_test"
toos:ignore="ContentDescription"/>
</RelativeLayout>
</RelativeLayout>
Пример использования компонента:
<app.package.components.CustomImageButton
android:id="@+id/cibMyImageButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:cib_src="@mipmap/my_image_to_put_in_the_button"
app:cib_text="Some text to show in the button"
app:cib_contentDescription="icon description"/>
Ответ 11
android:layout_gravity="center_vertical|center_horizontal|center" >