use a single layout xml file for an activity? - android

Is it possible to use a single xml file for the "whole layout" (activity)?
Can you "embed" the row layout, that is in a separate file, to the listview in the main layout xml?
So it look something like this
<LinearLayout>
...
<ListView>
<LinearLayout>
<ImageView>
<TextView>
...
</LinearLayout>
</ListView>
</LinearLayout>
If it is possible, how is it done, how do you use "id", adapter etc then?
Because you could use
<listview>
...
</listview>
and not only
<listview .../>
...I thought it maybe could be possible to put the row layout directly there inside, but dont know how to do, to get it to work if it is possible. Is it?
Would like to have one single layout xml file, per activity, instead of many small parts. Would be easier to get the whole picture then I think and simplify stuff. Any other ways to do achieve this maybe?

Its definitely possible to use single xml for listview and its cell layout
It will go like this
You are creating two layouts in xml
<LinearLayout android:id="#+id/listview_layout"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<ListView android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:id="#+id/cell_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
.............do your cell layout here
</LinearLayout>
Here use listview_layout for setting your ContentView
setContentView(listview_layout)
and use cell_layout in any adapter to set cell layout
you will find good tutorials for setting custom adapters for listview on StackOverFlow
Hope this will solve your problem

Related

Setting ListView heights with 2 ListViews in 1 LinearLayout

Here is my xml file for my layout:
<com.handmark.pulltorefresh.library.PullToRefreshScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pull_to_refresh_scrollview_feat"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ListView
android:id="#+id/listViewFriends"
android:layout_width="match_parent"
android:layout_height="1100dp" >
</ListView>
<ListView
android:id="#+id/listViewTrending"
android:layout_width="match_parent"
android:layout_height="1100dp" >
</ListView>
</LinearLayout>
</com.handmark.pulltorefresh.library.PullToRefreshScrollView>
For some reason, the only way to show both ListViews is by setting height in actual dp's. I can't use wrap_content or layout_weights.
Is this a limitation of using multiple ListViews? Or am I doing it wrong?
I simply scrapped this idea and used a MergeAdapter and got what I was looking for.
I assume PullToRefreshScrollView is some sort of ScrollView. You should not use a ListView inside a ScrollView; they just do not play well together. Not only must you must set an explicit layout height for the list(s), but the two views will get in each other's way in dealing with touch events.
If you promote the LinearLayout to the top of the container hierarchy, you can set the following attributes for each ListView:
. . .
android:layout_height="0dp"
android:layout_weight="1"
. . .
They should then take up the same vertical space.
I have not tried this, but could you set layout_height=0dp and layout_weight=1 to your ListViews and see what happens?
Hope it helps.

Edit Text and Text View not visible when ListView is set in Android

here my xml layout of my Android app (where I show all of my contacts)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip"
android:text="Scegli il contatto:"
/>
<EditText
android:id="#+id/editTextSend"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<ListView
android:id="#+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
I fill ListView using a custom Adapter.
But textView and Edit Text are not visibile. I want to show in particular edit text where users can write initial letters of his contacts name)
Suggestions to get them visible?
I fill ListView ... But textView and Edit Text are not visibile.
If you can only see a ListView then it appears you're using a ListActivity and forgot to call setContentView(). So you aren't actually using your layout... you only see ListActivity's default ListView.
That said, your XML code will work, but here are some quick notes:
As I stated in my comment, the TextView might be hidden depending on what type of Activity or Fragment you are using:
A ListActivity will automatically bind the #+id/android:empty and #+id/android:list Views, so the "empty" TextView is only shown when the ListView is empty.
An Activity won't recognize #+id/android:empty on its own. All the Views should be visible.
fill_parent is deprecated, simply use match_parent
Setting a ListView's height to wrap_content forces the Adapter to draw the ListView multiple times... with your layout I recommend using match_parent.
I'd say it is visible pretty fine with your layout. But anyway, I'd make listview declared that way:
<ListView
android:id="#+id/android:list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
so it will take all the remaining free space

How can I set a footer in an android listview to dynamically stretch to the bottom?

I searched already but unfortunately found no real solution to this. I have added a footer to a listview with:
View footer = getLayoutInflater().inflate(R.layout.listfooter, null);
listview.addFooterView(footer);
The xml for the footer looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/footer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="#FFFFFFFF"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:background="#ee222222"
>
<TextView
android:id="#+id/info"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Test Test Test"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
It does display a footer only as a single line
I change the number of rows in the list dynamically but I want the footer to always fill the rest of the listview if there are not enough items in it.
How can I do this?
Edit: I added an image, the left is how it is right now and the 2 on the right is what I want.
I can say the best solution can be for this problem is.
1) Create a XMl layout which must have hierarchy like this.
<Liniear Layout>
<ScrollView>
<LinearLayout>
<ListView>// add your list data here.
<\ListView>
<TextView><TextView>// for footer text
<\LinearLayout>
<ScrollView>
<LinearLayout>
Please let me kno if anything, I hope this approach will work as I tried it myself.

Can some clarify usage of <include> and <merge>

I just need someone to tell me if I understood correctly when to use <include> and when <merge>.
So, I make a header layout which I want to include into some other XML layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Header text" />
</LinearLayout>
And I include it into some other XML this way (which is pretty basic):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include
android:id="#+id/header"
layout="#layout/top"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
This will work well, no issue about it. But in order to optimize the code, I have to use <merge> in the layout which gets included. So the top layout should not have a tag <LinearLayout> but it must look like this:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Header text" />
</merge>
Have I understood this correctly?
From my understanding it will set the merge element as the higher element in the view hierarchy. Include will simply put the whole viewgroup in there. So using your example the view hierarchy should look like:
With merge:
LinearLayout (root)
|
TextView
With include:
LinearLayout (root)
|
LinearLayout
|
TextView
So you will have an extra LinearLayout in the view hierarchy that you do not need. However, sometimes you need that intermediate view. In your case, you wouldn't, since both the LinearLayouts have the same layout params and no other differences.
Yes you understood it correctly. merge is used as pseudo parent element to reduce the number of levels in view trees.
Just check this link, it gives very good explanation of merge.
In your header file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include
android:id="#+id/header"
layout="#layout/top"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout> doesn't make any difference when your file is included in other file you mentioned. So it's a good thing to use merge instead.
Since in XML you must use a single parent element and the rest of the XML elements should be included in it, you should use merge as single parent element and can avoid adding unnecessary parent layout.
Just avoid 'merge' when you want to apply a layout differently than layout is defined in file in which your content is inclded.

Reserve a "slot" in a layout XML file for a dynamically created button?

In my app, I have one (and only one) UI element which isn't referenced in the XML layout file.
That element is a button, instantiated and returned at run-time by a 3rd party library (i.e. I don't have control over that).
My problem is that I would like some of the elements (TextViews) in the XML layout file to be placed relative to that button, using RelativeLayout.
Is it possible to "reserve an empty slot" in the XML layout file for that button such that I can do something like the following?
<TextView android:id="#+id/tv_text_under_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/btn_dynamically_created_button"
android:text="" />
Alternatively, if I were to set the layout at run-time using RelativeLayout.LayoutParams.addRule(), what would be the ID of that dynamically created button, if it has no reference at all in the XML layout file?
For example, in the following call:
layoutParams.addRule(RelativeLayout.BELOW, R.id.btn_dynamically_created_button);
What would I put instead of R.id.btn_dynamically_created_button?
Update: Thanks to the answer below, I created a place holder like this:
<LinearLayout android:id="#+id/btn_dynamically_created_button"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</LinearLayout>
The challenge now is: How to associate the returned object from getDynamicallyCreatedButton() (returned object is subclass of LinearLayout, not Button), with R.id.btn_dynamically_created_button?
EDIT: This thread seem to address a similar issue, but I am not sure that I understand the solution offered.
I'd suggest:
Put a LinearLayout with width/height set to wrap-content, horizontal orientation and zero padding as the placeholder.
Orient all the other things to that LinearLayout.
When its time to put the button, simply stick it into the LinearLayout.
See if that works for you.
EDIT: attempt at a short example:
The layout (suitably shortened): you can place other components relative to the LinearLayout with id LinearLayout01.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_marginTop="2sp" android:layout_marginBottom="2sp" android:layout_height="wrap_content">
<LinearLayout android:id="#+id/LinearLayout01" android:layout_height="wrap_content" android:layout_width="wrap_content" android:gravity="right" style="#style/SimpleButtonBar" android:layout_below="#+id/rootlayout" android:layout_alignParentBottom="true">
</LinearLayout>
<ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentTop="true" android:layout_above="#+id/LinearLayout01" android:fillViewport="true">
<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="#+id/detaillayout">
</RelativeLayout>
</ScrollView>
</RelativeLayout>
The code (for example, this would go in onCreate): fetch your button (you need to make sure it has the right Context, but I figure you're doing that alright), fetch the LinearLayout, create a layout parameters object and stick your button into the LinearLayout.
Button b = getButton(); // retrieve your button somehow
LinearLayout l = (LinearLayout)findViewById(R.id.LinearLayout01);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
l.addView(b, lp);

Categories

Resources