在使用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);

    }
}

自定义正方形布局可以正常工作,直到自定义布局的超出屏幕的绑定(bind)为止。不会自动调整以适应屏幕尺寸的内容。如下所示,CustomSquareLayout实际上延伸到屏幕下方(不可见)。我期望的是onMeasure处理此问题,并给出适当的度量。但事实并非如此。 这里值得关注的注意点是,即使CustomSquareLayout表现得很奇怪,它的子布局也都落在始终位于左侧的Square布局下。

android - 自定义方形布局无法正常工作-LMLPHP
<!-- 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>

正常情况:(Textview位于顶部)

android - 自定义方形布局无法正常工作-LMLPHP

以下是我引用的一些链接:
  • Custom Square LinearLayout. How?
  • Simple way to do dynamic but square layout

  • 希望找到解决方案,当扩展布局时使用onMeasure或任何其他函数(以便即使某些扩展了“自定义布局”,Square属性仍保留)

    编辑1:为进一步说明,第一种情况的预期结果显示为android - 自定义方形布局无法正常工作-LMLPHP

    编辑2:我偏爱onMeasure()或此类函数,因为它们需要更早(在渲染之前)确定布局规范(尺寸)。否则,在组件加载后更改尺寸很简单,但不是必需的。

    最佳答案

    您可以通过在布局后检查“方形度”来强制显示方形 View 。将以下代码添加到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();
            }
        }
    });
    
    这将强制以指定大小替换MATCH_PARENT的正方形 View 的重新测量和布局。虽然不是非常优雅,但是可以正常工作。
    android - 自定义方形布局无法正常工作-LMLPHP
    您还可以在自己的自定义 View 中添加 PreDraw listener

    在自定义 View 的每个构造函数中添加对初始化方法的调用:
    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;
            }
        });
    }
    
    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>
    

    关于android - 自定义方形布局无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46056093/

    10-09 05:50
    查看更多