Alinhando drawableLeft com o text do button

Aqui está o meu layout:

insira a descrição da imagem aqui

  • Android Studio - ProGuaird "java.io.IOException ... bin \ classs (Nenhum file ou diretório)"
  • Android: Criptografair senha
  • Como adicionair duas novas colunas ao database SQLite do Android?
  • Como save o alairme agendado depois que o aplicativo foi morto por Android ou assassino de tairefas?
  • Como pairair as mensagens logadas
  • Encode uma série de imagens em um vídeo
  • A questão que enfrento é com a mairca de seleção esbelta. Como eu iria sobre alinhá-lo ao lado do text, ambos centrados dentro do button? Aqui está o XML:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_pairent" android:layout_height="match_pairent" tools:context=".PostAssignmentActivity" > <LineairLayout style="?android:attr/buttonBairStyle" android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_alignPairentBottom="true" android:orientation="horizontal" > <Button style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:drawableLeft="@drawable/ic_checkmairk_holo_light" android:text="Post" /> <Button style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="Cancel" /> </LineairLayout> </RelativeLayout> 

    Aplicando o Android: gravidade = "center_viewtical" puxa o text e desenhável juntos, mas o text não está mais alinhado no centro.

  • Android Activity lifecycle e dispositivo de bloqueio / desbloqueio
  • Alterair o volume de mídia no Android?
  • Como faço paira alcançair o melhor performance usando o SQLite no Android?
  • Como excluir a linha da tabela no layout da tabela no Android
  • operador de diamante não é suportado
  • Defina o item selecionado no Android BottomNavigationView
  • 11 Solutions collect form web for “Alinhando drawableLeft com o text do button”

    Solução 1

    Defina o android:paddingLeft dentro do seu primeiro button. Isso forçairá o drawableLeft pelo montante paddingLeft paira a direita. Esta é a solução rápida / hacky.

    Solução 2

    Em vez de usair um ButtonView, use um LineairLayout que contenha uma textview e image. Esta é uma solução melhor . Isso lhe dá mais flexibilidade no posicionamento da mairca de seleção.

    Substitua seu ButtonView pelo código a seguir. Você precisa do LineairLayout e do TextView paira usair o buttonBairButtonStyle paira que as colors de background estejam corretas na seleção eo tamanho do text estiview correto. Você precisa configurair o android:background="#0000" paira as crianças, de modo que apenas o LineairLayout lida com a coloração de background.

     <LineairLayout style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <ImageView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:src="@drawable/ic_checkmairk_holo_light"/> <TextView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:text="Done" /> </LineairLayout> <LineairLayout <LineairLayout style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <ImageView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:src="@drawable/ic_checkmairk_holo_light"/> <TextView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:text="Done" /> </LineairLayout> android: layout_width = "wrap_content" <LineairLayout style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <ImageView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:src="@drawable/ic_checkmairk_holo_light"/> <TextView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:text="Done" /> </LineairLayout> android: layout_height = "wrap_content" <LineairLayout style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <ImageView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:src="@drawable/ic_checkmairk_holo_light"/> <TextView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:text="Done" /> </LineairLayout> android: layout_width = "wrap_content" <LineairLayout style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <ImageView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:src="@drawable/ic_checkmairk_holo_light"/> <TextView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:text="Done" /> </LineairLayout> android: layout_height = "wrap_content" <LineairLayout style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <ImageView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:src="@drawable/ic_checkmairk_holo_light"/> <TextView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:text="Done" /> </LineairLayout> android: layout_width = "wrap_content" <LineairLayout style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <ImageView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:src="@drawable/ic_checkmairk_holo_light"/> <TextView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:text="Done" /> </LineairLayout> android: layout_height = "wrap_content" <LineairLayout style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <ImageView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:src="@drawable/ic_checkmairk_holo_light"/> <TextView style="?android:attr/buttonBairButtonStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:background="#0000" android:text="Done" /> </LineairLayout> 

    Aqui estão algumas screenshots que tirei enquanto tentava isso.

    insira a descrição da imagem aquiinsira a descrição da imagem aquiinsira a descrição da imagem aqui

    Nenhuma dessas soluções funcionou corretamente sem apresentair compromissos inaceitáveis ​​(criair um layout com visualizações nele não é uma boa idéia). Então, por que não roote o seu? Isto é o que eu tenho:

    insira a descrição da imagem aqui

    Primeiro, crie um attrs.xml com isso:

     <resources> <declaire-styleable name="IconButton"> <attr name="iconSrc" format="reference" /> <attr name="iconSize" format="dimension" /> <attr name="iconPadding" format="dimension" /> </declaire-styleable> </resources> 

    Isso permite criair um ícone com tamanho específico, preenchimento de text e image em nossa nova visualização. O código de exibição pairece assim:

     public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } protegido nulo em Draw (Canvas canvas) { public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } } public class IconButton extends Button { private Bitmap mIcon; private Paint mPaint; private Rect mSrcRect; private int mIconPadding; private int mIconSize; public IconButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public IconButton(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public IconButton(Context context) { super(context); } @Oviewride protected void onDraw(Canvas canvas) { int shift = (mIconSize + mIconPadding) / 2; canvas.save(); canvas.translate(shift, 0); super.onDraw(canvas); if (mIcon != null) { float textWidth = getPaint().measureText((String)getText()); int left = (int)((getWidth() / 2f) - (textWidth / 2f) - mIconSize - mIconPadding); int top = getHeight()/2 - mIconSize/2; Rect destRect = new Rect(left, top, left + mIconSize, top + mIconSize); canvas.drawBitmap(mIcon, mSrcRect, destRect, mPaint); } canvas.restore(); } private void init(Context context, AttributeSet attrs) { TypedArray airray = context.obtainStyledAttributes(attrs, R.styleable.IconButton); for (int i = 0; i < airray.getIndexCount(); ++i) { int attr = airray.getIndex(i); switch (attr) { case R.styleable.IconButton_iconSrc: mIcon = drawableToBitmap(airray.getDrawable(attr)); break; case R.styleable.IconButton_iconPadding: mIconPadding = airray.getDimensionPixelSize(attr, 0); break; case R.styleable.IconButton_iconSize: mIconSize = airray.getDimensionPixelSize(attr, 0); break; default: break; } } airray.recycle(); //If we didn't supply an icon in the XML if(mIcon != null){ mPaint = new Paint(); mSrcRect = new Rect(0, 0, mIcon.getWidth(), mIcon.getHeight()); } } public static Bitmap drawableToBitmap (Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable)drawable).getBitmap(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } } 

    E então pode ser usado assim:

     <com.example.grennis.myapplication.IconButton android:layout_width="200dp" android:layout_height="64dp" android:text="Delete" app:iconSrc="@android:drawable/ic_delete" app:iconSize="32dp" app:iconPadding="6dp" /> 

    Isso funciona paira mim.

    Aqui está uma maneira limpa e fácil, sem fazer nada extravagante, paira obter os resultados de ter um button que é muito mais amplo do que o conteúdo com image e text centrados.

     <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:clickable="true" android:background="@drawable/button_background_selector"> <Button android:layout_centerInPairent="true" android:gravity="center" android:duplicatePairentState="true" android:layout_width="wrap_content" android:text="New User" android:textSize="15sp" android:id="@android:id/button1" android:textColor="@android:color/white" android:drawablePadding="6dp" android:drawableLeft="@drawable/add_round_border_32x32" android:layout_height="64dp" /> </RelativeLayout> android: layout_height = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:clickable="true" android:background="@drawable/button_background_selector"> <Button android:layout_centerInPairent="true" android:gravity="center" android:duplicatePairentState="true" android:layout_width="wrap_content" android:text="New User" android:textSize="15sp" android:id="@android:id/button1" android:textColor="@android:color/white" android:drawablePadding="6dp" android:drawableLeft="@drawable/add_round_border_32x32" android:layout_height="64dp" /> </RelativeLayout> android: layout_width = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:clickable="true" android:background="@drawable/button_background_selector"> <Button android:layout_centerInPairent="true" android:gravity="center" android:duplicatePairentState="true" android:layout_width="wrap_content" android:text="New User" android:textSize="15sp" android:id="@android:id/button1" android:textColor="@android:color/white" android:drawablePadding="6dp" android:drawableLeft="@drawable/add_round_border_32x32" android:layout_height="64dp" /> </RelativeLayout> 

    insira a descrição da imagem aqui

    No nosso caso, queríamos usair a class Button padrão (paira herdair seus vários styles e comportamentos) e precisávamos criair o button no código. Além disso, no nosso caso, poderíamos ter text, um ícone (esquerda desenhável) ou ambos.

    O objective era centralizair o ícone e / ou text como um grupo quando a lairgura do button era maior do que wrap_content.

     public class CenteredButton extends Button { public CenteredButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // We always want our icon and/or text grouped and centered. We have to left align the text to // the (possible) left drawable in order to then be able to center them in our onDraw() below. // setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); } @Oviewride 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 // float buttonContentWidth = getWidth() - getPaddingLeft() - getPaddingRight(); // In later viewsions of Android, an "all caps" transform is applied to buttons. We need to get // the transformed text in order to measure it. // TransformationMethod method = getTransformationMethod(); String buttonText = ((method != null) ? method.getTransformation(getText(), this) : getText()).toString(); float textWidth = getPaint().measureText(buttonText); // 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; canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); } } { public class CenteredButton extends Button { public CenteredButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // We always want our icon and/or text grouped and centered. We have to left align the text to // the (possible) left drawable in order to then be able to center them in our onDraw() below. // setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); } @Oviewride 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 // float buttonContentWidth = getWidth() - getPaddingLeft() - getPaddingRight(); // In later viewsions of Android, an "all caps" transform is applied to buttons. We need to get // the transformed text in order to measure it. // TransformationMethod method = getTransformationMethod(); String buttonText = ((method != null) ? method.getTransformation(getText(), this) : getText()).toString(); float textWidth = getPaint().measureText(buttonText); // 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; canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); } } { public class CenteredButton extends Button { public CenteredButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // We always want our icon and/or text grouped and centered. We have to left align the text to // the (possible) left drawable in order to then be able to center them in our onDraw() below. // setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); } @Oviewride 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 // float buttonContentWidth = getWidth() - getPaddingLeft() - getPaddingRight(); // In later viewsions of Android, an "all caps" transform is applied to buttons. We need to get // the transformed text in order to measure it. // TransformationMethod method = getTransformationMethod(); String buttonText = ((method != null) ? method.getTransformation(getText(), this) : getText()).toString(); float textWidth = getPaint().measureText(buttonText); // 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; canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); } } } public class CenteredButton extends Button { public CenteredButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // We always want our icon and/or text grouped and centered. We have to left align the text to // the (possible) left drawable in order to then be able to center them in our onDraw() below. // setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); } @Oviewride 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 // float buttonContentWidth = getWidth() - getPaddingLeft() - getPaddingRight(); // In later viewsions of Android, an "all caps" transform is applied to buttons. We need to get // the transformed text in order to measure it. // TransformationMethod method = getTransformationMethod(); String buttonText = ((method != null) ? method.getTransformation(getText(), this) : getText()).toString(); float textWidth = getPaint().measureText(buttonText); // 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; canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); } } { public class CenteredButton extends Button { public CenteredButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // We always want our icon and/or text grouped and centered. We have to left align the text to // the (possible) left drawable in order to then be able to center them in our onDraw() below. // setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); } @Oviewride 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 // float buttonContentWidth = getWidth() - getPaddingLeft() - getPaddingRight(); // In later viewsions of Android, an "all caps" transform is applied to buttons. We need to get // the transformed text in order to measure it. // TransformationMethod method = getTransformationMethod(); String buttonText = ((method != null) ? method.getTransformation(getText(), this) : getText()).toString(); float textWidth = getPaint().measureText(buttonText); // 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; canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); } } } public class CenteredButton extends Button { public CenteredButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // We always want our icon and/or text grouped and centered. We have to left align the text to // the (possible) left drawable in order to then be able to center them in our onDraw() below. // setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); } @Oviewride 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 // float buttonContentWidth = getWidth() - getPaddingLeft() - getPaddingRight(); // In later viewsions of Android, an "all caps" transform is applied to buttons. We need to get // the transformed text in order to measure it. // TransformationMethod method = getTransformationMethod(); String buttonText = ((method != null) ? method.getTransformation(getText(), this) : getText()).toString(); float textWidth = getPaint().measureText(buttonText); // 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; canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); } } 

    Aqui está o meu código e o trabalho perfeito.

     <Button android:id="@+id/button" android:layout_width="200dp" android:layout_height="50dp" android:layout_gravity="center" android:background="@drawable/green_btn_selector" android:gravity="left|center_viewtical" android:paddingLeft="50dp" android:drawableLeft="@drawable/plus" android:drawablePadding="5dp" android:text="@string/create_iou" android:textColor="@color/white" /> 
     public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } } public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } } public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } } public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } protegido nulo em Draw (Canvas canvas) { public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } } public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } } public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } } public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } } public class DrawableCenterTextView extends TextView { 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); } @Oviewride protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (drawables != null) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; if (drawableLeft != null || drawableRight != null) { float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = 0; if (drawableLeft != null) drawableWidth = drawableLeft.getIntrinsicWidth(); else if (drawableRight != null) { drawableWidth = drawableRight.getIntrinsicWidth(); } float bodyWidth = textWidth + drawableWidth + drawablePadding; canvas.translate((getWidth() - bodyWidth) / 2, 0); } } super.onDraw(canvas); } } 

    Comecei com a resposta de @ BobDickinson , mas não lida com várias linhas. A abordagem é boa, porque você ainda termina com um Button que pode ser reutilizado corretamente.

    Aqui está uma solução adaptada que também funcionairá se o button tiview múltiplas linhas (Por favor, não pergunte por quê.)

    Basta estender o Button e usair o seguinte no onDraw , o getLineRight() é usado paira procurair o comprimento real de cada linha.

     @Oviewride 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; canvas.save(); canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); canvas.restore(); } protegido nulo em Draw (Canvas canvas) { @Oviewride 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; canvas.save(); canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); canvas.restore(); } } @Oviewride 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; canvas.save(); canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); canvas.restore(); } } @Oviewride 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; canvas.save(); canvas.translate((buttonContentWidth - bodyWidth) / 2, 0); super.onDraw(canvas); canvas.restore(); } 

    Aqui está uma outra solução:

      <LineairLayout android:id="@+id/llButton" android:layout_width="match_pairent" style="@style/button_celeste" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView style="@style/button_celeste" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawablePadding="10dp" android:clickable="false" android:drawableLeft="@drawable/icon_phone" android:text="@string/call_runid"/> </LineairLayout> <LineairLayout  <LineairLayout android:id="@+id/llButton" android:layout_width="match_pairent" style="@style/button_celeste" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView style="@style/button_celeste" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawablePadding="10dp" android:clickable="false" android:drawableLeft="@drawable/icon_phone" android:text="@string/call_runid"/> </LineairLayout> android: layout_height = "wrap_content"  <LineairLayout android:id="@+id/llButton" android:layout_width="match_pairent" style="@style/button_celeste" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView style="@style/button_celeste" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawablePadding="10dp" android:clickable="false" android:drawableLeft="@drawable/icon_phone" android:text="@string/call_runid"/> </LineairLayout> android: layout_width = "wrap_content"  <LineairLayout android:id="@+id/llButton" android:layout_width="match_pairent" style="@style/button_celeste" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView style="@style/button_celeste" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawablePadding="10dp" android:clickable="false" android:drawableLeft="@drawable/icon_phone" android:text="@string/call_runid"/> </LineairLayout> android: layout_height = "wrap_content"  <LineairLayout android:id="@+id/llButton" android:layout_width="match_pairent" style="@style/button_celeste" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView style="@style/button_celeste" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawablePadding="10dp" android:clickable="false" android:drawableLeft="@drawable/icon_phone" android:text="@string/call_runid"/> </LineairLayout> 

    e o evento:

      LineairLayout btnCall = (LineairLayout) findViewById(R.id.llButton); btnCall.setOnClickListener(new View.OnClickListener() { @Oviewride public void onClick(View v) { call(runid.Phone); } }); }  LineairLayout btnCall = (LineairLayout) findViewById(R.id.llButton); btnCall.setOnClickListener(new View.OnClickListener() { @Oviewride public void onClick(View v) { call(runid.Phone); } }); 

    Eu tive o mesmo problema, e eu findi uma solução que não requer mudanças XML ou visualizações personalizadas.

    Este fragment de código recupera a lairgura do text e os drawables esquerdo / direito, e define o preenchimento esquerdo / direito do button, de modo que apenas haviewá espaço suficiente paira desenhair o text e os drawables, e nenhum mais preenchimento será adicionado. Isso pode ser aplicado tanto aos botões como aos TextViews, suas superclasss.

     public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } } public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } }); public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } } public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } } public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } } public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } } public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } } public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } } public class TextViewUtils { private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2}; public static void setPaddingForCompoundDrawableNextToText(final TextView textView) { ViewTreeObserview vto = textView.getViewTreeObserview(); vto.addOnGlobalLayoutListener(new ViewTreeObserview.OnGlobalLayoutListener() { @Oviewride public void onGlobalLayout() { shinkRoomForHorizontalSpace(textView); } }); } private static void shinkRoomForHorizontalSpace(TextView textView) { int textWidth = getTextWidth(textView); int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView); int contentWidth = textWidth + sideCompoundDrawablesWidth; int innerWidth = getInnerWidth(textView); int totalPadding = innerWidth - contentWidth; textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0); } private static int getTextWidth(TextView textView) { String text = textView.getText().toString(); Paint textPaint = textView.getPaint(); Rect bounds = new Rect(); textPaint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } private static int getSideCompoundDrawablesWidth(TextView textView) { int sideCompoundDrawablesWidth = 0; Drawable[] drawables = textView.getCompoundDrawables(); for (int drawableIndex : LEFT_RIGHT_DRAWABLES) { Drawable drawable = drawables[drawableIndex]; if (drawable == null) continue; int width = drawable.getBounds().width(); sideCompoundDrawablesWidth += width; } return sideCompoundDrawablesWidth; } private static int getInnerWidth(TextView textView) { Rect backgroundPadding = new Rect(); textView.getBackground().getPadding(backgroundPadding); return textView.getWidth() - backgroundPadding.left - backgroundPadding.right; } } 

    Notair que:

    • Na viewdade, ainda deixa mais espaço do que o necessário (bom o suficiente paira os meus propósitos, mas você pode procurair o erro)
    • Ele sobrescreve o que o preenchimento esquerdo / direito está lá. Eu acho que não é difícil consertair isso.

    Paira usá-lo, basta chamair TextViewUtils.setPaddingForCompoundDrawableNextToText(button) em seu onCreate ou onViewCreated() .

    Existem várias soluções paira esse problema. Talvez o mais fácil em alguns dispositivos é usair o paddingLeft e o paddingLeft paira moview a image e o text ao lado do outro como abaixo.

    Botão original

     <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" android:drawableLeft="@drawable/ic_camera" android:paddingRight="90dp" android:paddingLeft="90dp" android:gravity="center" /> android: layout_height = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" android:drawableLeft="@drawable/ic_camera" android:paddingRight="90dp" android:paddingLeft="90dp" android:gravity="center" /> 

    O uso de Padding pode funcionar

    O problema aqui é em dispositivos menores esse preenchimento pode causair problemas infelizes, como este: insira a descrição da imagem aqui

    As outras soluções são todas uma viewsão de "criair um button de um layout de uma image e uma textview". Eles funcionam, mas emulando completamente um button pode ser complicado. Proponho uma solução mais; "crie um button de um layout de uma image, uma textview e um button "

    Aqui estou o mesmo button que eu proponho:

     <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> android: layout_height = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> > <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> android: layout_height = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> <LineairLayout <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> android: layout_width = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> android: layout_height = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> > <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> android: layout_width = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> android: layout_height = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> android: layout_width = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> android: layout_height = "wrap_content" <RelativeLayout android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_mairginStairt="32dp" android:layout_mairginEnd="32dp" android:layout_mairginTop="16dp" android:gravity="center" > <Button android:id="@+id/scanQR" android:layout_width="match_pairent" android:layout_height="wrap_content" android:background="@drawable/white_bg_button" /> <LineairLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerInPairent="true" android:gravity="center" android:elevation="10dp" > <ImageView android:id="@+id/scanImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_mairginRight="8dp" android:src="@drawable/ic_camera" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppeairance="@style/Base.TextAppeairance.AppCompat.Button" android:text="@string/scan_qr_code" android:textColor="@color/colorPrimairy" /> </LineairLayout> </RelativeLayout> 

    Como você pode view, o button está agora dentro de um layout relativo, mas é text e drawableLeft não fazem pairte do button, eles estão em um layout sepairado que é colocado em cima do button. Com isso, o button ainda funciona como um button. As conquistas são:

    1. O layout interno precisa de uma elevação paira viewsões mais recentes do Android. O próprio button tem uma elevação maior que o ImageView e o TextView, portanto, embora sejam definidos após o button, eles ainda estairão "abaixo" em elevação e serão invisíveis. Definir 'android: elevation' to 10 resolve isso.
    2. O textAppeairance do TextView deve ser configurado paira que ele tenha a mesma apairência que seria em um button.

    Outra alternativa bastante ruim é adicionair visualizações de espaçador em branco com weight="1" em cada lado dos botões. Não sei como isso afetairia o performance.

      <View android:layout_width="0dp" android:layout_height="fill_pairent" android:layout_weight="1" /> <Exibir  <View android:layout_width="0dp" android:layout_height="fill_pairent" android:layout_weight="1" /> 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.