Say I have a layout file that I would like to use as part of another layout, how would I do that?
For example, I have a table layout at /res/layout/table.xml. I want to use that table as a component inside a relative layout at /res/layout/relative_stuff.xml. Say my relative layout is to contain the table and two buttons.
The simple case is to do the combination completely inside the relative_stuff.xml file. But a better case would be the ability to set the table xml programmatically: the reality is I want to choose from many different tables, for now say two tables at: /res/layout/table_1.xml and /res/layout/table_2.xml.
So basically my main layout file is /res/layout/relative_stuff.xml. And I want to set either of two tables inside it programmatically.
You an re-use layouts using an include tag.
For example, using your example layout/table.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
<include layout="#layout/table"/>
</LinearLayout>
If you don't want to do it in XML, you can use a LayoutInflater to inflate your XML and add it to whatever container you are using.
LayoutInflater mLayoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
View tableLayout = mLayoutInflater.inflate(R.layout.table, (ViewGroup) findViewById(R.layout.root_id));
rootLayout.addView(tableLayout);
You can use Layout Inflator Service to add multiple add the activity.
Related
I have a custom view called CustomImageView.
I would like to create an xml file with this view so I inflate the view and add it programmatically to my current layout. (depending on orientation , I will decide where to add it)
Is it possible to so something like this in the xml without a containing layout
<?xml version="1.0" encoding="utf-8"?>
<CustomImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="wrap_content"
android:height="wrap_content"
android:level="2"
android:anotherattr="adsad" />
After that I will inflate it. or should I put it in a Layout like LinearLayout? I just want an xml with my view so I can inflate it and add to my existing layout.. I am not sure what the containing layout would be!
This is perfectly legitimate. You can do it with built-in or custom views. Here is an example from the Android framework. It's an XML layout file containing a single TextView, representing a default ListView row layout. The TextView has several attributes assigned to it in XML, just as your custom view will.
Is it possible to so something like this in the xml
Yes you can inflate an XML that just contains one view. But why not just create the view programmatically? new CustomImageView(...)
depending on orientation , I will decide where to add it
Consider using the layout directories such as "layout-land" to automatically inflate different layouts based on orientation - that's what those are for. Read more about this Supporting Different Screens
I am not sure what the containing layout would be
Use the layout directories and it removes all doubt
I have a requirement where there are 2 programatically generated screens and 2 xml layouts. Now i need to on the fly combine, these layouts multiple times.
For ex, i have screen 1 - programatically created, screen 2 - programatically created, screen 3- from a xml layout, screen 4 - from a xml layout
My final layout design should be a single screen with screen1, screen2, screen 3, screen 4, screen 2... with all screens sharing equal screen space based on the number of screen i input. Please let me know the approach. Some screens are having relative layout and some linear ones. So it should combine these.
You'll need to invoke addView() on the primary layout. Once the primary layout is built (which holds all the other layouts), the addView() method will add new views to the existing primary layout.
To add the new layout, you'll need to inflate it first.
LinearLayout primaryLayout;
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
LinearLayout newLayout = (LinearLayout)layoutInflater.inflate(R.layout.your_new_layout, null, false);
primaryLayout.addView(newLayout);
AddView also provides an index option to place the new layout at a specific point in the primary layout.
Try starting with a blank, XML layout (say called primary_layout):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/primaryLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
Then, as your activity starts, set that first, then inflate and add as desired:
setContentView(R.layout.primary_layout);
LinearLayout primaryLayout = (LinearLayout) findViewById(R.id.primaryLayout);
Then you can add your new views to that one. As for adding multiple times, I believe that it's done by reference, so it only sees a single view. Try building the view in a method, and just returning the view. Such as:
private View buildNewView(){
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
LinearLayout newView = (LinearLayout)layoutInflater.inflate( R.layout.my_new_view null, false );
return newView ;
}
And call it via primaryLayout.addView(buildNewView();.
You could look into Fragments. They seem to do exactly what you need. Here are the links to the Training and API Guides on them.In your xml file, you can specify 4 child layouts inside a LinearLayout parent, each with an attribute android:layout_weight="1", so each child layout would only take up the same amount of space. If in portrait orientation, it is suggested to set android:layout_width="match_parent and android:layout_height="0dp" Now, you can label the id's of each child layout as id1, id2, id3, etc, but you can also label the two layouts you will create as something likeandroid:id="#+id/fragment_container_first and android:id="#+id/fragment_container_second.In the Java code, you would set the contentView as the id of the xml file (setContentView(R.layout.myXMLLayout);), create two instances of a Fragment by following the Training guide link I provided above, and add those views to the containers you setup earlier inside your xml files by using something like getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container_first, firstFragment).commit(); and getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container_second, secondFragment).commit();(If you are using the support library, which is what the training guides use).I really hope this helps you out. You can build a really flexible UI with Fragments. For instance, later on, you can replace the first two fragments with other fragments at runtime, increasing flexibility. You can even setup different UIs for different screen sizes, with a more compact view on a phone, but with much more to offer on a larger screen like a tablet.I'd love to hear back if this helped you out!
I have a Layout that I want to populate with items consisting of 2 textviews and one button. I do not know before hand how many items that will populate my Layout.
Since I don't know when writing the layout.xml how many items I want to add, thats means that I have to add the items in the java instead of the xml. But I do not like to build GUI in java because it looks ugly.
Does anyone know if I can create an xml file for my item and then add new items to my layout during execution?
I have written some pseudo code to try to demonstrate what I want to accomplish:
MainLayout.xml
//My empty Layout
<Layout myMainLayout >
</RelativeLayout>
Fragment_post.xml
//one post
<TextView/>
<TextView/>
<Button/>
In the code somewhere
setContentView(R.layout.MainLayout);
MyMainLayout.addFragment(R.layout.Fragment_post);
You can add your fragment_post.xml wherever you want:
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout view=(LinearLayout)inflater.inflate(R.layout.yourfragment, null);
yourLayout.addView(view);
Please don't confuse a Fragment with a piece of the GUI. See here for details: http://developer.android.com/guide/components/fragments.html
Sure you can do this. Just set an initial empty layout to your activity.
onCreate()
{
setContentView(R.layout.initial_layout);
}
Then get and keep a reference to main layout.
LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout mainLayout=(RelativeLayout)inflater.inflate(R.layout.initial_layout, null);
Next, add new views to your layout as and when you need them.
LinearLayout view=(LinearLayout)inflater.inflate(R.layout.fragment_post, null);
mainLayout.addView(view);
But note that what you refer to as fragments here are not what android refers to as fragments. Learn about actual android fragments here:
http://developer.android.com/guide/components/fragments.html
I am trying to add rows to a TableLayout that I define in an XML file. The XML file contains a header row for the table.
I can add new rows quite well using info from various tutorials but the code required for setting up the layout for the new rows is a horrendous mess and it seems like a pain in the ass to maintain whenever the layout for the header row changes.
Is it possible to create new rows to a TableLayout while still defining the row layout in XML? For example define a template row in XML, obtain a handle to it in code and then clone the template whenever I need it.
Or is the right way to do this somehow completely different?
Your proposed approach will work fine and it more or less matches the common pattern used when populating ListView items.
Define a layout that contains a single row. Obtain a LayoutInflater by using LayoutInflater.from(myActivity). Use this inflater to create new rows using your layout like a template. Generally you will want to use the 3-argument form of LayoutInflater#inflate passing false for the third attachToRoot parameter.
Let's say you wanted to use a template layout with a label and a button in each item. It might look something like this: (Though yours would define your table rows instead.)
res/layout/item.xml:
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/my_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button android:id="#+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Then at the point where you inflate:
// Inflate the layout and find the component views to configure
final View item = inflater.inflate(R.layout.item, parentView, false);
final TextView label = (TextView) item.findViewById(R.id.my_label);
final Button button = (Button) item.findViewById(R.id.my_button);
// Configure component views
label.setText(labelText);
button.setText(buttonText);
button.setOnClickListener(buttonClickListener);
// Add to parent
parentView.addView(item);
I'm coming from the world of GWT and UIBinder, where I'm used to defining custom components by extending Composite, and then putting all the UI layout code in a MyComponent.ui.xml file. This is a very nice way to build up components from smaller pieces.
I'm trying to achieve the same effect on Android with custom Views. I've been able to programmatically extend View, and then add objects by calling addView(textView). I'd like to be able to do that in XML, but I don't see how to associate an xml layout file with the view (apart the primary res/layout/main.xml file, which provides the primary layout for the app.
How can I layout my custom views in XML?
Edit: My question was unclear. What I'm looking to do is associate a my_widget.xml file with my customized view. Then in my_widget.xml I'd like to define various TextViews, etc, and plug them into my View class.
Use the fully qualified name of your custom view class in place of one of the built-in views. Here's a layout, for instance, that fills the window with your class:
<?xml version="1.0" encoding="utf-8"?>
<my.package.MyCustomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
To construct Views from XML, use LayoutInflater.
You can use findViewById (int id) with an id defined in XML. See the example in the android doc here (scroll down to IDs).