2011-10-04 76 views
0

我想創建一個自定義的LinearLayout(後來定製的ImageButton),可以採取百分比值基於其母公司的大小,而不管父類型(相對或線性)的大小的兩個維度。我正在關注這篇文章:How to size an Android view based on its parent's dimensions,這非常有幫助,但我有一個問題,那些答案沒有解決。定製的ViewGroup作品裏面的LinearLayout不RelativeLayout的

當我把我的自定義的LinearLayout另外的LinearLayout內,按預期工作的一切。我的自定義LinearLayout覆蓋了預期的空間(下例中爲父寬度的80%)。

但是如果我把它放在一個RelativeLayout的裏面,我的屏幕上始終顯示爲空,我不知道爲什麼會這樣。

這裏是我的類:

public class ButtonPanel extends LinearLayout { 

    public ButtonPanel(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

     int parentWidth = MeasureSpec.getSize(widthMeasureSpec); 
     int parentHeight = MeasureSpec.getSize(heightMeasureSpec); 

     int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
     int heightMode = MeasureSpec.getMode(heightMeasureSpec); 

     int newWidth = (int) Math.ceil(parentWidth * 0.8); 

     this.setMeasuredDimension(newWidth, parentHeight); 
     this.setLayoutParams(new RelativeLayout.LayoutParams(newWidth,parentHeight)); 

     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 
} 

這裏是我的活動測試佈局。

<RelativeLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:orientation="horizontal" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

     <com.android.tests.views.ButtonPanel 
      xmlns:android="http://schemas.android.com/apk/res/android" 
      android:orientation="horizontal" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:background="@drawable/inner_panel" 
       android:gravity="center_horizontal" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentTop="true"> 
     </com.android.tests.views.ButtonPanel> 
    </RelativeLayout> 

在我的活動中,我所做的就是將內容視圖設置爲上述佈局。

(順便說一句,是否有人現在我怎麼能拿父母的類型動態地設置新LayoutParameters?上面你會看到父類型(RelativeLayout的)硬編碼到自定義視圖onMeasure功能)

在此先感謝您的幫助!

回答

0

原來我在這篇文章中的兩個查詢比預期更相關。

我意識到,我的觀點的的LayoutParams設置到一個完全新的實例,我被改寫由相對佈局來定位我認爲需要的佈局定位信息。

通過「歸零」的信息,我的觀點有正確的尺寸,但佈局不知道在什麼地方,所以根本談不上。

新的onMeasure的以下代碼顯示瞭如何直接修改已添加到視圖中的LayoutParams的高度和寬度,以避免覆蓋佈局位置信息以及必須根據父類型創建新的LayoutParams。

@Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

     int specWidth = MeasureSpec.getSize(widthMeasureSpec); 
     int specHeight = MeasureSpec.getSize(heightMeasureSpec); 

     int newWidth = (int) Math.ceil(parentWidth * 0.8); 
     int newHeight = (int) Math.ceil(parentHeight * 0.8); 

     this.setMeasuredDimension(newWidth, newHeight); 

     this.getLayoutParams().height = newHeight; 
     this.getLayoutParams().width = newWidth; 

     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 

現在,我會誠實地說,這段代碼仍然沒有錯誤。多次將活動引入前景和背景會不斷縮小此自定義視圖的大小。在每次提交活動時我都會重複應用0.8的縮減因子(我懷疑LayoutParams的設置與它有關,但實際上可能沒有必要,但我沒有時間測試)。

但是,這仍然回答了關於這篇文章的問題,即爲什麼我的觀點儘管有正確的尺寸,但並沒有出現。

0

這是暴露出來的問題嗎?

this.setLayoutParams(new RelativeLayout.LayoutParams(newWidth,parentHeight)); // <-- a RelativeLayout params? 
+0

我不確定你的意思。 不可否認,我正在實現這個半盲,我從那一行了解到的是任何給定View或Viewgroup所具有的佈局參數,它們必須是其父容器的佈局參數的一個實例。 這是關於這一行,我在最後問了我的小問題,這樣我就不必將RelativeLayout作爲父類型進行硬編碼。 雖然,blessenm似乎給了我答案。 – RobertoCuba

0

在onMeasure函數中,您可以使用類似這樣的內容來知道哪個類是視圖的父類。

this.getParent().getClass().getName() 

這也應該工作

a instanceof B 

B.class.isAssignableFrom(a.getClass()) 

當使用 「的instanceof」,你需要知道在編譯時的 「B」 類的。當使用「isAssignableFrom」時,它可以是動態的,並在運行時更改。

如果你不與字符串比較compfortable,您還可以使用枚舉。

+0

謝謝,我會在今天晚些時候嘗試。 – RobertoCuba

+0

嘗試了這一點,但做了一個小小的修改,getSimpleName()讓我單獨得到類名,事實證明getName()獲取整個包(android.widget.RelativeLayout)。 我似乎很奇怪我不得不求助於字符串比較來告訴另一個父母,但我想我的目的是有效的。 感謝您的指針! – RobertoCuba

+0

我已經更新了我的答案。如果這有幫助,upvote,如果它解決了你的問題,接受答案。 – blessenm

相關問題