Android ListFragment #id attribute - android

I place two ListFragment in my MainActivity.
This is the ListFragment xml file: fragment1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false" />
</LinearLayout>
My question is, why must I use android:id="#id/android:list" here? When I use, e.g., #+id/frag_list, the program crashes with Error "inflating class fragment".

ListActivity has a default layout that consists of a single, full-screen list in the center of the screen. However, if you desire, you can customize the screen layout by setting your own view layout with setContentView() in onCreate(). To do this, your own view MUST contain a ListView object with the id "#android:id/list" (or list if it's in code). Its same when your class extends ListFragment.
For more info do check the docs
http://developer.android.com/reference/android/app/ListActivity.html.
You can extend Fragment instead of ListFragment. Have a custom layout with ListView. Then you can provide any id for your listview.

Related

Custom view xml versus its usage

I have a custom view CustomSettingEntry this is its xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout_custom_setting_entry_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/custom_setting_entry_title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
Then I use it in a fragment and assign it an id:
<com.mypackage.name.CustomSettingEntry
android:id="#+id/layout_notification_setting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:setting_title="#string/title"
app:setting_subtitle="#string/subtitle" />
My question is what's the difference between the LinearLayout with id layout_custom_setting_entry_container and the usage with id layout_notification_setting? do they refer to the same thing?
If I set a click listener on the custom view inside the fragment, then later in some condition disabled clicking on the root LinearLayout inside the custom view, will this stop the listener?
I understand your custom view is a subclass of LinearLayout which inflates an xml layout. If so, the resulting view hierarchy is
[LinearLayout (actually a CustomSettingEntry), id : layout_notification_setting]
[LinearLayout, id : layout_custom_setting_entry_container]
...
So there are two levels of viewgroups, each one with it own id.
By the way this is inefficient because, the outer viewgroup (your custom class) has only one child (the root of the xml).
On solution is to use a <merge> as root of the xml layout to skip one level. See Optimize by merging or Inflating layout for your custom view
for more details.

Fragment in LinearLayout not appear without layout_weight property

I have two fragments (MyListFragment, MyDetailFragment) in one activity(MyActivity). The first fragment is a list of items, the second one is detail of an item (which is another list, but I think it doesn't matter). The first list fragment is shown when MyActivity starts.
MyListFragment view:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment class="myapp.ActionsList"
android:id="#+id/actions_list_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MyDetailFragment view:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="#android:id/list"
android:tag="#string/activities_list_tag"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
There is a click handler on MyListFragment which calls method in MyActivity which opens the MyDetailFragment.
#Override
public void onActionSelected(MAction action, Integer position){
/**some code...*/
getFragmentManager().beginTransaction()
.replace(R.id.fragment_container,
new MyDetailFragment(mAction,position)).commit();
}
The problem is:
that when I click on any item in MyListFragment, the MyDetailFragment won't show up (although I know it's lifecycle methods are called properly).
I found out that when I put android:layout_weight="1" to fragment definition in MyListFragment, it works. Does anybody know why?
As I understand the android:layout_weight property, it should play some role only when there are more view in LinearLaoyout, but I have only one.
This is the working layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment class="myapp.ActionsList"
android:id="#+id/actions_list_fragment"
**android:layout_weight="1"**
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Thanks
getFragmentManager().beginTransaction()
.replace(R.id.fragment_container,
new MyDetailFragment(mAction,position)).commit();
You are completely replacing a fragment, so there's only one fragment's view in fragment_container at a time. Better make fragment_container a FrameLayout and set height and width of fragment layout roots to match_parent.
You are using layout_weight wrong and i don't think u understood it's functionality. In order to function in LinearLayout parrent you must have a weightSum which will be the total weight of the layout. The second thing would be to set childs weight or height 0dp depending on the LinearLayout orientation. Every child of the layout must have a layout_weight and the total sum of the weight to be equal to weightSum. Such that the Layout will be splited automatically depending you're weight.
Ok, I was doing wrong one thing.
Only fragments loaded programmatically can be replaced. Not fragments defined in xml.
But I didn't know it. Because MyListFragmentView contains fragment in xml definition, so although I called replaced, the method didn't replace actions_list_fragment with new one but put new one after actions_list_fragment. That's why layout_weights made it work - there were two childs in root LinearLayout but I though there is only one.

dynamically changing custom view as common footer in android application

In my android app i want to put a common footer for all the activities. I created a custom view which extends Relative Layout, which contains a ImageView. It'll change the source for every 10 sec depends upon the data from server. I had put my custom view class in every activity's XML file also.
Now my problem is, i'm unable to find the way how it will instantiated in every activity means how the result view will added to every activity.
Simply, i want Admob Advertisement like feature in my application.
This is One of my Activities XML layout:
Activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="0dp"
>
<RelativeLayout
android:id="____"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
----
----
</RelativeLayout>
<com.ninepstudio.movieme.activities.Banner
android:id="#+id/banner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#id/activity_movies_layout" />
</RelativeLayout>

any id in listview in listfragment not working

i have created a program for list fragment where my layout contains a fragment and the fragment contains a inflated listview
the problem is if a give the listview any other id except android:list it is not working .
why it is so
what android:list refers to.
the code is
Main layout :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/lfrag1"
android:name="com.example.chap5.lfrag"
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="1" />
</LinearLayout>
Layout which is inflated for each fragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
The id of the listview that is given here as android:list ,it is working for it .but for any other id it is not working
kindly update
thanks
tejinder
This is a requirement of using ListFragment
http://developer.android.com/reference/android/app/ListFragment.html
ListFragment has a default layout that consists of a single list view. However, if you desire, you can customize the fragment layout by returning your own view hierarchy from onCreateView(LayoutInflater, ViewGroup, Bundle). To do this, your view hierarchy must contain a ListView object with the id "#android:id/list" (or list if it's in code)
If you want to use another id, don't extend ListFragment, just extend Fragment and do it yourself.

How can I use a listview without extending ListActivity in my class?

I have an application with various tabs (on a tabhost). Each tab is an activity that extends activity and has some textfields and things on it.
Now, I need that my tabs have inside a listview, but in the example from Android developer guide says that you have to extend ListActivity and not Activity.
Basically, I need to merge these two tutorials:
List View
Layouts
How can I use a listview without extending listactivity on my class?
My XML file:
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp"/>
</LinearLayout>
</TabHost>
It's almost the same. Basing myself on ListView's tutorial.
Instead of doing:
setListAdapter();
do the following:
Add a <ListView> in your layout
create a field var in your Activity private ListView mListView;
on the onCreate() method do this:
mListView = (ListView) findViewById(R.id.your_list_view_id);
mListView.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));
I don't remember if ListActivity provides something more.
Your TabHost can contain a ListActivity as well, since it inherits from Activity.
But, in case you want learn how to add a listview in an activity any way, follow these instructions. It's simple enough, Make an Activity, Add a Listview in your XML.
Use findViewById() to get your ListView.

Categories

Resources