2016-04-12 39 views
0

Kendi sürümümüzü oluşturmak için AppBarLayout'u genişletiyorum. Amacım, çalışma zamanında bazı LayoutParameters ayarlamaktır. AppBar yüksekliği.Özel GörünümGrup/Kompozit Görünüm DüzeniParametreleri kendi kurgusunun içinde

Herhangi bir Paramter ayarlamaya çalışırsam, bir NPE alırım, sanırım LayoutParameters henüz oluşturulmamış ve ayarlanmamıştır.

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    if(!hasSetHeight) { 
     ViewGroup.LayoutParams params = this.getLayoutParams(); 
     params.height = mExpandedHeight; 
     this.setLayoutParams(params); 
    } 
} 

özel bir ViewGroup/kompozit Görünüm yapıcısı içindeki LayoutParameters ayarlamak için bir yolu var mı:

public MyAppBar(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    ... 

    LayoutInflater.from(context).inflate(R.layout.layout_my_app_bar, this, true); 

    ViewGroup.LayoutParams params = this.getLayoutParams(); 
    params.height = calculateExpandedHeight(selectedAspectRatio); 
    this.setLayoutParams(params); 

    ... 
} 

Benim şu anki geçici çözüm LayoutParamsonMeasure içine ayarlamaktır?


layout_my_app_bar.xml

<?xml version="1.0" encoding="utf-8"?> 
<merge xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/tools"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     android:background="?attr/colorPrimary" 
     app:popupTheme="@style/AppTheme.PopupOverlay"/> 
</merge> 

cevap

0

Eh, alıyoruz NullPointerException Görüntüle henüz sistem tarafından dışarı atılmış değil çünkü boş olan LayoutParams ilişkilidir. Bu size iki seçenek sunar: Görünüm ayarlanana kadar param ayarını geciktirebilir veya nasıl yerleştirileceğini anlatmak için View in internal onMeasure (nasıl kullandığınıza benzer) kullanabilirsiniz.

eski ViewTreeOberserver gelen OnGlobalLayoutListener ile elde edilebilir :

public MyAppBar(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    ... 

    getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
      public void onGlobalLayout() { 
       ViewGroup.LayoutParams params = this.getLayoutParams(); 
       // Set the params here 

       removeOnGlobalLayoutListener(MyAppBar.this, this); // Remove the listener 
      } 
     }); 
    requestLayout(); 
} 

@SuppressLint("NewApi") 
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener) { 
    if(Build.VERSION.SDK_INT < 16) 
     v.getViewTreeObserver().removeGlobalOnLayoutListener(listener); 
    else v.getViewTreeObserver().removeOnGlobalLayoutListener(listener); 
} 

ikincisi, sadece bir boy oranı gibi görünen uyguluyorsanız beri (biraz) daha iyi olabilir, olacaktır onMeasure yöntemini kullanın ve dönüşümünüzü oradaki widthMeasureSpec'e uygulayın. Örneğin.

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int adjustedHeight = MeasureSpec.getSize(widthMeasureSpec)/selectedAspectRatio 

    super.onMeasure(widthMeasureSpec, 
     MeasureSpec.makeMeasureSpec(adjustedHeight, MeasureSpec.getMode(MeasureSpec.EXACTLY))); 
} 

gerçekten dikkate diğer MeasureSpec olasılıkları onMeasure almadığını öne Unutmayın, ben her zaman genişliğini biliyor ve yükseklik dayalı kendisini ayarlamak isteyeceksiniz büyük bir varsayım yapıyorum söyledi. Diğer durumlar için biraz daha dinamik ve hesaplı olmak istiyorsanız, easy View measuring bunu açıklayan oldukça iyi bir iş yaptı. Sadece seni doğru yönde gösterebileceğini düşündüm.