如何在按下状态时移动button文本

我做了一个button的自定义背景,也为不同的button状态。 但是现在我明白了我无法理解的一点。

当button处于正常状态时,看起来就好了。 但是当我按下button时,我需要将文本向下移动几个像素,因为button背景图像正在移动(实际上它感觉像在图像上移动,因为首先在button下面有边框,当它处于按下状态时,这个边界消失)。 请看下面的图片。

当按下状态button时,如何移动button中的button文字? (可能填充某种方式或布局button的自定义)

在这里输入图像说明

Solutions Collecting From Web of "如何在按下状态时移动button文本"

我没有自己尝试,但如果你使用九补丁作为背景可绘制两种状态,那么你应该考虑设置适当的填充框在按下状态drawable。 在这里看到细节。

设置填充9补丁不适合我。 在触摸监听器中设置填充是很麻烦的,在任何地方使用button都会乱码。

我去了Button子类,结果是合理的。 在我的情况下,我想抵消图标( drawableLeft )和文字1px左侧和1px下来。

子类button小部件:

 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情况下调整填充

  • 增加顶部和左侧填充很重要, 同时减less底部和右侧填充。 所以内容区域的大小保持不变,内容区域有效地移动。

您可以在视图上使用填充。 您可以像添加一个OnTouchListener到button或视图

 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; } }); 

当button被按下时,ontouchlistener会让你知道。

PēterisCaune答案比重写setPressed()更糟糕。 但是直到你在ICS或者更低版本的设备上testing你的应用程序,并添加button作为列表查看项目,你才能一直使用setPressed。 为了实现这一点,我改进了我的button的类:

 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