como posso tornar o drawable em um botão menor? O ícone é muito grande, na verdade mais alto que o botão. Este é o código que estou usando:
<Button
android:background="@drawable/red_button"
android:drawableLeft="@drawable/s_vit"
android:id="@+id/ButtonTest"
android:gravity="left|center_vertical"
android:text="S-SERIES CALCULATOR"
android:textColor="@android:color/white"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:drawablePadding="10dp">
</Button>
A parte superior é como deve ser, e a parte inferior como deve ser agora.
Tentei fazer isso, mas não há imagem exibida. :-(
Resources res = getResources();
ScaleDrawable sd = new ScaleDrawable(res.getDrawable(R.drawable.s_vit), 0, 10f, 10f);
Button btn = (Button) findViewById(R.id.ButtonTest);
btn.setCompoundDrawables(sd.getDrawable(), null, null, null);
Respostas:
Você deve usar um ImageButton e especificar a imagem em
android:src
, e definirandroid:scaletype
comofitXY
Configurando drawable dimensionado no código
Drawable drawable = getResources().getDrawable(R.drawable.s_vit); drawable.setBounds(0, 0, (int)(drawable.getIntrinsicWidth()*0.5), (int)(drawable.getIntrinsicHeight()*0.5)); ScaleDrawable sd = new ScaleDrawable(drawable, 0, scaleWidth, scaleHeight); Button btn = findViewbyId(R.id.yourbtnID); btn.setCompoundDrawables(sd.getDrawable(), null, null, null); //set drawableLeft for example
fonte
drawable.setBounds(0, 0, drawable.getIntrinsicWidth()*0.5, drawable.getIntrinsicHeight()*0.5);
Eu encontrei uma solução XML muito simples e eficaz que não requer
ImageButton
Faça um arquivo drawable para sua imagem como abaixo e use-o para
android:drawableLeft
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/half_overlay" android:drawable="@drawable/myDrawable" android:width="40dp" android:height="40dp" /> </layer-list>
Você pode definir o tamanho da imagem com
android:width
eandroid:height
propriedades.Dessa forma, você pode obter pelo menos o mesmo tamanho para telas diferentes.
A desvantagem é que não é exatamente como fitXY, que dimensionaria a largura da imagem para caber em X e dimensionaria a altura da imagem de acordo.
fonte
android:drawableTop
adicionei o novo drawable. Não importa quais valores de largura / altura eu defina, ele me mostra o padrão.Os botões não redimensionam suas imagens internas.
Minha solução não requer manipulação de código.
Ele usa um layout com TextView e ImageView.
O plano de fundo do layout deve ter o drawable 3d vermelho.
Pode ser necessário definir o atributo xml android: scaleType .
Exemplo:
<LinearLayout android:id="@+id/list_item" android:layout_width="fill_parent" android:layout_height="50dp" android:padding="2dp" > <ImageView android:layout_width="50dp" android:layout_height="fill_parent" android:src="@drawable/camera" /> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:lines="1" android:gravity="center_vertical" android:text="Hello - primary" /> </LinearLayout>
BTW:
Boa sorte
fonte
Use um ScaleDrawable como Abhinav sugeriu.
O problema é que o drawable não aparece então - é algum tipo de bug no ScaleDrawables. você precisará alterar o "nível" programaticamente. Isso deve funcionar para todos os botões:
// Fix level of existing drawables Drawable[] drawables = myButton.getCompoundDrawables(); for (Drawable d : drawables) if (d != null && d instanceof ScaleDrawable) d.setLevel(1); myButton.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
fonte
Meu DiplayScaleHelper, que funciona perfeitamente:
import android.content.Context; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.ScaleDrawable; import android.widget.Button; public class DisplayHelper { public static void scaleButtonDrawables(Button btn, double fitFactor) { Drawable[] drawables = btn.getCompoundDrawables(); for (int i = 0; i < drawables.length; i++) { if (drawables[i] != null) { if (drawables[i] instanceof ScaleDrawable) { drawables[i].setLevel(1); } drawables[i].setBounds(0, 0, (int) (drawables[i].getIntrinsicWidth() * fitFactor), (int) (drawables[i].getIntrinsicHeight() * fitFactor)); ScaleDrawable sd = new ScaleDrawable(drawables[i], 0, drawables[i].getIntrinsicWidth(), drawables[i].getIntrinsicHeight()); if(i == 0) { btn.setCompoundDrawables(sd.getDrawable(), drawables[1], drawables[2], drawables[3]); } else if(i == 1) { btn.setCompoundDrawables(drawables[0], sd.getDrawable(), drawables[2], drawables[3]); } else if(i == 2) { btn.setCompoundDrawables(drawables[0], drawables[1], sd.getDrawable(), drawables[3]); } else { btn.setCompoundDrawables(drawables[0], drawables[1], drawables[2], sd.getDrawable()); } } } } }
fonte
Você pode chamar
setBounds
os drawables "compostos" para modificar o tamanho da imagem.Experimente este código para dimensionar automaticamente o drawable de seu botão:
DroidUtils.scaleButtonDrawables((Button) findViewById(R.id.ButtonTest), 1.0);
definido por esta função:
public final class DroidUtils { /** scale the Drawables of a button to "fit" * For left and right drawables: height is scaled * eg. with fitFactor 1 the image has max. the height of the button. * For top and bottom drawables: width is scaled: * With fitFactor 0.9 the image has max. 90% of the width of the button * */ public static void scaleButtonDrawables(Button btn, double fitFactor) { Drawable[] drawables = btn.getCompoundDrawables(); for (int i = 0; i < drawables.length; i++) { if (drawables[i] != null) { int imgWidth = drawables[i].getIntrinsicWidth(); int imgHeight = drawables[i].getIntrinsicHeight(); if ((imgHeight > 0) && (imgWidth > 0)) { //might be -1 float scale; if ((i == 0) || (i == 2)) { //left or right -> scale height scale = (float) (btn.getHeight() * fitFactor) / imgHeight; } else { //top or bottom -> scale width scale = (float) (btn.getWidth() * fitFactor) / imgWidth; } if (scale < 1.0) { Rect rect = drawables[i].getBounds(); int newWidth = (int)(imgWidth * scale); int newHeight = (int)(imgHeight * scale); rect.left = rect.left + (int)(0.5 * (imgWidth - newWidth)); rect.top = rect.top + (int)(0.5 * (imgHeight - newHeight)); rect.right = rect.left + newWidth; rect.bottom = rect.top + newHeight; drawables[i].setBounds(rect); } } } } } }
Esteja ciente de que isso pode não ser acionado em
onCreate()
uma atividade, porque a altura e a largura do botão (ainda) não estão disponíveis lá. Chame issoonWindowFocusChanged()
ou use esta solução para chamar a função.Editado:
A primeira encarnação desta função não funcionou corretamente. Ele usou o código userSeven7s para dimensionar a imagem, mas o retorno
ScaleDrawable.getDrawable()
não parece funcionar (nem retornarScaleDrawable
) para mim.O código modificado usa
setBounds
para fornecer os limites para a imagem. O Android se encaixa a imagem nesses limites.fonte
onCreate()
.Se você quiser usar 1 imagem e exibi-la em tamanho diferente, você pode usar o drawable em escala ( http://developer.android.com/guide/topics/resources/drawable-resource.html#Scale ).
fonte
Estou fazendo como abaixo. Isso cria uma imagem de tamanho 100x100 no botão independente da imagem de entrada.
drawable.bounds = Rect(0,0,100,100) button.setCompoundDrawables(drawable, null, null, null)
Não usando
ScaleDrawable
nenhum. Não usarbutton.setCompoundDrawablesRelativeWithIntrinsicBounds()
resolveu meu problema, já que parece usar limites intrínsecos (tamanho da imagem de origem) em vez dos limites que você acabou de definir.fonte
Você pode usar drawables de tamanhos diferentes que são usados com densidades / tamanhos de tela diferentes, etc. para que sua imagem fique correta em todos os dispositivos.
Veja aqui: http://developer.android.com/guide/practices/screens_support.html#support
fonte
Você tentou envolver sua imagem em um ScaleDrawable e usá-lo em seu botão?
fonte
ScaleDrawable
seria perfeito, mas simplesmente não funciona. Parece ter algo a ver com "níveis". Mais informações aqui (e algumas soluções alternativas que não são perfeitas): stackoverflow.com/questions/5507539/…Aqui está a função que criei para dimensionar drawables vetoriais. Usei-o para definir o drawable composto TextView.
/** * Used to load vector drawable and set it's size to intrinsic values * * @param context Reference to {@link Context} * @param resId Vector image resource id * @param tint If not 0 - colour resource to tint the drawable with. * @param newWidth If not 0 then set the drawable's width to this value and scale * height accordingly. * @return On success a reference to a vector drawable */ @Nullable public static Drawable getVectorDrawable(@NonNull Context context, @DrawableRes int resId, @ColorRes int tint, float newWidth) { VectorDrawableCompat drawableCompat = VectorDrawableCompat.create(context.getResources(), resId, context.getTheme()); if (drawableCompat != null) { if (tint != 0) { drawableCompat.setTint(ResourcesCompat.getColor(context.getResources(), tint, context.getTheme())); } drawableCompat.setBounds(0, 0, drawableCompat.getIntrinsicWidth(), drawableCompat.getIntrinsicHeight()); if (newWidth != 0.0) { float scale = newWidth / drawableCompat.getIntrinsicWidth(); float height = scale * drawableCompat.getIntrinsicHeight(); ScaleDrawable scaledDrawable = new ScaleDrawable(drawableCompat, Gravity.CENTER, 1.0f, 1.0f); scaledDrawable.setBounds(0,0, (int) newWidth, (int) height); scaledDrawable.setLevel(10000); return scaledDrawable; } } return drawableCompat; }
fonte
Usando o recurso "BATCH DRAWABLE IMPORT", você pode importar um tamanho personalizado dependendo do seu exemplo de requisito 20dp * 20dp
Agora, após a importação, use drawable_image importado como drawable_source para seu botão
É mais simples assim
fonte
É porque você não fez
setLevel
. depois de vocêsetLevel(1)
, será exibido como você quiserfonte
Usando a extensão Kotlin
val drawable = ContextCompat.getDrawable(context, R.drawable.my_icon) // or resources.getDrawable(R.drawable.my_icon, theme) val sizePx = 25 drawable?.setBounds(0, 0, sizePx, sizePx) // (left, top, right, bottom) my_button.setCompoundDrawables(drawable, null, null, null)
Eu sugiro criar uma função de extensão no TextView ( Button extends it ) para fácil reutilização.
button.leftDrawable(R.drawable.my_icon, 25) // Button extends TextView fun TextView.leftDrawable(@DrawableRes id: Int = 0, @DimenRes sizeRes: Int) { val drawable = ContextCompat.getDrawable(context, id) val size = context.resources.getDimensionPixelSize(sizeRes) drawable?.setBounds(0, 0, size, size) this.setCompoundDrawables(drawable, null, null, null) }
fonte
Experimentei as técnicas deste post, mas não achei nenhuma delas tão atraente. Minha solução foi usar uma visualização de imagem e uma visualização de texto e alinhar a parte superior e inferior da visualização de imagem com a visualização de texto. Assim obtive o resultado desejado. Aqui estão alguns códigos:
<RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="match_parent" android:layout_height="48dp" > <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignTop="@+id/textViewTitle" android:layout_alignBottom="@+id/textViewTitle" android:src="@drawable/ic_back" /> <TextView android:id="@+id/textViewBack" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textViewTitle" android:layout_alignBottom="@+id/textViewTitle" android:layout_toRightOf="@+id/imageView1" android:text="Back" android:textColor="@color/app_red" android:textSize="@dimen/title_size" /> </RelativeLayout>
fonte
Eu fiz uma classe de botão personalizado para conseguir isso.
CustomButton.java
public class CustomButton extends android.support.v7.widget.AppCompatButton { private Drawable mDrawable; public CustomButton(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.CustomButton, 0, 0); try { float mWidth = a.getDimension(R.styleable.CustomButton_drawable_width, 0); float mHeight = a.getDimension(R.styleable.CustomButton_drawable_width, 0); Drawable[] drawables = this.getCompoundDrawables(); Drawable[] resizedDrawable = new Drawable[4]; for (int i = 0; i < drawables.length; i++) { if (drawables[i] != null) { mDrawable = drawables[i]; } resizedDrawable[i] = getResizedDrawable(drawables[i], mWidth, mHeight); } this.setCompoundDrawables(resizedDrawable[0], resizedDrawable[1], resizedDrawable[2], resizedDrawable[3]); } finally { a.recycle(); } } public Drawable getmDrawable() { return mDrawable; } private Drawable getResizedDrawable(Drawable drawable, float mWidth, float mHeight) { if (drawable == null) { return null; } try { Bitmap bitmap; bitmap = Bitmap.createBitmap((int)mWidth, (int)mHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return drawable; } catch (OutOfMemoryError e) { // Handle the error return null; } } }
attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CustomButton"> <attr name="drawable_width" format="dimension" /> <attr name="drawable_height" format="dimension" /> </declare-styleable> </resources>
Uso em xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.MainActivity"> <com.example.CustomButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableTop="@drawable/ic_hero" android:text="Avenger" custom:drawable_height="10dp" custom:drawable_width="10dp" /> </RelativeLayout>
fonte
Canvas
emgetResizedDrawable
e desenhar nele, se você não vai fazer nada com ele? Toda a função pode ser reduzida apenas adrawable.setBounds(0, 0, mWidth, mHeight)
.