I use a custom View element based on RelativeLayout, I get attributes in the constructor, if the size is set to - "dp", then it works fine, but if I put MATCH_PARENT program crashes during initialization, how to get the size if specified MATCH_PARENT and not for example 150dp?

 private void init(AttributeSet attrs, Context context) { int[] attrsArray = new int[] { android.R.attr.id, // 0 android.R.attr.layout_width, // 1 android.R.attr.layout_height // 2 }; final TypedArray typedArray = context.obtainStyledAttributes(attrs, attrsArray); try { // Получаем Id Id = typedArray.getResourceId(0, View.NO_ID); // Ширина m_nWidth = typedArray.getDimensionPixelSize(1, ViewGroup.LayoutParams.MATCH_PARENT); // Высота m_nHeight = typedArray.getDimensionPixelSize(2, ViewGroup.LayoutParams.MATCH_PARENT); } catch(Exception ex) { m_nWidth = 200; m_nHeight = 200; } finally { // Освобождаем ресурсы typedArray.recycle(); } } 

Constructor:

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

Log:

04-22 13: 38: 18.695: E / AndroidRuntime (1992): FATAL EXCEPTION: main java.lang.UnsupportedOperationException: Can not convert to dimension: type = 0x10 04-22 13: 38: 18.695: E / AndroidRuntime (1992 ): at android.content.res.TypedArray.getDimensionPixelSize (TypedArray.java:463) 04-22 13: 38: 18.695: E / AndroidRuntime (1992): at com.test.view.CustomView.init (CustomView.java: 63) 04-22 13: 38: 18.695: E / AndroidRuntime (1992): at com.test.view.CustomView. <Init> (CustomView.java:26)

  • Which line falls then? - Suvitruf
  • Falls to typedArray.getDimensionPixelSize (1, ViewGroup.LayoutParams.MATCH_PARENT); - UserAlexandr
  • The reason is clear - 0x10 is the code from R.class, which is MATCH_PARENT, therefore when converting we fall. Maybe it's better not to override these values? - Gorets
  • I need to get the size of the View to draw an object in it in the middle - UserAlexandr
  • probably you need to use other methods to get the height and width of the container, they will be only after drawing on the screen - Gorets

2 answers 2

Suppose you need to draw something on the View after getting its dimensions.

You can use this option: Make CallBack render type void DrawCallback (View view) and where you need to check the dimensions View do this.

  int measuredWidth = target.getMeasuredWidth(); int measuredHeight = target.getMeasuredHeight(); if (measuredWidth == 0 || measuredHeight == 0) { new Deferer(target, mDrawCallBack); return; } else { mDrawCallBack(target); } 

Deferer:

 class Deferer implements ViewTreeObserver.OnPreDrawListener { DrawCallback callback; ImageView targer; Deferer (ImageView target, DrawCallback callback) { this.target = new WeakReference<ImageView>(target); this.callback = callback; target.getViewTreeObserver().addOnPreDrawListener(this); } @Override public boolean onPreDraw() { ImageView target = this.target.get(); if (target == null) { return true; } ViewTreeObserver vto = target.getViewTreeObserver(); if (!vto.isAlive()) { return true; } int width = target.getMeasuredWidth(); int height = target.getMeasuredHeight(); if (width <= 0 || height <= 0) { return true; } vto.removeOnPreDrawListener(this); callback(target); return true; } 

I did not check the work, but it should shoot with minimal amendments :)

    Doesn't the designer get the size before drawing it?

    No, it does not. The size becomes known only after working off:

     @Override protected void onLayout() 

    come from here, google something or something ...