Подтвердить что ты не робот

Как перемещать текст кнопок при нажатии

Я создал пользовательский фон для кнопки, а также для разных состояний кнопок. Но теперь я понял, что не могу понять.

Когда кнопка находится в нормальном состоянии, она выглядит просто отлично. Но когда я нажимаю кнопку, мне нужно переместить текст на несколько пикселей, потому что перемещение фонового изображения кнопки (на самом деле это похоже на перемещение по изображению, потому что сначала там граничит под кнопкой, а когда она в нажатом состоянии, тогда эта граница исчезает). См. Рисунок ниже.

Как перемещать текст кнопок в кнопке при нажатии кнопки? (возможно, как-то заполнение или макет для кнопки)

enter image description here

4b9b3361

Ответ 1

Я сам не пробовал, но если вы используете девять патчей в качестве фона, пригодного для обоих состояний, тогда вы должны рассмотреть возможность установки соответствующего поля заполнения в нажатом состоянии. Подробнее см. здесь.

Ответ 2

Настройка прогона в 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

  • Было важно увеличить верхнее и левое заполнение и в то же время уменьшить нижнее и правое заполнение. Таким образом, размер области содержимого остается прежним, а область содержимого фактически просто сдвигается.

Ответ 3

Вы можете использовать прописку в представлении. Вы можете добавить 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 сообщит вам, когда кнопка нажата, а не.

Ответ 4

Ответ 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);
    }
}

Ответ 5

это может сработать:

setPadding(left, top, right, bottom); // Normal
setPadding(left, top + x, right, bottom - x); // Pressed