【问题标题】:How does one determine the DIP height of the tabcontent area?如何确定 tabcontent 区域的 DIP 高度?
【发布时间】:2011-09-10 10:30:50
【问题描述】:

tl;dr:如何获得 FrameLayout 的 DIP 高度?

完整:我正在尝试设计一个在可用的一般分辨率中保持一致的布局。我浏览了 Google 上的开发人员最佳实践,这对我的理解有所帮助。我已经将图标转换为 9-patch,并且正在使用 DIP 高度,这大大改善了事情。

但是,无论分辨率如何,我都会尝试播放三行按钮,这些按钮将占据屏幕的其余部分。我需要为小屏幕和平板电脑做一些不同的事情,但我目前只担心大多数手机的正常屏幕。

我有一个布局,其中有一个 TabWidget 作为 @android:id/tabs 角色和一个 FrameLayout 作为 @android:id/tabcontent

其中一个选项卡活动只是 3 行按钮,我想填充整个 FrameLayout,我怀疑我必须根据 FrameLayout 的高度计算按钮的高度。

那么我的问题是,如何获得 FrameLayout 的 DIP 高度?

我尝试了 GlobalLayoutListener,它只返回 0。我试过拉 LayoutParams,它只为 FILL_PARENT 返回 -1。我需要 FrameLayout 的实际 DIP 高度来正确设置可用区域的高度。

我该怎么做,还是我看错了?

感谢任何帮助。

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    我想出了一种方法来获得我想要的结果,只是不是我尝试的确切方法,并且从未设法直接但间接地获得 tabcontent 的高度。

    我找到了两种方法可以做到这一点,我将在下面发布它们。

    首先我做了 方法 2,但后来发现我更喜欢 方法 1,并决定采用它,因为它更具可扩展性。

    方法一

    我从How to size an Android view based on its parent's dimensions 找到的这种方式是最可定制和可读的方法。简而言之,您需要扩展 FrameLayout 并覆盖 onMeasure 方法。

    <?xml version="1.0" encoding="utf-8"?>
    <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="0dip"
        android:layout_margin="0dip">
        <LinearLayout
            android:id="@+id/topLayout"
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="0dip"
            android:layout_margin="0dip">
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="50dp"
                android:padding="0dip"
                android:layout_margin="0dip" />
            <view
                class="com.tmcaz.patch.TabContentFrameLayout"
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:padding="0dip"
                android:layout_margin="0dip" />
        </LinearLayout>
    </TabHost>
    

    主要区别在于为此使用自定义类,您可以在其中处理事件本身的大小,类似于 方法 2,但无需进行任何计算来获取内容高度。

    我这样做是为了让自己能够访问该事件并处理内容中的所有大小调整。阅读本文的人很可能需要覆盖其他内容并以完全不同的方式处理 onMeasure 事件。

    代码如下

    public class TabContentFrameLayout extends FrameLayout {
            // add constructors, etc
            @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
            // Should turn these in to member variables and reference it throughout.
            int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
            int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    
            this.setMeasuredDimension(parentWidth, parentHeight);
    
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
    

    方法二

    我将id 分配给了拥有TabWidgetFrameLayoutLinearLayout。这是我的 main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="0dip"
        android:layout_margin="0dip">
        <LinearLayout
            android:id="@+id/topLayout"
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="0dip"
            android:layout_margin="0dip">
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="50dip"
                android:padding="0dip"
                android:layout_margin="0dip" />
            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:padding="0dip"
                android:layout_margin="0dip" />
        </LinearLayout>
    </TabHost>
    

    我为tabs 分配了一个DIP 高度,然后为LinearLayout 抓取LayoutParams,我只是从结果中减去tabs 的高度。我在此处添加代码仅用于基本说明目的,并且可以更有效地执行此操作,这不是我的生产代码:)

    需要注意的一点是,在最有用的 onCreate 事件期间,您似乎无法直接拉动布局的高度。您需要创建一个GlobalLayoutListener 来捕捉布局的变化并获取大小。

    public class MyTabActivity extends TabActivity {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            LinearLayout ll = (LinearLayout)findViewById(R.id.topLayout);
            ll.getViewTreeObserver().addOnGlobalLayoutListener(
                    new ViewTreeObserver.OnGlobalLayoutListener() {
    
                        public void onGlobalLayout() {
                            DisplayLayoutDimensions();
                        }
                    }
            );
    
             // Code here to add activities to the tabs, etc
    }
    

    .

    public void DisplayLayoutDimensions()
    {
            // Put code to calculate the heights you need instead of printing
            // out the values obviously.
            Resources r = getResources();
            LinearLayout topLayout = (LinearLayout)findViewById(R.id.topLayout);
            LayoutParams tabWidgetParams = getTabHost().getTabWidget().getLayoutParams();
    
            float scale = r.getDisplayMetrics().density;
            float pxTabContent = topLayout.getHeight() - tabWidgetParams.height;
    
            /*** The commented out DIP calculations didn't work for me in any AVD so
                 manually I calculated them with the scale which worked fine         ***/
    
            //float dipTopLayout = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, topLayout.getHeight(), r.getDisplayMetrics());
            //float dipTabWidget = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabWidgetParams.height, r.getDisplayMetrics());
            //float dipTabContent = dipTopLayout - dipTabWidget;
    
            Log.d("MyTabActivity", "LinearLayout (topLayout) Height: " + topLayout.getHeight() + "px / " + (topLayout.getHeight() / scale) + "dp");
            Log.d("MyTabActivity", "TabWidget Height: " + tabWidgetParams.height + "px / " + (tabWidgetParams.height / scale) + "dp");
            Log.d("MyTabActivity", "Calculated (tabcontent) Height: " + pxTabContent + "px / " + (pxTabContent / scale) + "dp");
    }
    

    希望这在某些时候可以帮助某人。如果有人有更好的方法来做到这一点,请说出来。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-28
      • 2015-10-28
      • 1970-01-01
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多