The right Layout for different screen sizes?Absolute Layout?

Put problem concerning Views, Layouts and other XML-Resources (like AndroidManifest) here.

The right Layout for different screen sizes?Absolute Layout?

Postby VIDEN » Tue Jun 09, 2009 9:25 am

Hey,

I'm developing an android app for building automation in which I show a room from the top view as seen on the pictures below.

As the light, temp, ect. icon have to be in a specific place on the background picture I am using the absolute layout. My problem is, that when I tilt the phone or when i use a device with a large screen the background picture adapts to the new screen but my icons still stay at their absolute cooridantes.
Since the program is supposed to run an the G1 as well as an min. 7" screen I have to find some sort of solution.

Is there a better way to solve my problem than using the absolute layout? Is there a way to give a relative position for my icons (for example % of the container they are in) ?

Greets

David
Attachments
Android_Demo_5.jpg
Android_Demo_5.jpg (29.1 KiB) Viewed 659 times
Android_Demo_3.jpg
Android_Demo_3.jpg (33.72 KiB) Viewed 661 times
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

Top

Reply

Postby satishkumar_lskin » Tue Jun 09, 2009 2:27 pm

Hi,

Absolute Layout is generally not recommended for use in Layouts unless otherwise u need to place the UI components at their absolute positions with out any change always.
LinearLayout is known for its flexibility in adapting to different screen resolutions and configuration changes like screen-orientation change.
For ur requirement , I would suggest u to use LinearLayout and override onConfigurationChanged() in ur Activity to change the width and height of the LinearLayout , if needed. ( Remember that u need not relayout the components inside the LinearLayout. Changing the dimensions of the LinearLayout would be sufficient ).
satishkumar_lskin
Developer
Developer
 
Posts: 32
Joined: Mon Oct 20, 2008 8:15 am
Location: Coimbatore , TamilNadu, India

Postby VIDEN » Tue Jun 09, 2009 2:45 pm

The problem is that I need specific positions for the icons relative to the the background image.
The light bulb should always be in the middle of the room and the fan should always be in the upper left corner. I don't think I can achieve that with the Linear Layout can I?

Greets

David
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

Postby VIDEN » Thu Jun 11, 2009 7:36 am

anyone? please..
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

Postby WarrenFaith » Thu Jun 11, 2009 2:17 pm

Hey Viden,

i would recommend a more specific layout. It doesn't seem to be good to allow the room-image to stretch to fit the screen. I would set a height and width. Inside this you should be able to place icons on every coordinate you want. The last question is: xml or programmed layout?
WarrenFaith
Moderator
Moderator
 
Posts: 227
Joined: Fri Mar 13, 2009 10:59 am
Location: Berlin, Germany

Postby VIDEN » Fri Jun 12, 2009 8:50 am

Hey WarrenFaith,

thx for the answer!
Well what exactly do you mean with a "more specific layout".
The way I understand it is that you still recommend using the AbsoluteLayout and giving the background image a hard coded size.

I agree, that it isn't desirable for the bgimage to be stretched over the screen. It is important, that it keeps its aspect ratio. But giving it an absolute size isn't really satisfying ether because than it will always have the same size even on a big screen.

Ideally the bgimages size should be adjusted accoirding to the size of the display, always keeping its aspect ratio. The icons should have relative position withing the bgimage, always staying at the same realtive place...

Is this possible?

Greets David
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

Top

Postby WarrenFaith » Fri Jun 12, 2009 9:30 am

If you can provide a minimalistic code sample including your layout-xml I would try it.

Have you tried to get the current width and height of you backgroundimage and calculate the correct position for you icons alone? Should be easy to do so, simple math for :)
WarrenFaith
Moderator
Moderator
 
Posts: 227
Joined: Fri Mar 13, 2009 10:59 am
Location: Berlin, Germany

Postby VIDEN » Fri Jun 12, 2009 9:55 am

Hey,

yes I have thought of just taking the background width and hight and adjusting the icon position according to its size, but than I have to do it all in Java... I actually liked the fact doing all the GUI in xml ;)

Here the important code part. I actually don't touch these Views in java except for registering Listeners.
(res/layout/main.xml and SauterDemo.java)

Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <AbsoluteLayout
  2.  
  3.                                                 android:id="@+id/AbsoluteLayout"
  4.  
  5.                                                 android:gravity="center_horizontal|center_vertical"
  6.  
  7.                                                 android:background="@drawable/zimmer_dunkel"
  8.  
  9.                                                 android:layout_span="1">
  10.  
  11.                                                 <ToggleButton
  12.  
  13.                                                         android:id="@+id/LightToggleBtn"
  14.  
  15.                                                         android:textOn=""
  16.  
  17.                                                         android:textOff=""
  18.  
  19.                                                         android:background="@drawable/licht_toggle_btn"
  20.  
  21.                                                         android:layout_width="wrap_content"
  22.  
  23.                                                         android:layout_height="wrap_content"
  24.  
  25.                                                         android:text="Licht"
  26.  
  27.                                                         android:layout_x="140px"
  28.  
  29.                                                         android:layout_y="100px" />                            
  30.  
  31.                                                 <Button
  32.  
  33.                                                         android:id="@+id/TempButton"
  34.  
  35.                                                         android:background="@drawable/btn_blank_background"
  36.  
  37.                                                         android:drawableLeft="@drawable/btn_temp"
  38.  
  39.                                                         android:layout_height="wrap_content"
  40.  
  41.                                                         android:layout_width="wrap_content"
  42.  
  43.                                                         android:text="@string/sec_temp"
  44.  
  45.                                                         android:layout_y="250dip"  
  46.  
  47.                                                         android:layout_x="140dip"/>
  48.  
  49.                                                 <Button
  50.  
  51.                                                         android:id="@+id/MultistateButton"
  52.  
  53.                                                         android:background="@drawable/btn_blank_background"
  54.  
  55.                                                         android:drawableLeft="@drawable/lueftung"
  56.  
  57.                                                         android:layout_height="wrap_content"
  58.  
  59.                                                         android:layout_width="wrap_content"
  60.  
  61.                                                         android:text=""
  62.  
  63.                                                         android:layout_y="20dip"  
  64.  
  65.                                                         android:layout_x="20dip"/>
  66.  
  67.                                         </AbsoluteLayout>
Parsed in 0.004 seconds, using GeSHi 1.0.8.4


additionally the whole Project is added in the bottom ... It's just a demo for me to kinda get familiar with android.. nothung final or good designed

Thx David
Attachments
AndroidDemo.zip
(621.3 KiB) Downloaded 40 times
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

Postby WarrenFaith » Fri Jun 12, 2009 10:10 am

i will try this as soon as possible :)
WarrenFaith
Moderator
Moderator
 
Posts: 227
Joined: Fri Mar 13, 2009 10:59 am
Location: Berlin, Germany

Postby WarrenFaith » Fri Jun 12, 2009 12:27 pm

I checked your application and i didn't find a way to do this with the xml layout. I think you have to do this programatically.
I found an interesting post discussing this problem but the solution there is more bad practice than anything else, imho. http://groups.google.com/group/android-developers/msg/e3ca2b568cf3109c

I would do this programatically...
WarrenFaith
Moderator
Moderator
 
Posts: 227
Joined: Fri Mar 13, 2009 10:59 am
Location: Berlin, Germany

Postby VIDEN » Mon Jun 15, 2009 3:42 pm

Hey,

thanks for the effort you took upon you!
I have studied the AbsoluteLayout.java a bit and came to the conclusion, that the main work that has to be done to give the layouts children a relative position is to extend it and change the "onLayout" method.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.     @Override
  3.  
  4.     protected void onLayout(boolean changed, int l, int t,
  5.  
  6.             int r, int b) {
  7.  
  8.         int count = getChildCount();
  9.  
  10.  
  11.  
  12.         for (int i = 0; i < count; i++) {
  13.  
  14.             View child = getChildAt(i);
  15.  
  16.             if (child.getVisibility() != GONE) {
  17.  
  18.  
  19.  
  20.                 AbsoluteLayout.LayoutParams lp =
  21.  
  22.                         (AbsoluteLayout.LayoutParams) child.getLayoutParams();
  23.  
  24.  
  25.  
  26.                 int childLeft = mPaddingLeft + lp.x;
  27.  
  28.                 int childTop = mPaddingTop + lp.y;
  29.  
  30.                 child.layout(childLeft, childTop,
  31.  
  32.                         childLeft + child.getMeasuredWidth(),
  33.  
  34.                         childTop + child.getMeasuredHeight());
  35.  
  36.  
  37.  
  38.             }
  39.  
  40.         }
  41.  
  42.     }
Parsed in 0.033 seconds, using GeSHi 1.0.8.4


I could just put percent values in my XML layout for x and y and than calculate them relative to the layouts size.

While this will work for the icons, I am not sure how to handle the background image so that it adjusts to the screen size but still keeps it's aspect ratio... any ideas?

Greets David
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

Postby WarrenFaith » Mon Jun 15, 2009 4:35 pm

First: Well done on extending the layout... great solution.
Second: I would say that you have to do a bit math for the background.
You could make this:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. // more pseudocode than java <img src="http://www.anddev.org/images/smilies/smile.png" alt=":)" title="Smile" />
  3.  
  4. widthRate = layoutWidth() / backgroundWith();
  5.  
  6. heightRate = layoutHeight() / backgroundHeight();
  7.  
  8. rate = Math.min(widthRate, heightRate);
  9.  
  10. newWidth = backgroundWidth() * rate;
  11.  
  12. newHeight = backgroundHeight() * rate;
  13.  
  14.  
Parsed in 0.033 seconds, using GeSHi 1.0.8.4

This sould stretch the background to the border it hits first and keep the ratio because it is multiplied with the rate.

Please keep me informed if it helped you.
Great coding!
WarrenFaith
Moderator
Moderator
 
Posts: 227
Joined: Fri Mar 13, 2009 10:59 am
Location: Berlin, Germany

Postby VIDEN » Tue Jun 16, 2009 10:41 am

Hey,

I've been working on the new AbsoluteLayout Class this morning.
Making the icons position relative was really easy, I actually just had to change 2 lines of the original method:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. @Override
  2.  
  3.         protected void onLayout(boolean changed, int l, int t, int r, int b) {
  4.  
  5.                
  6.  
  7.                 int count = getChildCount();
  8.  
  9.                
  10.  
  11.         for (int i = 0; i < count; i++) {
  12.  
  13.             View child = getChildAt(i);
  14.  
  15.             if (child.getVisibility() != GONE) {
  16.  
  17.  
  18.  
  19.                 AbsoluteLayout.LayoutParams lp =
  20.  
  21.                         (AbsoluteLayout.LayoutParams) child.getLayoutParams();
  22.  
  23.  
  24.  
  25.                 int childLeft = getPaddingLeft() + (lp.x*(r-l)/100);
  26.  
  27.                 int childTop = getPaddingTop() + (lp.y*(b-t)/100);
  28.  
  29.                 child.layout(childLeft, childTop,
  30.  
  31.                         childLeft + child.getMeasuredWidth(),
  32.  
  33.                         childTop + child.getMeasuredHeight());
  34.  
  35.  
  36.  
  37.             }
  38.  
  39.         }
  40.  
  41.         }
Parsed in 0.038 seconds, using GeSHi 1.0.8.4



But I am having problems adjusting the size of the Layout. I'm not sure witch method is the right one to change...
I tried things linke:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.                 setMinimumWidth(layoutWidth);
  2.  
  3.                 setMinimumHeight(layoutHight);
  4.  
  5.                 setMeasuredDimension(layoutWidth, layoutHight);
  6.  
  7.                 getBackground().setBounds(l, t, l+layoutWidth, t+layoutHight);
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


in the onLayout() method using your pseudocode to calculate layoutWidth and layoutHight, but I figured this is the wrong place, since the parent component has already defined the size for the layout by then, giving it the coordinates (l,t,r,b) where it can place its Items...

So I found the onMesure() method which as I believe tells its parent, how big it wants to be...right?
Well as I understood the javadoc, the parent calls mesure() which calls the onMesure() Method in my Class.
I am to mesure my size there and save it via the setMesuredDimension() Method.
So this is the right Method to change!
My only problem is finding the maximum width and hight that my view can have to be able to calculate "rate".

I thought the parameters onMesure(widthMeasureSpec, heightMeasureSpec) could help me here.
I assumed them to be the maximal width and hight may parent is willing to give to me, but the values are really odd (eg. widthMeasureSpec: -2147483328 heightMeasureSpec: -2147483251 ). So they really arn't helpful

So is there a way to get the max size my view can have for everything to stay on the screen? - maybe via the parent?

If I had a doc on how the views are build and which methods are called at what time I could probably find a solution but this way its just trial and error....

Greets

David
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

Postby VIDEN » Tue Jun 16, 2009 11:28 am

oops okay that was a noob mistake...

Just read the doc...

I found how to interpret the onMesure() params here (http://developer.android.com/reference/ ... eSpec.html)

greets
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

finished

Postby VIDEN » Tue Jun 16, 2009 12:51 pm

Okay, everything seemes to be fine and working now... for anyone who is interested in the code, here's the Class:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. @SuppressWarnings("deprecation")
  2.  
  3. public class PanoramaLayout extends AbsoluteLayout {
  4.  
  5.  
  6.  
  7.         public PanoramaLayout(Context context) {
  8.  
  9.                 super(context);
  10.  
  11.                 // TODO Auto-generated constructor stub
  12.  
  13.         }
  14.  
  15.  
  16.  
  17.         public PanoramaLayout(Context context, AttributeSet attrs) {
  18.  
  19.                 super(context, attrs);
  20.  
  21.                 // TODO Auto-generated constructor stub
  22.  
  23.         }
  24.  
  25.  
  26.  
  27.         public PanoramaLayout(Context context, AttributeSet attrs, int defStyle) {
  28.  
  29.                 super(context, attrs, defStyle);
  30.  
  31.                 // TODO Auto-generated constructor stub
  32.  
  33.         }
  34.  
  35.        
  36.  
  37.         @Override
  38.  
  39.         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  40.  
  41.  
  42.  
  43.                 int layoutWidth;
  44.  
  45.                 int layoutHight;
  46.  
  47.                
  48.  
  49.                 // Find out how big everyone wants to be
  50.  
  51.                 measureChildren(widthMeasureSpec, heightMeasureSpec);
  52.  
  53.                
  54.  
  55.                 //Give Layout its maximum size keeping the backgrounds aspect ratio
  56.  
  57.                 if(MeasureSpec.getMode(widthMeasureSpec)== MeasureSpec.AT_MOST && MeasureSpec.getMode(heightMeasureSpec)== MeasureSpec.AT_MOST){
  58.  
  59.                         float widthRate = (float)MeasureSpec.getSize(widthMeasureSpec) / (float)getBackground().getIntrinsicWidth();
  60.  
  61.                         float heightRate = (float)MeasureSpec.getSize(heightMeasureSpec) / (float)getBackground().getIntrinsicHeight();
  62.  
  63.                         float rate = Math.min(widthRate, heightRate);
  64.  
  65.                         layoutWidth = (int)(getBackground().getIntrinsicWidth()*rate);
  66.  
  67.                         layoutHight = (int)(getBackground().getIntrinsicHeight()*rate);
  68.  
  69.  
  70.  
  71.                 }else{
  72.  
  73.                         layoutWidth = getBackground().getIntrinsicWidth();
  74.  
  75.                         layoutHight = getBackground().getIntrinsicHeight();
  76.  
  77.                 }
  78.  
  79.                
  80.  
  81.                 // Account for padding too
  82.  
  83.                 layoutWidth += getPaddingLeft() + getPaddingRight();
  84.  
  85.                 layoutHight += getPaddingTop() + getPaddingBottom();
  86.  
  87.        
  88.  
  89.                 // Write measurements
  90.  
  91.                 setMeasuredDimension(resolveSize(layoutWidth, widthMeasureSpec),
  92.  
  93.                 resolveSize(layoutHight, heightMeasureSpec));
  94.  
  95.  
  96.  
  97.                
  98.  
  99.         }
  100.  
  101.        
  102.  
  103.        
  104.  
  105.         @Override
  106.  
  107.         protected void onLayout(boolean changed, int l, int t, int r, int b) {
  108.  
  109.                
  110.  
  111.                 int count = getChildCount();
  112.  
  113.                
  114.  
  115.         for (int i = 0; i < count; i++) {
  116.  
  117.             View child = getChildAt(i);
  118.  
  119.             if (child.getVisibility() != GONE) {
  120.  
  121.  
  122.  
  123.                 AbsoluteLayout.LayoutParams lp =
  124.  
  125.                         (AbsoluteLayout.LayoutParams) child.getLayoutParams();
  126.  
  127.  
  128.  
  129.                 int childLeft = getPaddingLeft() + (lp.x*(r-l)/100);
  130.  
  131.                 int childTop = getPaddingTop() + (lp.y*(b-t)/100);
  132.  
  133.                  child.layout(childLeft, childTop,
  134.  
  135.                         childLeft + child.getMeasuredWidth(),
  136.  
  137.                         childTop + child.getMeasuredHeight());
  138.  
  139.  
  140.  
  141.             }
  142.  
  143.         }
  144.  
  145.         }
  146.  
  147.        
  148.  
  149. }
Parsed in 0.045 seconds, using GeSHi 1.0.8.4



I have 2 Screenshots in Action below (normal avd skin and 800x600 large skin)

Greets David
Attachments
Android_Demo_7.jpg
Android_Demo_7.jpg (38.34 KiB) Viewed 493 times
Android_Demo_6.jpg
Android_Demo_6.jpg (30.06 KiB) Viewed 493 times
VIDEN
Developer
Developer
 
Posts: 32
Joined: Tue May 12, 2009 9:39 am
Location: Germany

Top

Return to View, Layout & Resource Problems

Who is online

Users browsing this forum: No registered users and 5 guests