Android-如何缩放视图以适应全屏应用程序';它的高度和宽度完美吗?

Android-如何缩放视图以适应全屏应用程序';它的高度和宽度完美吗?,android,Android,如果你有一个计算器应用程序,你想写一个布局,看起来像,你如何缩放按钮和显示,以适应所有屏幕大小 我研究过的想法: 通过编程计算每个组件的高度和宽度。通过编程方式创建视图给了您最大的能力,但这并不理想。我更喜欢用XML编写UI 使用布局权重嵌套线性布局。这是可行的,但lint会给出性能警告,因为我正在嵌套权重。最重要的是,它不考虑文本大小。因此,在小屏幕上,文本被切掉。相反,在大屏幕上,文本太小 编辑: 3.使用具有嵌套权重的表格布局。考虑到这些扩展自LinearLayout,我假设缺少lint警

如果你有一个计算器应用程序,你想写一个布局,看起来像,你如何缩放按钮和显示,以适应所有屏幕大小

我研究过的想法:

  • 通过编程计算每个组件的高度和宽度。通过编程方式创建视图给了您最大的能力,但这并不理想。我更喜欢用XML编写UI


  • 使用布局权重嵌套线性布局。这是可行的,但lint会给出性能警告,因为我正在嵌套权重。最重要的是,它不考虑文本大小。因此,在小屏幕上,文本被切掉。相反,在大屏幕上,文本太小

  • 编辑: 3.使用具有嵌套权重的表格布局。考虑到这些扩展自LinearLayout,我假设缺少lint警告是不相关的,这仍然会导致性能损失,对吗

    有更好的办法吗?我觉得我错过了一些明显的东西

    编辑2: 如果有人对此解决方案感兴趣,我已经创建了一个自定义布局(如raphw建议的),并将在此处发布源代码:

    <LinearLayout android:layout_width="match_parent" android:layout_height="100dp">
        <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="A" />
        <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="B" />    
        <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="C" />
    </LinearLayout>
    
    <LinearLayout android:layout_width="match_parent" android:layout_height="100dp">
        <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="A" />
        <Button android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" android:text="B" />    
        <Button android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" android:text="C" />
    </LinearLayout>
    
    EvenSpaceGridLayout.java:

    package com.example.evenspacegridlayout;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class EvenSpaceGridLayout extends ViewGroup {
    
        private int mNumColumns;
    
        public EvenSpaceGridLayout(Context context) {
            super(context);
        }
    
        public EvenSpaceGridLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            TypedArray a = context.obtainStyledAttributes(attrs,
                    R.styleable.EvenSpaceGridLayout);
            try {
                mNumColumns = a.getInteger(
                        R.styleable.EvenSpaceGridLayout_num_columns, 1);
            } finally {
                a.recycle();
            }
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    
            // Calculate how many cells we need
            int cellCount = countCellsNeeded();
    
            // Calculate number of rows needed given the number of cells
            int numRows = cellCount / mNumColumns;
    
            // Calculate width/height of each individual cell
            int cellWidth = widthSize / mNumColumns;
            int cellHeight = heightSize / numRows;
    
            // Measure children
            measureChildrenViews(cellWidth, cellHeight);
    
            setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            final int count = getChildCount();
            for (int i = 0; i < count; i++) {
                View child = getChildAt(i);
                LayoutParams lp = (LayoutParams) child.getLayoutParams();
                child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight());
            }
        }
    
        private int countCellsNeeded() {
    
            int cellCount = 0;
            final int childCount = getChildCount();
    
            for (int i = 0; i < childCount; i++) {
    
                View child = getChildAt(i);
                LayoutParams lp = (LayoutParams) child.getLayoutParams();
    
                int spanColumns = lp.spanColumns;
    
                // If it's trying to span too far, make it span the maximum possible
                if (spanColumns > mNumColumns) {
                    spanColumns = mNumColumns;
                }
    
                int remainingCellsInRow = mNumColumns - (cellCount % mNumColumns);
                if (remainingCellsInRow - spanColumns < 0) {
                    cellCount += remainingCellsInRow + spanColumns;
                } else {
                    cellCount += spanColumns;
                }
            }
    
            // Round off the last row
            if ((cellCount % mNumColumns) != 0) {
                cellCount += mNumColumns - (cellCount % mNumColumns);
            }
    
            return cellCount;
        }
    
        private void measureChildrenViews(int cellWidth, int cellHeight) {
    
            int cellCount = 0;
            final int childCount = getChildCount();
    
            for (int i = 0; i < childCount; i++) {
    
                View child = getChildAt(i);
                LayoutParams lp = (LayoutParams) child.getLayoutParams();
    
                int spanColumns = lp.spanColumns;
    
                // If it's trying to span too far, make it span the maximum possible
                if (spanColumns > mNumColumns) {
                    spanColumns = mNumColumns;
                }
    
                // If it can't fit on the current row, skip those cells
                int remainingCellsInRow = mNumColumns - (cellCount % mNumColumns);
                if (remainingCellsInRow - spanColumns < 0) {
                    cellCount += remainingCellsInRow;
                }
    
                // Calculate x and y coordinates of the view
                int x = (cellCount % mNumColumns) * cellWidth;
                int y = (cellCount / mNumColumns) * cellHeight;
    
                lp.x = x;
                lp.y = y;
    
                child.measure(MeasureSpec.makeMeasureSpec(cellWidth * spanColumns, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(cellHeight, MeasureSpec.EXACTLY));
    
                cellCount += spanColumns;
            }
        }
    
        @Override
        protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
            return p instanceof LayoutParams;
        }
    
        @Override
        protected LayoutParams generateDefaultLayoutParams() {
            return new LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT);
        }
    
        @Override
        public LayoutParams generateLayoutParams(AttributeSet attrs) {
            return new LayoutParams(getContext(), attrs);
        }
    
        @Override
        protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
            return new LayoutParams(p.width, p.height);
        }
    
        public static class LayoutParams extends ViewGroup.LayoutParams {
    
            int x, y;
    
            public int spanColumns;
    
            public LayoutParams(Context context, AttributeSet attrs) {
                super(context, attrs);
                TypedArray a = context.obtainStyledAttributes(attrs,
                        R.styleable.EvenSpaceGridLayout_LayoutParams);
                try {
                    spanColumns = a
                            .getInteger(
                                    R.styleable.EvenSpaceGridLayout_LayoutParams_span_columns,
                                    1);
    
                    // Can't span less than one column
                    if (spanColumns < 1) {
                        spanColumns = 1;
                    }
                } finally {
                    a.recycle();
                }
            }
    
            public LayoutParams(int w, int h) {
                super(w, h);
            }
        }
    }
    
    package com.example.evenspacegridlayout;
    导入android.content.Context;
    导入android.content.res.TypedArray;
    导入android.util.AttributeSet;
    导入android.view.view;
    导入android.view.ViewGroup;
    公共类EvenSpaceGridLayout扩展了视图组{
    私有int-mnumn列;
    公共网格布局(上下文){
    超级(上下文);
    }
    公共网格布局(上下文上下文、属性集属性){
    超级(上下文,attrs);
    TypedArray a=上下文。获取样式属性(属性,
    R.styleable.EvenSpaceGridLayout);
    试一试{
    mNumColumns=a.getInteger(
    R.styleable.EvenSpaceGridLayout_num_columns,1);
    }最后{
    a、 回收();
    }
    }
    @凌驾
    测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
    int widthSize=MeasureSpec.getSize(widthMeasureSpec);
    int heightSize=MeasureSpec.getSize(heightMeasureSpec);
    //计算我们需要多少细胞
    int cellCount=countcellsneed();
    //计算给定单元格数所需的行数
    int numRows=cellCount/mNumColumns;
    //计算每个单元的宽度/高度
    int cellWidth=widthSize/mNumColumns;
    内部单元高度=高度大小/numRows;
    //测量儿童
    测量儿童视图(单元宽度、单元高度);
    设置测量尺寸(宽度测量等级、高度测量等级);
    }
    @凌驾
    仅受保护的void布局(布尔值已更改、int l、int t、int r、int b){
    最终整数计数=getChildCount();
    for(int i=0;imNumColumns){
    spanColumns=mNumColumns;
    }
    int remainingCellsInRow=mNumColumns-(cellCount%mNumColumns);
    如果(剩余单元格行-跨列<0){
    cellCount+=剩余的CellsInRow+Span列;
    }否则{
    cellCount+=span列;
    }
    }
    //把最后一排排排成四舍五入
    如果((cellCount%mNumColumns)!=0){
    cellCount+=mNumColumns-(cellCount%mNumColumns);
    }
    返回细胞计数;
    }
    私有void measureChildrenView(int cellWidth、int cellHeight){
    int-cellCount=0;
    final int childCount=getChildCount();
    for(int i=0;imNumColumns){
    spanColumns=mNumColumns;
    }
    //如果它不适合当前行,请跳过这些单元格
    int remainingCellsInRow=mNumColumns-(cellCount%mNumColumns);
    如果(剩余单元格行-跨列<0){
    cellCount+=剩余的CellsInRow;
    }
    //计算视图的x和y坐标
    int x=(cellCount%mNumColumns)*cellWidth;
    int y=(单元格计数/mNumColumns)*单元格高度;
    lp.x=x;
    lp.y=y;
    child.measure(MeasureSpec.makeMeasureSpec(cellWidth*spanColumns,MeasureSpec.justice)、MeasureSpec.makeMeasureSpec(cellHeight,MeasureSpec.justice));
    cellCount+=span列;
    }
    }
    @凌驾
    受保护的布尔checkLayoutParams(ViewGroup.LayoutParams p){
    返回LayoutParams的p实例;
    }
    @凌驾
    受保护的LayoutParams GeneratedDefaultLayoutParams(){
    返回新的LayoutParams(LayoutParams.WRAP_内容,
    LayoutParams.WRAP_内容);
    }
    @凌驾
    公共布局参数generateLayoutParams(属性集属性){
    返回新的LayoutParams(getContext(),attrs);
    }
    @凌驾
    受保护的LayoutParams generateLayoutParams(ViewGroup.LayoutParams p){
    返回新的布局参数(p.宽度,p.高度);
    }
    公共静电
    
    <LinearLayout android:layout_width="match_parent" android:layout_height="100dp">
        <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="A" />
        <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="B" />    
        <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="C" />
    </LinearLayout>
    
    <LinearLayout android:layout_width="match_parent" android:layout_height="100dp">
        <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="A" />
        <Button android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" android:text="B" />    
        <Button android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" android:text="C" />
    </LinearLayout>
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
        <LinearLayout android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent">
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="7" />
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="8" />    
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="9" />
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="x" />
        </LinearLayout>
    
        <LinearLayout android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent">
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="4" />
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="5" />    
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="6" />
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="-" />
        </LinearLayout>
    
        <LinearLayout android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent">
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="1" />
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="2" />    
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="3" />
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="+" />
        </LinearLayout>
    
        <LinearLayout android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent">
            <Button android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:text="0" />
            <Button android:layout_weight="1.5" android:layout_width="match_parent" android:layout_height="match_parent" android:text="." />    
            <Button android:layout_weight="1.5" android:layout_width="match_parent" android:layout_height="match_parent" android:text="=" />
        </LinearLayout>
    </LinearLayout>