Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically adding ABOVE to LayoutParams causes view height to be 0

I have a custom View. In the constructor for the view, I create and add two subviews. However, using LayoutParams.addRule() is causing some problems. Rules such as CENTER_HORIZONTAL work, but when I try to use ABOVE, the subview ends up with a height of 0.

Here is the code in my constructor:

    setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));


    mLayoutParams = new LayoutParams(width, height);
    mLayoutParams.leftMargin = left;
    mLayoutParams.topMargin = top;

    mImage = new ImageView(getContext());
    mImage.setImageDrawable(getResources().getDrawable(R.drawable.my_image_drawable));
    mImage.setScaleType(ScaleType.FIT_XY);
    mImage.setId(R.id.my_image_id);
    addView(mImage, mLayoutParams);

    mText = new TextView(getContext());
    mText.setText(R.string.my_text);
    mText.setId(R.id.my_text_id);
    LayoutParams textParams = new LayoutParams(200, 40);
    // textParams.addRule(CENTER_HORIZONTAL, TRUE); //Works
    textParams.addRule(ABOVE, mImage.getId()); //Doesn't work

    addView(mText, textParams);

If I inspect the view on an emulator with the Device Monitor, I can see that the layout_height of the text is 40, but the top, bottom, and height parameters are all 0. measuredHeight appears to be the same as the screen width.

  1. Am I doing something wrong with adding the rules?
  2. Is there a better place to add the rules? Does something need to happen first?
  3. Any other alternatives? Making the TextView have a height of FILL_PARENT, gravity BOTTOM, and setting its bottom margin to the height of the image works, but I need to be able to add another view above the text, and this won't work for that.
like image 222
karl Avatar asked Nov 11 '22 22:11

karl


1 Answers

where in your code are you checking for height? If it's somewhere within onCreate or onCreateView, you won't get any info. Layout is a two-pass process and in those two methods the two passes are not complete.

You may need to get the height in those methods by using the ".post" method like this:

        myView.post( new Runnable() {
        @Override
            public void run() {
                int height = myView.getHeight();
            } 
        });

The runnable makes it run on the UI thread, but it's invoked after both passes, the measure pass and the layout pass, have completed. So trying to set a rule based on a center horizontal without first knowing the measurements is going to fail.

like image 156
Martin Avatar answered Nov 15 '22 01:11

Martin