我为按钮和不同的按钮状态创建了自定义背景。但是现在我达到了一个我无法理解的地步。
当按钮处于正常状态时,它看起来很好。但是当我按下按钮时,我需要将文本向下移动几个像素,因为按钮背景图像移动(实际上感觉就像它在图像上移动一样,因为首先按钮下面有边框,当它处于按下状态时,此边框消失)。请看下面的图片。
按下按钮状态时,如何移动按钮中的按钮文本? (可能以某种方式填充或按钮的布局自定义)
答案 0 :(得分:5)
在9补丁中设置填充对我来说不起作用。 在触摸侦听器中设置填充是混乱的,在使用按钮的任何地方都会丢失代码。
我选择了子类Button
,结果显得相当整洁。在我的情况下,我想偏移图标(drawableLeft
)和文本1px左和1px向下。
Subclassed按钮小部件:
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
案例中调整填充
增加顶部和左侧填充非常重要,同时减少底部和右侧填充。因此内容区域的大小保持不变,内容区域实际上只是移位。
答案 1 :(得分:4)
我自己没有尝试,但是如果你使用九个补丁作为两种状态的背景可绘制,那么你应该考虑在压缩状态下绘制适当的填充框。详情请见here。
答案 2 :(得分: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会在按下按钮时让你知道,而不是。
答案 3 :(得分:1)
PēterisHaune答案比覆盖setPressed()更糟糕。但是对于在ICS或更低级别的设备上测试您的应用程序并添加按钮作为listview项目,请使用setPressed进行操作。 为了实现这一点,我改进了我的按钮课程:
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);
}
}
答案 4 :(得分:0)
这可能会起作用:
setPadding(left, top, right, bottom); // Normal
setPadding(left, top + x, right, bottom - x); // Pressed