Как я могу сжать drawable на кнопке?
Как я могу сделать drawable на кнопке меньше? Значок слишком большой, на самом деле выше, чем кнопка. Это код, который я использую:
<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>
чем выше он должен выглядеть, тем ниже он выглядит прямо сейчас.

Я пробовал это, но изображение отсутствует. : - (
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);
14 ответов:
вы должны использовать ImageButton и укажите изображение в
android:srcи setandroid:scaletypeдо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
я нашел очень простое и эффективное решение XML, которое не требует
ImageButtonсделайте рисованный файл для вашего изображения, как показано ниже, и используйте его для
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>вы можете установить размер изображения с
android:widthиandroid:heightсвойства.таким образом, вы могли бы по крайней мере получить тот же размер на разных экранах.
недостатком является то, что он не совсем похож на fitXY, который будет масштабировать ширину изображения, чтобы соответствовать X и масштабировать высоту изображения соответственно.
кнопки не изменяют размер своих внутренних изображений.
мое решение не требует обработки кода.
он использует макет с TextView и ImageView.
фон макета должен иметь красный 3d drawable.
возможно, Вам потребуется определить android: scaleType атрибут xml.
пример:
<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>кстати:
- подсчет различных значков разрешения может привести к предсказуемый пользовательский интерфейс (значок слишком большой или слишком маленький)
- текст в textview (включая кнопки) не заполняет компонент. Это проблема Android и я не знаю, как ее решить.
- вы можете использовать его как включить.
удачи
мой DiplayScaleHelper, который отлично работает:
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()); } } } } }
использовать ScaleDrawable как Абинав предложил.
проблема в том, что drawable не показывает тогда - это какая-то ошибка в ScaleDrawables. вам нужно будет изменить "уровень" программно. Это должно работать для каждой кнопки:
// 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]);
можно назвать
setBoundsна" составных " чертежах изменить размер изображения.попробуйте этот код для авторазмера drawable вашей кнопки:
DroidUtils.scaleButtonDrawables((Button) findViewById(R.id.ButtonTest), 1.0);определяется этой функцией:
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); } } } } } }имейте в виду, что это не может быть вызвано в
onCreate()активности, потому что высота и ширина кнопки там (пока) недоступны. Вызовите это наonWindowFocusChanged()или использовать данное решение для вызова функции.редактировать:
первое воплощение этой функции не работает правильно. Он использовал код userSeven7s для масштабирования изображения, но возвращает
ScaleDrawable.getDrawable()не работает (как и возвращениеScaleDrawable) для меня.модифицированный код использует
setBoundsобеспечить границы для изображения. Android вписывает изображение в эти границы.
Если вы хотите использовать 1 изображение и отображать его в разных размерах, вы можете использовать масштабирование drawable ( http://developer.android.com/guide/topics/resources/drawable-resource.html#Scale).
вы можете использовать различные размеры чертежей, которые используются с различными плотностями/размерами экрана и т. д. так что ваше изображение выглядит прямо на всех устройствах.
смотрите здесь: http://developer.android.com/guide/practices/screens_support.html#support
вы пробовали обернуть свое изображение в ScaleDrawable а затем использовать его в вашей кнопке?
вот функция, которую я создал для масштабирования векторные рисунки. Я использовал его для установки TextView compound drawable.
/** * 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; }
Я сделал собственный класс button для достижения этой цели.
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>использование в 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>
я попробовал методы этого поста, но не нашел ни одного из них настолько привлекательным. Мое решение состояло в том, чтобы использовать imageview и textview и выровнять imageview сверху и снизу к textview. Таким образом, я получил желаемый результат. Вот код:
<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>

Comments