我想我可能在layout_margin
处理按钮的方式上发现了一个错误。可以归结为测量时不考虑按钮边距。结果,他们的父母ViewGroup
测量自己略微过小。当最终绘制按钮时,没有足够的空间,他们被迫包装或椭圆化他们的文本。即使按钮的祖父母中有足够的空间让按钮的父母变大,也会发生这种情况。无论我在按钮的样式中设置layout_margin
还是在按钮本身上设置layout_margin
,都存在问题。我不知道这是否会影响其他类型的观点。
这是一个已知问题吗?除了不在按钮上使用边距之外,是否存在任何解决方法?(或者我只是做错了什么?)
我在大约一年前发现unanswered question表示layout_margin
在自定义按钮样式中根本不起作用。它实际上对我来说就像问题的提问者所期望的那样,至少在按钮确实具有指定余量的意义上。所以也许谷歌最近“修复”了它并且修复忽略了一些东西。
此片段布局演示了此问题。它在编辑器中看起来很好。指定的按钮样式的3dp
为<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<EditText
android:id="@+id/userField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="8"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:hint="@string/hint_user" />
<EditText
android:id="@+id/passwordField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/userField"
android:layout_alignLeft="@id/userField"
android:layout_alignRight="@id/userField"
android:inputType="textPassword"
android:fontFamily="sans-serif"
android:hint="@string/hint_password" />
<Button
android:id="@+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/userField"
android:layout_centerVertical="true"
style="@style/button_blue"
android:text="@string/login" />
</RelativeLayout>
。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/fragment"
android:name="com.example.MyFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
tools:layout="@layout/fragment_login" />
</RelativeLayout>
但是当这个片段放在另一个布局中时,片段的宽度显然是不正确的。
\u00A0
文本包含中间词,因为我在按钮文本中使用了不间断的空格(layout_margin
)。在正常空间中,它包裹在单词边界。如果我从按钮样式中删除<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.chalcodes.marginbug.MainActivity" >
<RelativeLayout
android:id="@+id/buttonLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:layout_toRightOf="@id/button1"
android:text="Button" />
</RelativeLayout>
</RelativeLayout>
,问题就会消失。
编辑:这是一个展示问题的独立布局。问题始终出现在WYSIWYG编辑器SDK 21中。在实际设备上,错误表现在2.3.6和4.0.4而不是4.4.1或5.0.1。
{{1}}
编辑2:跟进corsair992的评论,我将AS更新到最新版本(1.2 beta 3)并粘贴了我上面的独立示例。这个 重现了这个问题。但奇怪的是,当我将预览方向从纵向更改为横向时,问题就消失了。更奇怪的是,当我回到肖像时,问题没有回来!如果我重新启动AS,它会在第一次时错误地渲染我的布局,然后在旋转后正确渲染它。 Eclipse总是错误地渲染布局。
我注意到Android Studio的WYSIWYG编辑器比Eclipse更加积极地缓存事物。在Eclipse中,我可以立即看到对自定义视图的更改,但是在一个干净的&amp; amp;之后,AS固执地依赖于自定义视图的旧渲染。重建,甚至重启后。所以也许AS正在缓存一些关于布局的信息,这有助于它第二次正确渲染。但也许这只是掩盖了这个错误。
答案 0 :(得分:0)
我实际上创建了自己的解决方法,似乎解决了这个问题。但这只是一个概念证明。这个问题似乎没有影响4.4或5.0,虽然我发誓我已经看到它在我的4.4设备上发生了某些时候。为了使解决方法可以部署,我必须有条件地激活它。
我会将奖金奖励给能够向我展示此问题影响的Android版本(如果是已知问题)或在运行时检测设备是否受到影响的聪明方法的人。
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.Button;
public class WorkaroundButton extends Button {
public WorkaroundButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams();
final int width = getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
final int height = getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
setMeasuredDimension(width, height);
}
}
答案 1 :(得分:0)
我能够重现这一点的唯一方法就是选择&#34; Wear Square&#34;编辑器中的虚拟设备。
似乎问题不在于保证金。正如您在上图和第一次编辑的图像中看到的那样,边距确实是强制执行的。
问题在于边距大小,android:layout_toRightOf
属性和RelativeLayout缺少&#34;权重&#34; LinearLayouts中的概念。
不使用android:layout_toRightOf
,而是使用为其子项指定权重值的水平LinearLayout,或使用左侧按钮上的android:layout_alignParentLeft="true"
和右侧按钮上的android:layout_alignParentRight="true"
。