Android:如何根据大小创建自定义布局

Posted

技术标签:

【中文标题】Android:如何根据大小创建自定义布局【英文标题】:Android: How to create custom layout dependent on size 【发布时间】:2013-06-08 10:10:10 【问题描述】:

我需要一个建议...我想创建自定义视图组,该视图组将根据该视图的大小具有不同的布局。

一个例子:

两个视图:

视图 A:高度至少为 50dp 的子视图 视图 B:我的自定义视图,它扩展了垂直方向的 LinearLayout,高度为 200 dp

我想要什么:

    当我将 2 个视图 A 插入到视图 B 中时: 我想将这两个视图 A 拉伸到 100 dp。所以 B 将是具有 2 个孩子的常见线性布局。 当我将 5 个视图 A 插入到视图 B 中时: 我想将滚动视图添加到 B 中。所有 5 个视图 A 都将在此滚动视图中,它们的高度为 50 dp。

通常,我在构造函数中将视图添加到自定义视图。但我不能在这里做,因为我不知道构造函数中 B 的高度。我只知道 A 的高度。所以请告诉我应该使用哪种回调方法...当 B 的高度已知时,我可以根据此高度添加所有子视图。

或者如果您知道任何其他方法...请告诉我...

非常感谢!

【问题讨论】:

如果 B 的高度应该是 const,那么只需检查孩子 A 的共同高度。如果聚合高度会更多,那么 200(或 4+ 视图) - 在 B 内创建一个 ScrollView 并将您的 A 视图推入其中,然后以编程方式将 ScrollView 的布局参数设置为 match_parent。否则(如果 A 仅查看 1-3 个)- 将它们 layout_weight 参数设置为 1。 这正是我想要的。但我不知道什么时候会知道值 200,即覆盖哪种方法。 B 的高度不是 const 高度,而是取决于屏幕尺寸。正如我所写:构造函数中不知道此值...感谢您的回复... 【参考方案1】:

您应该考虑将所有视图放入滚动视图中的垂直线性布局,或者更好:使用单个列表视图而不是布局和滚动视图。

原因是它会在需要时自动处理滚动,具体取决于屏幕上的可用空间和视图的大小。

【讨论】:

不幸的是,这不是我们想要的行为。我想在不需要滚动视图时拉伸子视图......即当内部视图的聚合大小较小时,我将使用权重,当大小较大时,我将使用滚动视图。而且我不知道如何使用列表视图或简单的滚动视图。顺便说一句。布局会比我的例子复杂一点。这将是一个包含多列的表格布局。这就是我不想使用列表视图的原因。 android 支持多种屏幕分辨率和密度。您应该考虑如何处理不同的配置,以便使用所需的布局。即使使用权重,您也需要检查视图是否有足够的空间来显示其内容。你会怎么做? 确定我知道...这就是我想使用这种自定义布局的原因。当屏幕/分辨率足够大或只是将设备 dpi 更改为较低值时,内容很小,并且当它不是全屏时看起来不太好(它只占据屏幕的一部分)......所以我想使用重量拉伸它。另一方面,当屏幕很小时,我必须使用滚动视图。我将如何区分这两种情况?这就是我在这里要问的:) 我想通过 getHeight() 方法获取高度,并根据这个值选择布局。但是我不知道在哪个View方法中。 好的,我明白了。要获取每个视图的高度,您可以使用此方法:***.com/a/10923514/878126【参考方案2】:

您可以使用此代码获取主布局的实际高度。 然后,您可以在 if-else 或 switch-case 块中使用该高度来检查所需的条件。

public int getLayoutSize() 
// Get the layout id
    final LinearLayout root = (LinearLayout) findViewById(R.id.mainroot);
    final AtomicInteger layoutHeight = new AtomicInteger();

    root.post(new Runnable()  
    public void run()  
        Rect rect = new Rect(); 
        Window win = getWindow();  // Get the Window
                win.getDecorView().getWindowVisibleDisplayFrame(rect);

                // Get the height of Status Bar
                int statusBarHeight = rect.top;

                // Get the height occupied by the decoration contents 
                int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();

                // Calculate titleBarHeight by deducting statusBarHeight from contentViewTop  
                int titleBarHeight = contentViewTop - statusBarHeight; 
                Log.i("MY", "titleHeight = " + titleBarHeight + " statusHeight = " + statusBarHeight + " contentViewTop = " + contentViewTop); 

                // By now we got the height of titleBar & statusBar
                // Now lets get the screen size
                DisplayMetrics metrics = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(metrics);   
                int screenHeight = metrics.heightPixels;
                int screenWidth = metrics.widthPixels;
                Log.i("MY", "Actual Screen Height = " + screenHeight + " Width = " + screenWidth);   

                // Now calculate the height that our layout can be set
                // If you know that your application doesn't have statusBar added, then don't add here also. Same applies to application bar also 
                layoutHeight.set(screenHeight - (titleBarHeight + statusBarHeight));
                Log.i("MY", "Layout Height = " + layoutHeight);   

            // Lastly, set the height of the layout       
            FrameLayout.LayoutParams rootParams = (FrameLayout.LayoutParams)root.getLayoutParams();
            rootParams.height = layoutHeight.get();
            root.setLayoutParams(rootParams);
        
    );

return layoutHeight.get();

【讨论】:

以上是关于Android:如何根据大小创建自定义布局的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XML 根据图像大小调整 Android 组件的大小

Compose 通过自定义Modifier修改布自定义布局

Flutter 自定义布局,根据子元素决定 widget 的大小

创建自定义布局 ExtJs 4.1

Android自定义ViewGroup(四打造自己的布局容器)

android将activity设置成自定义的Dialog怎么调整大小