Ответ 1
Я сам не пробовал, но если вы используете девять патчей в качестве фона, пригодного для обоих состояний, тогда вы должны рассмотреть возможность установки соответствующего поля заполнения в нажатом состоянии. Подробнее см. здесь.
Я создал пользовательский фон для кнопки, а также для разных состояний кнопок. Но теперь я понял, что не могу понять.
Когда кнопка находится в нормальном состоянии, она выглядит просто отлично. Но когда я нажимаю кнопку, мне нужно переместить текст на несколько пикселей, потому что перемещение фонового изображения кнопки (на самом деле это похоже на перемещение по изображению, потому что сначала там граничит под кнопкой, а когда она в нажатом состоянии, тогда эта граница исчезает). См. Рисунок ниже.
Как перемещать текст кнопок в кнопке при нажатии кнопки? (возможно, как-то заполнение или макет для кнопки)
Я сам не пробовал, но если вы используете девять патчей в качестве фона, пригодного для обоих состояний, тогда вы должны рассмотреть возможность установки соответствующего поля заполнения в нажатом состоянии. Подробнее см. здесь.
Настройка прогона в 9-патче не работала для меня. Настройка прокладки в сенсорных прослушивателях беспорядочна, будет использоваться код подстилки в любом месте.
Я пошел с подклассом Button
, и он оказался достаточно аккуратным. В моем случае, я хотел смещать значок (drawableLeft
) и текст 1px слева и 1px вниз.
Виджет кнопки с подклассом:
package com.myapp.widgets;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;
import com.myapp.R;
public class OffsetButton extends Button {
public OffsetButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public OffsetButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public OffsetButton(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean value = super.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
setBackgroundResource(R.drawable.btn_normal);
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
setBackgroundResource(R.drawable.btn_pressed);
setPadding(getPaddingLeft() + 1, getPaddingTop() + 1, getPaddingRight() - 1,
getPaddingBottom() - 1);
}
return value;
}
}
И используйте его в макете, как это:
<com.myapp.widgets.OffsetButton
android:text="@string/click_me"
android:drawableLeft="@drawable/icon_will_be_offset_too_thats_good" />
Несколько заметок:
Я не использовал StateListDrawable
для фона и вместо этого переключал фонов в код. Когда я попытался использовать StateListDrawable
, была бы небольшая пауза между изменением дополнений и изменением фона. Это выглядело не очень хорошо.
Настройка фонового сброса заполнения, поэтому не нужно настраивать дополнение в ACTION_UP
case
Было важно увеличить верхнее и левое заполнение и в то же время уменьшить нижнее и правое заполнение. Таким образом, размер области содержимого остается прежним, а область содержимого фактически просто сдвигается.
Вы можете использовать прописку в представлении. Вы можете добавить OnTouchListener к кнопке или просмотреть, например
viewF.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction == MotionEvent.ACTION_UP) {
//set your padding
} else if (event.getAction == MotionEvent.ACTION_DOWN){
//set your padding
}
return true;
}
});
Функция ontouchlistener сообщит вам, когда кнопка нажата, а не.
Ответ Pēteris Caune работает хуже, чем переопределение setPressed(). Но всегда в порядке с setPressed, пока вы не протестируете свое приложение на ICS или более низком устройстве и не добавите кнопку в качестве элемента списка. Чтобы архивировать это, я улучшил класс своей кнопки:
public class OffsetButton extends Button {
private static final int OFFSET_IN_DP = 6;
private int offset_in_px;
private boolean wasPressed = false;
private Integer[] defaultPaddings;
public OffsetButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}
public OffsetButton(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public OffsetButton(Context context) {
super(context);
initView();
}
private void initView() {
offset_in_px = (int) DisplayUtil.convertDpToPixel(OFFSET_IN_DP);
}
@Override
public void setPressed(boolean pressed) {
if (pressed && !wasPressed) {
changePaddings();
}
if (!pressed && wasPressed) {
resetPaddings();
}
super.setPressed(pressed);
}
private void changePaddings() {
defaultPaddings = new Integer[]{getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom()};
setPadding(getPaddingLeft(), getPaddingTop() + offset_in_px, getPaddingRight(), getPaddingBottom() - offset_in_px);
wasPressed = true;
}
private void resetPaddings() {
setPadding(defaultPaddings[0], defaultPaddings[1], defaultPaddings[2], defaultPaddings[3]);
wasPressed = false;
}
@Override
public boolean performClick() {
resetPaddings();
return super.performClick();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isEnabled())
{
if (event.getAction() == MotionEvent.ACTION_DOWN && !wasPressed) {
changePaddings();
} else if (event.getAction() == MotionEvent.ACTION_UP && wasPressed) {
resetPaddings();
}
}
return super.onTouchEvent(event);
}
}
это может сработать:
setPadding(left, top, right, bottom); // Normal
setPadding(left, top + x, right, bottom - x); // Pressed