I'm working on an android project where I have a set of views (2 TextViews and some checkboxes in a checkbox group) to replicate many time in the same activity.
Is it possible to define the layout only for one set and instantiate it many time?
Also, the views are grouped in a Relative layout, is it possible to position the without the id attributes (to avoid id duplication)?
I would use a ListView for this. Even if you got like 5 items it workd fine. If you got many more items it still works perfect. Take a look at this example.
You can do this by defining the fields you want to reuse in their own xml. you can then use the 'include' tag for where you want them to display.
http://developer.android.com/training/improving-layouts/reusing-layouts.html
You do need to define the id's to position them in the relative layout. What is your concern about replicating the id's.
The other thing worth mentioning is how to use findById() when using 'include'. You can put a id on the include tag (which is effectively the relative layout viewgroup). Find that group first (Cast to viewgroup) and then do a findbyId on that group for what ever view you are after.
I am trying to add content in tab view using "setContent(...)" method
TabHost.TabSpec spec = tabs.newTabSpec("tag1");
spec.setContent(R.id.radioGroup1);
spec.setContent(R.id.button1);
when i add more than one item in setContent(...) using different methods it only prefers the last one.
How can i add two view under a single tab, in this case- radioGroup1 as well as button1 ?
Thanks
you can not directly add more then one view but aleternative is you can add container view (e.g. linear layout) and inside container layout you can add as many views you want for sure
this is exactly what you want..nice example of tab
You have to group the two views into a single one - for example a LinearLayout.
It is typical in Android, that when you do stuff in a callback from the system (like e.g. onCreate or onButtonPressed) that the effect only come active after the user code returns and that the last setting 'overrides' previous ones in the same callback, as you have seen.
I have a view with TabHost and TabWidget which host on every tab a ListView. I need to have an empty view for every ListView. That is on every tab, if corresponding ListView has no items, I need to display another view.
If I have a single tab with a view marked by #android:id/empty id in the layout xml-file, it works perfectly well. But how can the same thing be accomplished for each tab?
I prefer a simple solution with minimum coding. I'd wish Android support something like #android:id/empty1 and #android:id/empty2, but it doesn't.
UPDATE: It's solved. Custom IDs work ok for empty views as well. It was my misunderstanding that only preconfigured Android views with specific ID can serve as empty view.
After short investigation I found out, that custom IDs work ok for empty views as well. It was my misunderstanding that only preconfigured Android views with specific ID can serve as empty view.
Difficult to try and phrase this question, but I will try my best.
Basically, I have an application and I would like to split the code up more. To try and explain this, will give an example of one of my screens.
In my home screen, I have a title, user details, balance, next bill details and usage details. I want to split each of these sections into their own views. So what I have in my main XML file is I have 5 different RelativeLayouts, like this
<RelativeLayout android:orientation="vertical"
android:layout_below="#+id/title" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="#+id/layout1">
</RelativeLayout>
One for each function I want to have on my home screen. And as you can see I also have each layout set below the previous layout, so the order is title, layout1, layout2, layout3, layout4. (The reason I am doing this is, that I want each layout to be interchangable, i.e. I could remove layout2, and order then be title, layout1,layout3,layout4 as I may not need the 2nd layout depending on what is required of the app)
So in my main activity class, I have called each of these layouts.
layoutTitle = (RelativeLayout) findViewById(R.id.title);
layout1 = (RelativeLayout) findViewById(R.id.layout1);
layout2 = (RelativeLayout) findViewById(R.id.layout2);
layout3 = (RelativeLayout) findViewById(R.id.layout3);
layout4 = (RelativeLayout) findViewById(R.id.layout4);
Then I use layout inflator like so
View view;
LayoutInflater inflater = (LayoutInflater) getBaseContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.userdata, null);
to set up the layout for each layout I have defined in my xml file.
What I want to know is, is it possible to inflate another activity rather than an XML file? The reason I ask this is, that each function I said the home screen is made up of, title, user details, balance etc, I have an activity for each of these. Each of these functions has custom functionality that I have designed, such as animation etc. If I simply inflate these xml files, then I can't access the widgets inside so I can't set up the functionality from Java which is what I need.
If I was able to inflate another activity, then this would not be a problem, as I would set up the functionality for each function in activity, then just inflate that class.
I hope my question was clear, if not I can expand on any areas you are not sure about.
Would be very grateful for any assistance!!
EDIT: If it is not possible to inflate a class, then is there any other way method you could recommend that could solve my problem?
I do exactly the same as you.
I use composition in my Java activities to achieve the sharing of functionalities across my activities. I think of activities as "context", and not as parts of my page that get replicated. So when I am in a certain context (an activity), I then display layout1, layout2 and layout3 with specific parameters, and specific contents that depends on that activity. On another activity, layout1, 2 or 3 could be different, but they have the same location on my screen all the time.
I use composition through views: all my activities have a superclass (call it anything you want, something like ActivityWithCustomLayout, which contains all my layout as class members (as ViewGroup). They are protected, so each of the variables layout1, layout2 and layout3 are available to all subclass activities of this superclass.
And when on a specific activity, I populate each of the layouts on my onCreate method with:
layout1.addView(...something inflated from an XML that depends on that specific activity...);
layout2.addView(...same principle...);
So in fact all my XML layouts are "parts" of activities, which I inflate at runtime into views, that I add dynamically to my activity when needed.
You're right, these explanations are not easy :)
If you target Android >= Honeycomb (including ICS) then have a look at the Fragment framework, it may be a simpler way to achieve all of that (haven't had a look at that yet).
Not too much of an answer but I often find myself subclassing the layouts themselves. Then, in the onFinishInlate() callback, I wire up all of my view references using findByViewId. In your XML, you can replace <RelativeLayout> with <com.company.CustomLayout>, assuming that your CustomLayout is a subclass of RelativeLayout.
As mentioned, you can then pull them out into separate files and include them with the include tag. This makes refactoring easy and allows you to reuse the layout components.
Or, if you inflate these subclassed layouts from within your code, you don't have to worry about all the messy findViewById calls in your activity.
Fragments are also great and have similar life cycles to an activity. Good luck!
I'm not sure that you need to inflate all of those Views from within your Activity. Look into using the include and merge tags within your Layout. This should help get you started: http://developer.android.com/resources/articles/layout-tricks-merge.html
You can also toggle the visibility of your Layouts. So, you can declare them in XML, initialize them as visibility="false", and then toggle that visibility in your Java code.
You also stated: "If I simply inflate these xml files, then I can't access the widgets inside so I can't set up the functionality from Java which is what I need."
You can access any Layout component after it has been added to your Activity using findViewById and casting the object it returns to the appropriate type.
I have defined two views ExampleView1, ExampleView2, ExampleView3 and ExampleView4 in resources.
In my Activity I have an empty ViewFlipper. Based on doing some logic I want to add either ExampleView1 and ExampleView2 to the ViewFlipper and show the view.
Later I want to add based on internal logic either ExampleView3 and ExampleView4.
How do I do this? Is there some tutorial or can someone help me with example code?
Just use the addView method, which ViewFlipper inherits from ViewGroup. If your views are custom ones, you will have something like this:
flipper.addView(new ExampleView1());
On the other hand, if the views are defined inside an XML layout, you will have to inflate them first:
View view = LayoutInflater.from(context).inflate(R.layout.your_view, null);
flipper.addView(view);