Skinning Layouts

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

Skinning Layouts

Postby timhoeck » Sat Jan 31, 2009 2:05 am

I want to "skin" a certain layout for my app, so my idea was to just have multiple layouts containing the different "skin" setups - each layout containing the same IDs of views that I need to access (EditText, ImageViews, etc.). I would then just use setContentView() to load the new "skin".

The problem is, apparently using the same ids on multiple layouts doesn't work. If I switch the layout using setContentView, code modifying views that have the duplicate IDs do not work.

I don't want to have to read xml into a dynamically created layout, when it is already so easy to create and switch xml layouts. What am I missing?
timhoeck
Junior Developer
Junior Developer
 
Posts: 22
Joined: Fri Jan 16, 2009 4:41 pm

Top

Postby Emmanuel7 » Sat Jan 31, 2009 11:19 am

Can't you just use 'theme' to have different looks for your application ?
Emmanuel7
Senior Developer
Senior Developer
 
Posts: 164
Joined: Fri Dec 12, 2008 2:17 am
Location: Paris

Postby darolla » Sat Jan 31, 2009 1:42 pm

User avatar
darolla
Master Developer
Master Developer
 
Posts: 273
Joined: Thu Sep 25, 2008 5:16 pm
Location: Dortmund, Germany

Postby timhoeck » Sat Jan 31, 2009 9:37 pm

Thanks guys,

My issue with styles/themes is this.. and maybe I am just not familiar enough with them yet.

Can I:

a) Set styles which control the physical settings/location of the items I am styling, such as layout margins, height and width? In examples, I only see the option to set appearance settings.

b) How do you apply a style to an item dynamically? I can set a style of a particular item before runtime through the editor (or XML), but how can I do this via code? The only thing I am aware of to apply styles is setTheme(), which applies to the entire activity, and not to individual items in the layout, like a specific View.
timhoeck
Junior Developer
Junior Developer
 
Posts: 22
Joined: Fri Jan 16, 2009 4:41 pm

Postby darolla » Sun Feb 01, 2009 10:15 am

please take a look at the links !

or at the docu !
User avatar
darolla
Master Developer
Master Developer
 
Posts: 273
Joined: Thu Sep 25, 2008 5:16 pm
Location: Dortmund, Germany

Postby pskink » Sun Feb 01, 2009 1:45 pm

timhoeck wrote:Thanks guys,

My issue with styles/themes is this.. and maybe I am just not familiar enough with them yet.

Can I:

a) Set styles which control the physical settings/location of the items I am styling, such as layout margins, height and width? In examples, I only see the option to set appearance settings.

b) How do you apply a style to an item dynamically? I can set a style of a particular item before runtime through the editor (or XML), but how can I do this via code? The only thing I am aware of to apply styles is setTheme(), which applies to the entire activity, and not to individual items in the layout, like a specific View.


ad a) sure, you can use any R.styleable value

ad b) good question: i dunno
pskink
pskink
Master Developer
Master Developer
 
Posts: 719
Joined: Mon Nov 24, 2008 3:49 pm

Top

Postby darolla » Sun Feb 01, 2009 2:45 pm

for all XML attributes there are setter.

e.g. button.setbackground (selector stuff).

greetings,
daroll
User avatar
darolla
Master Developer
Master Developer
 
Posts: 273
Joined: Thu Sep 25, 2008 5:16 pm
Location: Dortmund, Germany

Postby timhoeck » Sun Feb 01, 2009 8:02 pm

Again, thanks. I have been reading through style/theme examples. I guess I can use the setters to do what I want for now. As I learn more about the styles, I can begin using those. I think I may have found a partial answer for b) though:

Code: Select all
Theme t;
t.applyStyle(int resid, boolean force);


http://code.google.com/android/reference/android/content/res/Resources.Theme.html

I also found an interesting thread here explaining how to at least get specific attributes in your theme.


I'm still trying to figure out how to specify a specific style to a specific item. I understand I can do general styles for existing Android components, say Widget.EditText.. but how can I specify that a style applies to a specific EditText only.... When creating your layout I believe you can add the style attribute to an item.. but what makes it more confusing is that style doesn't show up in the properties list for an item in Eclipse. There is also no setStyle method for a view (but there IS a setScrollbarStyle)... why is that?
timhoeck
Junior Developer
Junior Developer
 
Posts: 22
Joined: Fri Jan 16, 2009 4:41 pm

Postby pskink » Sun Feb 01, 2009 10:21 pm

timhoeck wrote:
I'm still trying to figure out how to specify a specific style to a specific item. I understand I can do general styles for existing Android components, say Widget.EditText.. but how can I specify that a style applies to a specific EditText only.... There is also no setStyle method for a view (but there IS a setScrollbarStyle)... why is that?


i agree, it's a bit strange that you cannot setStyle for a view (while you can specify for any view style="anyDefinedStyle" in your layout .xml file). i'm also trying to resolve that mystery
pskink
pskink
Master Developer
Master Developer
 
Posts: 719
Joined: Mon Nov 24, 2008 3:49 pm

Postby pskink » Sun Feb 01, 2009 11:16 pm

pskink wrote:
i agree, it's a bit strange that you cannot setStyle for a view (while you can specify for any view style="anyDefinedStyle" in your layout .xml file). i'm also trying to resolve that mystery


i think i found how style="myStyle" defined in layout xml works. no magic: tool that 'compiles' resource files simply includes your defined attributes when it finds style="..."

it leads me to think there is no any setStyle at all (however i still don't understand why we have generated R.style.* for)
pskink
pskink
Master Developer
Master Developer
 
Posts: 719
Joined: Mon Nov 24, 2008 3:49 pm

Postby timhoeck » Mon Feb 02, 2009 2:43 am

Well, applyStyle should work in order to change styles dynamically, but since I haven't figured out how to apply a style to a specific view only, it doesn't help my situation.

While I am still trying to figure out styles, what is the difference in a style, and making something styleable?

I'm having further fun setting things with the setters: I use relative layouts, so I am trying to set height and width values using:

Code: Select all
View bg = (View) findViewById(R.id.background);
bg.setBackgroundResource(R.drawable.bg_one);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_HORIZONTAL);
params..height = 116;
params.width = 302;
params.topMargin = 10;
bg.setLayoutParams(params);


The height and width parameters are integers, only allowing pixel settings... how do I do dip? According tohere, layout_height and layout_width in XML format can be specified in other dimensions, but height and width settings in code can only be pixels... argh!
timhoeck
Junior Developer
Junior Developer
 
Posts: 22
Joined: Fri Jan 16, 2009 4:41 pm

Postby pskink » Mon Feb 02, 2009 11:28 am

i got answer for setStyle from two android engineers:

http://groups.google.com/group/android- ... 2abe6daa56?

so thread about setStyle is over...
pskink
pskink
Master Developer
Master Developer
 
Posts: 719
Joined: Mon Nov 24, 2008 3:49 pm

Postby pskink » Mon Feb 02, 2009 11:42 am

timhoeck wrote:
The height and width parameters are integers, only allowing pixel settings... how do I do dip?


i found it. see android.util.TypedValue.java line 311, method applyDimension:

DisplayMetrics metrics;
...
return value * metrics.density;
pskink
pskink
Master Developer
Master Developer
 
Posts: 719
Joined: Mon Nov 24, 2008 3:49 pm

Postby timhoeck » Mon Feb 02, 2009 9:21 pm

Thanks for the followup answers.

Wow... no dynamic change of styles. That's... interesting. You can change attributes individually, but not change the style? Doesn't really make sense to me.

Since you can parse an existing style, maybe it's possible to create our own setStyle method, setting the attributes as needed.

Here's what I ended up with, with some example of setting Relative layout settings:

Code: Select all
private void changeSkin() {
   //Views involved in Skinning
   View layout = (View) findViewById(R.id.layout);
   View bg = (View) findViewById(R.id.background);
   View txtSearch = (View) findViewById(R.id.txtSearch);
   View icon = (View) findViewById(R.id.icon);
   
   //Setup layout parameters for each skinnable item
   RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
   RelativeLayout.LayoutParams bgParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
   RelativeLayout.LayoutParams txtParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
   RelativeLayout.LayoutParams icoParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
   
   // Retrieve saved Skin ID from preferences
   SharedPreferences settings = getSharedPreferences("MySettings", 0);
   int currentSkin = settings.getInt("skin", SKIN_DEFAULT);
   
   switch (currentSkin) {
      case SKIN_ONE:
         //Configure Layout View
         layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
         layoutParams.width = 302;
         layoutParams.height = 116;
         layoutParams.setMargins(10, 10, 10, 0);
         
         //Configure Background View
         bg.setBackgroundResource(R.drawable.bg_one);
         bgParams.addRule(RelativeLayout.CENTER_HORIZONTAL, R.id.layout);
         bgParams.width = 302;
         bgParams.height = 116;
         
         //Configure EditText View
         txtParams.addRule(RelativeLayout.CENTER_HORIZONTAL, R.id.layout);
         txtParams.setMargins(5, 63, 5, 0);
         
         //Configure Icon View
         icoParams.addRule(RelativeLayout.CENTER_HORIZONTAL, R.id.layout);
         icoParams.setMargins(0, 8, 0, 0);
         icoParams.height = 36;
         icoParams.width = 36;

         break;
      case SKIN_TWO:
         layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
         layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
         layoutParams.height = 98;
         layoutParams.width = 302;
         layoutParams.setMargins(10, 10, 10, 0);
         
         bg.setBackgroundResource(R.drawable.bg_two);
         bgParams.addRule(RelativeLayout.CENTER_HORIZONTAL, R.id.layout);
         bgParams.height = 98;
         bgParams.width = 302;
         bg.setLayoutParams(bgParams);
         
         txtParams.width = 237;
         txtParams.setMargins(10, 26, 0, 0);
         
         icoParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, R.id.layout);
         icoParams.setMargins(0, 30, 12, 0);
         icoParams.height = 36;
         icoParams.width = 36;
         break;
      default:
         layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
         layoutParams.height = 50;
         
         bg.setBackgroundResource(R.drawable.bg_default);
         bgParams.height = 98;
         
         txtParams.setMargins(5, 5, 45, 0);
         
         icoParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, R.id.layout);
         icoParams.setMargins(0, 8, 5, 0);
         icoParams.height = 36;
         icoParams.width = 36;
         
   }
   layout.setLayoutParams(layoutParams);
   bg.setLayoutParams(bgParams);
   txtSearch.setLayoutParams(txtParams);
   icon.setLayoutParams(icoParams);
}


Everything is still pulling from existing resources, so I will want to pull these values from an xml in the future, maybe I can use LayoutInflator? But for now I can have a few custom skins built into my app.

Seems like so much work when Android supports themes.
timhoeck
Junior Developer
Junior Developer
 
Posts: 22
Joined: Fri Jan 16, 2009 4:41 pm

Top

Return to View, Layout & Resource Problems

Who is online

Users browsing this forum: No registered users and 12 guests