comment puis-je rendre le dessin sur un bouton plus petit? L'icône est trop grande, plus haute que le bouton. C'est le code que j'utilise:
<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>
La partie supérieure correspond à l'apparence souhaitée, la partie inférieure à la présentation actuelle.
J'ai essayé cela mais aucune image ne s'affiche. :-(
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);
Vous devez utiliser un ImageButton et spécifier l'image dans Android:src
et définir Android:scaletype
sur fitXY
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
J'ai trouvé une solution XML très simple et efficace qui ne nécessite pas ImageButton
Créez un fichier dessinable pour votre image comme ci-dessous et utilisez-le pour 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>
Vous pouvez définir la taille de l'image avec les propriétés Android:width
et Android:height
.
De cette façon, vous pouvez au moins obtenir la même taille pour différents écrans.
L'inconvénient est que ce n'est pas exactement comme fitXY qui redimensionne la largeur de l'image pour l'adapter à X et redimensionne la hauteur de l'image en conséquence.
Les boutons ne redimensionnent pas leurs images intérieures.
Ma solution ne nécessite pas de manipulation de code.
Il utilise une mise en page avec TextView et ImageView.
Le fond de la mise en page doit avoir le 3d rouge dessinable.
Vous devrez peut-être définir l'attribut Android: scaleType xml.
Exemple:
<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:
Bonne chance
Mon DiplayScaleHelper, cela fonctionne parfaitement:
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());
}
}
}
}
}
Utilisez un ScaleDrawable as Abhinav suggéré.
Le problème est que le dessin ne montre pas alors - c'est une sorte de bug dans ScaleDrawables. vous devrez changer le "niveau" par programmation. Cela devrait fonctionner pour chaque bouton:
// 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]);
Vous pouvez appeler setBounds
sur les tiroirs "composés" pour modifier la taille de l'image.
Essayez ce code pour redimensionner automatiquement le dessin de votre bouton:
DroidUtils.scaleButtonDrawables((Button) findViewById(R.id.ButtonTest), 1.0);
défini par cette fonction:
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);
}
}
}
}
}
}
Sachez que cela ne peut pas être appelé dans onCreate()
d'une activité, car la hauteur et la largeur des boutons ne sont pas (encore) disponibles. Appelez ceci sur onWindowFocusChanged()
ou utilisez cette solution pour appeler la fonction.
Édité:
La première incarnation de cette fonction n'a pas fonctionné correctement. Il a utilisé le code userSeven7s pour redimensionner l'image, mais renvoyer ScaleDrawable.getDrawable()
ne semble pas fonctionner (ne renvoie pas non plus ScaleDrawable
).
Le code modifié utilise setBounds
pour fournir les limites de l'image. Android correspond à l'image dans ces limites.
Si vous souhaitez utiliser une image et l'afficher dans une taille différente, vous pouvez utiliser une échelle dessinable ( http://developer.Android.com/guide/topics/resources/drawable-resource.html#Scale ).
Avez-vous essayé d’envelopper votre image dans ScaleDrawable puis de l’utiliser dans votre bouton?
Je le fais comme ci-dessous. Cela crée une image de taille 100x100 dans le bouton, indépendamment de l'image d'entrée.
drawable.bounds = Rect(0,0,100,100)
button.setCompoundDrawables(drawable, null, null, null)
Ne pas utiliser ScaleDrawable
non plus. Ne pas utiliser button.setCompoundDrawablesRelativeWithIntrinsicBounds()
a résolu mon problème, car cela semble utiliser des limites intrinsèques (taille de l'image source) au lieu des limites que vous venez de définir.
J'ai créé une classe de boutons personnalisée pour y parvenir.
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>
Utilisation en 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>
Voici la fonction que j'ai créée pour la mise à l'échelle de vecteurs dessinables. Je l'ai utilisé pour configurer TextView compoundable.
/**
* 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;
}
Vous pouvez utiliser différentes tailles de dessinables qui sont utilisées avec différentes densités/tailles d’écran, etc., afin que votre image corresponde bien à tous les appareils.
Voir ici: http://developer.Android.com/guide/practices/screens_support.html#support
C'est parce que vous n'avez pas setLevel
. après vous setLevel(1)
, il sera affiché comme vous voulez