3

I have a little issue on what sequence things are being called when adding stuff to a RelativeLayout. I have a class extending Activity (name it RelActivity) where I want to create a RelativeLayout and put several custom Views (name it cusView) into that RelativeLayout. The topMargin and leftMargin of a custom View is calculated by using the position of another custom View (i.e. the first custom View has to be positioned directly by setting a number to topMargin and leftMargin). Please note that the Rules of RelativeLayout is not sufficient in this case.

So, over to the problem. In my RelActivity I do this:

  1. Create a RelativeLayout (name it relLayout)
  2. Iterate a cursor with cusViews recieved from a database
  3. For the first cusView -> Set position by topMargin and leftMargin using a LayoutParameter
  4. For the other cusViews -> calculate their topMargin and leftMargin by using one of the other cusViews and a LayoutParameter
  5. Set RelActivity's contentView to relLayout

What happens is that all cusViews but the first one are squeezed in the top left corner because both leftMargin and topMargin are always calculated to be zero. This happens because I use the width of the cusViews to calculate the topMargin and leftMargin, and the width of the cusView has not given a value yet.

Is the width first calculated in the cusView's overrided method onSizeChanged()? Is the onSizeChanged() method get called first when the layout is presented on the screen? If so, how do I work around this issue? Do I have to calculate the positionings after onSizeChanged() is done?

Edit: Here is a minimum working example:

Here is my onCreate in RelActivity:

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); relLayout = new RelativeLayout(this); cusViews = new ArrayList<CusView>(); listParams = new ArrayList<RelativeLayout.LayoutParams>(); readDBandSetLayout(); setContentView(relLayout); } 

There is too much information in the readDBandSetLayout() method to present it all here. below are the most important details. If I create the LayoutParams in the following way it works fine, the cusViews are listed downwards and rightwards of eachother:

queryCursor = customApplication.customData.query( number); //Fetches cursor for ( int i = 0; i < numberOfRows; i++ ){ if ( i == 0 ){ LayoutParams p = new LayoutParams(this.getResources().getDimensionPixelSize(R.dimen.small), this.getResources().getDimensionPixelSize(R.dimen.small)); p.topMargin = 50; p.leftMargin = 50; listParams.add(p); } else{ LayoutParams p = new LayoutParams(this.getResources().getDimensionPixelSize(R.dimen.large),this.getResources().getDimensionPixelSize(R.dimen.large)); p.addRule(RelativeLayout.BELOW, cusViews.get(i-1).getId()); p.addRule(RelativeLayout.RIGHT_OF, cusViews.get(i-1).getId()); listParams.add(p); } relLayout.addView(cusViews.get(i), listParams.get(i)); } 

However, what I want to do in the else statement is something like:

else{ LayoutParams p = new LayoutParams(this.getResources().getDimensionPixelSize(R.dimen.large),this.getResources().getDimensionPixelSize(R.dimen.large)); //Here I want to calculate cusView2Topmargin and cusView2Leftmargin based on the widths of the first or previosly positioned cusViews. But here the widths are 0 since they haven't been calculated yet. p.topMargin = cusView2Topmargin; //Always zero p.leftMargin = cusView2Leftmargin; //Always zero listParams.add(p); } 

So the problem lies in that the widths of the cusViews are zero at the point I need them to calculate the layout parameters topMargin and leftMargin.

Unfortunately I cannot use the RelativeLayout's Rules for what I want to achieve. If there were some way to create rules like RelativeLayout.RIGHT_OF and RelativeLayout.BELOW I could do it like that. Is this possible?

2
  • Your general approach is ok (assuming that relative-layout-or-any-other is not sufficient enough, which is a very rare case). My bet is you do sth. wrong when setting LayoutParams, this part can get tricky and I had similar problem in the past. Please provide some code samples and we'll see what we can do. Commented Feb 10, 2012 at 18:59
  • I added some working code. Hope it will suffice to understand the issue. Do you know if it is possible to create my own RelativeLayout Rules? That might solve the issue since using those rules actually works. Commented Feb 10, 2012 at 19:23

1 Answer 1

1

Its not very clear what your goal is for this layout. It might well be possible to use a simple LinearLayout to get what you want.

If you want to size these from a database lookup then try simply adding each of the views, using addView() first, storing a reference to each, then go back and sett the margins to place them in the proper positions.

Sign up to request clarification or add additional context in comments.

2 Comments

Note: You are trying to force an absolute view approach into a relative view. There is probably a better way to do this if you share your goals for what the final layout should look like.
I have been looking into this and believe that a LinearLayout is the way to go. As you say I am trying to force an absolute view out of a relative view. Another approach could be to use a GridLayout though I have not tried this myself.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.