Question

I have 5 LinearLayouts. For ease of writing and understanding, I'll refer to them as Views A - E.

View A is the parent of Views B, C, D, and E.

I have set the layout_weight to 8.0f for View A and the weights to 1.0f, 3.0f, 1.0f, 3.0f for Views B - E respectively.

I understand that this is for managing the empty space in the parent view, but I was hoping to size my View and subviews to own a percentage of the screen, rather than compete just for the free space.

However, this is all done programmatically, so should I set the height of the LinearLayouts to a coefficient of the getHeight() method/accessor of it's parent (View A)? If so, then how can I get the height of the parent if the view hasn't yet been added to it's parent, which would set its height with MATCH_PARENT?

Since the getHeight() method will return 0 for onCreate, onStart, and the first onResume, I had to keep looking for an answer. I found ViewTreeObserver and OnGlobalLayoutListener, which will let me know when the Layouts have been set. However, I would really appreciate having the height before any drawing occurs. Is that not possible?

Was it helpful?

Solution

If you don't need to do this programatically, you can do it in xml. In order to have the child LinearLayouts take up a percentage of the Parent LinearLayout (LinearLayout A) then you need to set the parent's weightSum=(Total layout_weight of child LinearLayouts) and then set the child LinearLayouts width/height property to "0dip" and set their layout_weight to the desired percentage.

Sample code for a vertical orientation would be:

<LinearLayout
     android:id="@+id/A"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:weightSum="8.0"
     android:orientation="vertical">
     <LinearLayout
          android:id="@+id/B"
          android:layout_height="0dip"
          android:layout_width="fill_parent"
          android:layout_weight="1.0"/>
     <LinearLayout
          android:id="@+id/C"
          android:layout_height="0dip"
          android:layout_width="fill_parent"
          android:layout_weight="3.0"
</LinearLayout>

OTHER TIPS

Unfortunately, it's not possible to get the size of a view before it's drawn (not unless there is a hack out there that I'm unaware of). The view doesn't hold any information about its size until it until it is ready to be laid out. It would be nice if, in a future release, they designed the system hold the view dimensions prior to the view being drawn.

You could create a custom class, extend the View class, and then override a method that is called by the system and return the dimensions to an object reference in your activity. However, this is likely to be more of a headache then a help and doesn't really give you any real advantage.

I'd recommend using ViewTreeObserver and the OnGlobalLayoutListener.

Here's how to do this with Fragments as mentioned above.

First save a reference to context in the onAttach method (you will probably want to setup a callback to the activity anyway:

Context context;

@Override
public void onAttach(Activity activity){
    super.onAttach(activity);

    context = activity;


} 

Then in onViewCreate, you take the measurements and use them:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Display display = ((WindowManager)
        context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics(metrics);

    float pixHeight = metrics.heightPixels;
    float pixWidth = metrics.widthPixels;
    float density  = context.getResources().getDisplayMetrics().density;
    float dpHeight = pixHeight / density;
    float dpWidth  = pixWidth / density;

    // make various layouts using your measurements, send the
    // measure of each parent to each custom drawn child, or 
    // send the bounds of each child as determined by the size of each parent

    return someView;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top