Kau*_* NP 5 android android-layout
我在使用时偶然发现了这个问题custom Square Layout:通过扩展布局并覆盖其onMeasure()方法,使尺寸=两个中的较小者(高度或宽度).
以下是自定义布局代码:
public class CustomSquareLayout extends RelativeLayout{
public CustomSquareLayout(Context context) {
super(context);
}
public CustomSquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomSquareLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CustomSquareLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Width is smaller
if(widthMeasureSpec < heightMeasureSpec)
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
//Height is smaller
else
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
}
}
Run Code Online (Sandbox Code Playgroud)
自定义方形布局工作正常,直到自定义布局超出屏幕范围.应该有什么应该自动调整到屏幕尺寸,但不会发生.如下所示,CustomSquareLayout实际上延伸到屏幕下方(不可见).我期望的是onMeasure处理这个问题,并给出适当的测量结果.但事实并非如此.这里感兴趣的是,即使认为CustomSquareLayout行为奇怪,它的子布局都属于方形布局,总是放在左侧.
<!-- XML for above image -->
<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"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="300dp"
android:text="Below is the Square Layout"
android:gravity="center"
android:id="@+id/text"
/>
<com.app.application.CustomSquareLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/text"
android:background="@color/colorAccent" #PINK
android:layout_centerInParent="true"
android:id="@+id/square"
android:padding="16dp"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" #Note this
android:background="@color/colorPrimaryDark" #BLUE
>
</RelativeLayout>
</com.app.application.CustomSquareLayout>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
正常情况:( Textview在顶部)
以下是我引用的一些链接:
希望onMeasure在扩展布局时找到解决方案,使用或任何其他功能(这样即使某些扩展了自定义布局,Square属性仍然存在)
编辑2:我给出了一个偏好onMeasure()或者这样的功能,因为需要在之前(渲染之前)确定布局规格(尺寸).否则,在组件加载后更改尺寸很简单,但不要求.
您可以通过在布局后检查"方形"来强制方形视图.将以下代码添加到onCreate().
final View squareView = findViewById(R.id.square);
squareView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
squareView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
if (squareView.getWidth() != squareView.getHeight()) {
int squareSize = Math.min(squareView.getWidth(), squareView.getHeight());
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) squareView.getLayoutParams();
lp.width = squareSize;
lp.height = squareSize;
squareView.requestLayout();
}
}
});
Run Code Online (Sandbox Code Playgroud)
这将强制重新测量和布局具有替换的指定大小的方形视图MATCH_PARENT.不是非常优雅,但它的工作原理.
您还可以向自定义视图添加PreDraw侦听器.
onPreDraw
boolean onPreDraw()
在即将绘制视图树时要调用的回调方法.此时,树中的所有视图都已经过测量并给出了一个框架.客户端可以使用它来调整其滚动边界,甚至可以在绘制之前请求新的布局.
返回true以继续当前绘图传递,或返回false以取消.
在自定义视图中的每个构造函数中添加对初始化方法的调用:
private void init() {
this.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (getWidth() != getHeight()) {
int squareSize = Math.min(getWidth(), getHeight());
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
lp.width = squareSize;
lp.height = squareSize;
requestLayout();
return false;
}
return true;
}
});
}
Run Code Online (Sandbox Code Playgroud)
XML可以如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="300dp"
android:gravity="center"
android:text="Below is the Square Layout" />
<com.example.squareview.CustomSquareLayout
android:id="@+id/square"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/text"
android:background="@color/colorAccent"
android:padding="16dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/colorPrimaryDark" />
</com.example.squareview.CustomSquareLayout>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
830 次 |
| 最近记录: |