2011-09-08 13 views
0

tl; dr: FrameLayoutのDIPの高さを取得するにはどうすればよいですか?タブコンテンツ領域のDIPの高さはどのように決定されますか?

フル:私は利用可能な一般的な解像度で一貫したレイアウトを設計しようとしています。私はGoogleの開発者のベストプラクティスを理解しています。私はアイコンを9パッチに変換し、DIPの高さを使用しています。

しかし、どこにいるのかは、解像度に関係なく、画面の残りの部分を占める3行のボタンを再生しようとしているところです。小さな画面やタブレットでは違うものを作る必要がありますが、現在のところ、ほとんどの携帯電話の通常の画面が心配です。

私は@androidとしてTabWidgetを持っていレイアウトがあります。@androidためのID /タブの役割とでframeLayout:ID/tabcontent

タブの活動の一つは、単に私が欲しいのボタンの3行ですがFrameLayoutの高さに基づいてボタンの高さを計算する必要があると思われるFrameLayout全体を塗りつぶします。

私の質問は、FrameLayoutのDIPの高さを取得する方法です。

GlobalLayoutListenerを試しましたが、0が返されます.LayoutParamsを取得しようとしましたが、FILL_PARENTに対して-1が返されました。使用可能な領域の高さを適切に設定するには、FrameLayoutの実際のDIPの高さが必要です。

どうすればできますか、それとも間違って見ていますか?

何か助けていただければ幸いです。

答えて

1

私が望んでいた結果を得る方法を見つけました。私が試した正確な方法ではなく、tabcontentの高さを直接的かつ間接的に得ることは決してありませんでした。

私はこれを行うには2つの方法を見つけました。

まず私は方法2 をしましたが、その後、私は方法1 を優先し、それはより多くの拡張だからそれで行くことにした発見しました。

方法1

私はHow to size an Android view based on its parent's dimensionsから発見され、ほとんどのカスタマイズと読みやすい方法ですこの方法です。ナットシェルでは、FrameLayoutを拡張し、onMeasureメソッドをオーバーライドする必要があります。あなたは方法2が、コンテンツの高さを取得するために任意の計算を実行する必要はありませんのようなイベント自体からサイズを扱うことができる場所

<?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> 

主な違いは、このためにカスタムクラスを使用しています。

私はイベントにアクセスし、コンテンツ内のすべてのサイズを処理するためにこれを行いました。これを読んでいる人は、何か他のものを上書きして、全く別様にonMeasureイベントを処理する必要があります。

コードは、私がTabWidgetFrameLayoutを保持LinearLayoutidを割り当て

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); 
    } 
} 

方法2

未満です。ここで私はtabsにDIPの高さを割り当てられ、その後、私は単に結果からtabsの高さを差し引くLinearLayoutためLayoutParamsをつかんで、私の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> 

です。私はここに基本的な説明目的のためだけにコードを追加しました。それは少し効率的に行うことができます。私の生産コードではありません:)

注意すべきことは、レイアウトの高さを直接引っ張って最も便利な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"); 
} 

これは、ある時点で誰かを助けることを望みます。誰かがこれを行うより良い方法を持っているなら、話してください。

関連する問題