Pass on Layout IDs dynamically
Question
I want to implement a 'favorite list' and let's assume that I have got an empty layout. At onCreate()
there is super.onCreate(savedInstanceState); setContentView(R.layout.main);
and then I open a database with my favorite animals, load a few things and add dynamically buttons to the layout.
The database schema is this:
CREATE TABLE animals(_id INTEGER PRIMARY KEY, name TEXT NOT NULL, layout TEXT NOT NULL)
and in the database there is:
_id - - - - - - - - name - - - - - - - - - layout
1 - - - - - - - - -- cat - - - - - - - - -- R.layout.cat
2 - - - - - - - - -- dog - - - - - - - - -- R.layout.dog
3 - - - - - - - - -- turtle - - - - - - - - R.layout.turtle
Of course the layouts/xml-files (R.layout.cat, R.layout.dog, R.layout.turtle)
exist.
So then you see three buttons saying cat, dog and turtle. In the OnClickListener
there is the following:
Intent intent = new Intent(MyFavorites.this, Animal.class);
Log.d ("onClick", button.getmyLayout());
// Shows either R.layout.cat, R.layout.dog or R.layout.turtle
// depending on what button was pressed. This works fine.
intent.putExtra("myLayout", button.getmyLayout());
// closes the database
myDbHelper.close();
startActivity(intent);
The Animal.class
can show all animal-xml-files because they all have the same functionality. This is why the layout is always passed on to the same class!
The Animal.class:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final int myLayout = getIntent().getIntExtra("myLayout", R.layout.main);
setContentView(myLayout);
}
Now here is the problem. I pass on a String and not an Integer and in the log cat there is:
Key myLayout expected Integer but value was a java.lang.String. The default value 2130903044 was returned.
The default value is R.layout.main which you find in the autogenerated R.class
as a hex number and in decimal it is 2130903044. So I do understand the error message. But I cannot think of another way to solve this problem. I was thinking about getters and setters
in the R.class
but of course they will be deleted at the next build.
OTHER TIPS
If your amount of layouts is finite and reasonable (you define reasonable %) I would propose to use just static map:
static Map<String,Integer> layouts = new HashMap<String,Integer>()
static {
layouts.put("cat",R.layout.cat);
...
layouts.put("unicorn",R.layout.unicorn);
}
This way you will get compile time safety, and it would be faster at the runtime.