I am trying to create a ListView inside a ListFragment. My list is customize, so it has been created with an adapter. But the aplication crass and give me this error your content must have a listview whose id attribute is 'android.r.id.list
This is the ListFragment class:
public static class DummySectionFragment extends ListFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false);
Vector<String> names=new Vector<String>();
names.add("Alex");
names.add("Julia");
setListAdapter(new MyAdapter(getActivity(), names));
return rootView;
}
}
This is MyAdapter class:
public class MiAdaptador extends BaseAdapter {
private final Activity activ;
private final Vector<String> list;
public MiAdaptador(Activity activ, Vector<String> list) {
super();
this.actividad = activ;
this.list = list;
}
public View getView(int position, View convertView,
ViewGroup parent) {
LayoutInflater inflater = activ.getLayoutInflater();
View view = inflater.inflate(R.layout.adapter_view, null, true);
TextView textView =(TextView)view.findViewById(R.id.titulo);
textView.setText(lista.elementAt(position));
return view;
}
}
My fragment_section_dummy layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Name list"
android:gravity="center"
android:layout_margin="10px"
android:textSize="10pt"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false" />
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
And my adapter_view layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight">
<TextView android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:singleLine="true"
android:text="title"
android:gravity="center"/>
<TextView android:id="#+id/subtitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Other text"
android:layout_below="#id/title"
android:layout_alignParentBottom="true"
android:gravity="center"/>
</RelativeLayout>
How could I solve this problem?
I'm starting to think that you should attach the view your inflating to the root view.
Change the inflation to:
View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, true);
Another option could be to only use the onCreateView() method to inflate the main layout. And use the onStart() method to set the list adapter. This way makes sure Android knows about your custom layout.
Posting a full stacktrace could help solving your problem.
There was others class who extends to ListFrament (like DummySectionFragment) but these didn`t inflate a layout which have a ListView. So I had to change the parent of there class (Fragment instead of ListFragment) and it has solved.
Thanks for your answer
Related
I've implemented onClickListener but inside onCreateView() it's unable to find the button's id and i.e "myButton"
My Code is:
public class Category extends Fragment implements View.OnClickListener {
View view;Button b;
public Category() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_category, container,false);
b=(Button)view.findViewById(R.id.myButton);
b.setOnClickListener(this);
return view;
}
My fragment_category.xml is as below it's containing one button and a textView:
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="layout.Category"
android:id="#+id/constraintLayout">
<TextView
android:layout_width="368dp"
android:layout_height="495dp"
android:text="#string/hello_blank_fragment"
tools:layout_editor_absoluteY="8dp"
tools:layout_editor_absoluteX="8dp" />
<Button
android:id="#+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:elevation="0dp"
android:text="Button"
tools:layout_editor_absoluteX="135dp"
tools:layout_editor_absoluteY="208dp" />
You are inflating "fragment_category", but you said you posted "fragment" xml code.
You're most likely not inflating the correct layout file.
Actually problem was there in IDE after some rectifications the error is sorted out.
I have created a custom layout for ListFragment, using ArrayAdapter, but when the array is empty, no empty message is displayed. I get no errors on the console. My min SDK version is 15, there should be no need to use support libraries.
headline_list.xml (i.e. my custom layout file)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#id/android:list" />
<TextView android:id="#+id/my_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
HeadlineFragment.java
public class HeadlineFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.headline_list, container, false);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List<String> headlines = ...; // populate headlines list
setListAdapter(new ArrayAdapter<String>(getActivity(),
R.layout.headline_list, R.id.my_text, headlines));
}
}
You are getting suggestions here, you should do the tries.. Anyway this layout is working perfectly for me:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ArrayAdapter adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, from);
setListAdapter(adapter);
return rootView;
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragmet"
android:layout_height="match_parent"
android:layout_width="match_parent">
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- Here is the view to show if the list is emtpy -->
<TextView
android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No Results" />
</RelativeLayout>
I had simply forgot to set the text!
After setting it, my TextView is displayed correctly:
<TextView android:id="#id/android:empty"
android:textSize="16sp"
android:textStyle="bold"
android:text="#string/empty_text"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
with string resource in strings.xml file:
<string name="empty_text">There are no data</string>
Unfortunately, the TextView is also displayed in each row of the list, but this is another question.
It may be related to the linear layout and the fact you didn't specified weight attribute to each of the items, so one may overlay another. Check your layout params and this:
Showing empty view when ListView is empty
I am trying to display 6 rows inside a linear layout. I want to do this through fragments as the content will be dynamic and the number of rows will also be dynamic later on. I have the following code but only one row appears on the screen. I have SettingsActivity.java, settings.xml ThemeRowFragment,java and theme_row_layout.xml.
SettingsActivity.java
//imports
public class SettingsActivity extends FragmentActivity {
private int NUM_THEMES = 7;
ThemeRowFragment[] view_themes;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
view_themes = new ThemeRowFragment[NUM_THEMES];
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
for (int i = 0; i < view_themes.length; i++) {
view_themes[i] = new ThemeRowFragment(COLOR_MAP[i]);
fragmentTransaction.add(R.id.theme_linear_layout, view_themes[i],
"Row" + i);
}
fragmentTransaction.commit();
}
}
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="#+id/theme_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
</LinearLayout>
ThemeRowFragment.java
public class ThemeRowFragment extends Fragment {
private int[] colors;
public ThemeRowFragment(int colors[]) {
super();
this.colors = colors;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.theme_row_layout, container,
false);
return view;
}
}
theme_row_layout.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="horizontal" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/pick_colors" >
</TextView>
</LinearLayout>
Fragments will inflate themselves into the View you add them to. So you really can't do it this way. So you need to have X empty containers, one for each fragment you are going to inflate. Add each fragment to the same container will actually layer them all on top of each other, sort of making them really hard to see and use when the screen renders.
Alternatives:
You could do something like the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="#+id/theme_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
<FrameLayout android:id="#+id/fragment_container1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container2"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container3"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container4"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container5"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<!-- etc. -->
</LinearLayout>
Or just add each FrameLayout programatically via the LinearLayout's addView() with a unique ID for each FrameLayout.
LinearLayout layout = (LinearLayout)findViewById(R.id.linear);
FragmentTxn txn = getFragmentManager.beginTransaction();
int i = 1; // This seems really fragile though
for (Fragment f : fragments) {
FrameLayout frame = new FrameLayout(this);
frame.setId(i);
layout.addView(frame);
txn.add(i, f);
i++;
}
txn.commit();
Or the other way would be to just use a listView and add each row that way. Not using Fragments at all.
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
<ListView android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
then later on do something like this:
ListView view = (ListView)findViewById(R.id.listview);
view.setAdapter(new ArrayAdapter(items) { // items is a collection of objects you are representing
public View getView(int position, View view, ViewGroup parent) {
view = LayoutInflator.from(parent.getContext()).inflate(R.layout.theme_row_layout, parent, false);
// manipulate the view
return view;
});
You are creating a instance of ThemeRowFragment n number of times. The problem is you are creating this as an fragment and trying to add it dynamically. Since you instantiate the same Fragment i suggest you to use ListView and use a custom adapter and set CustomView and override the getView method of your adapter to adjust your views
I know that there has been simialr questions but I can't make it work even though I look at those. The error message is:
java.lang.RuntimeException: Your content must have a ListView whose id
attribute is 'android.R.id.list'
. I have tried to change the id to list. In another. This what the code looks like:
public class committeeFragment extends SherlockListFragment {
private CommitteeAdapter adapter;
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
adapter = new CommitteeAdapter(getActivity().getApplicationContext());
setListAdapter(adapter);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return inflater.inflate(R.layout.fragment_committee, container, false);
}
public void
refreshList() {
adapter.updateDataSet();
adapter.notifyDataSetChanged();
}
}
It's using the following adapter:
public class CommitteeAdapter extends BaseAdapter {
private
ArrayList<StudentCommittee> committeeList;
private Context context;
public CommitteeAdapter(Context context) {
this.context = context;
CommitteeDatabaseAdapter dbAdapter = new CommitteeDatabaseAdapter(context);
committeeList = dbAdapter.readAllCommittees();
}
public void updateDataSet() {
CommitteeDatabaseAdapter dbAdapter = new CommitteeDatabaseAdapter(context);
committeeList = dbAdapter.readAllCommittees();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
StudentCommittee committee = committeeList.get(position);
View v = vi.inflate(R.layout.list_item_committee, null);
TextView sectionName = (TextView) v.findViewById(R.id.committee_namn);
sectionName.setText(committee.getName());
return v;
}
#Override
public int getCount() {
return committeeList.size();
}
#Override
public StudentCommittee getItem(int position) {
return committeeList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
}
Here is the xml-file that specifies the list(fragment_committee):
<?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"
android:tag="#string/tag_fragment_committee"
android:background="#color/white" >
<TextView
style="#style/AppsolutText.Headline"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Festerier" />
<View
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#drawable/divider_sliding_menu_item"/>
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
style="#style/AppsolutText.Normal"
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Uppdatera för att se en lista över festerier och fadderier. Kräver internetanslutning."/>
</LinearLayout>
Here is the xml for the list item:
<?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="horizontal" >
<ImageView
android:id="#+id/committee_symbol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingBottom="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" />
<TextView
android:id="#+id/committee_namn"
style="#style/AppsolutText.ListHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
I hope that you can figure out what's wrong. I have another listview that has the same id (list) in another xml-file within the project. I don't know if that's a problem. Please help me solve the problem.
The problem is here :
android:id="#+id/list"
you are adding a new id for your ListView but ListFragment needs a default Android ListView Id
change your ListView Id to :
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Change your ListView in XML to have the following id:
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
It's a requirement of using ListFragment/SherlockListFragment
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)
You can try to clean your project. If any xml releted error have , you can find it. Then you can change your list id . Find the list id are exist into your gen folder R.java class.
I decided to stop using actionbarsherlock and use the support libraries instead to get action bar in Android 2.1 and above. After doing this, i got the "java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'". What i did to remedy this problem was
to read this http://developer.android.com/reference/android/app/ListFragment.html#q=fragment
then change my fragment layout file from
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/item_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textIsSelectable="true"
tools:context=".ItemDetailFragment" />
to
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:context=".ItemDetailFragment">
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<TextView android:id="#+id/item_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textIsSelectable="true"/>
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data"/>
... and voila, the RunTimeException with missing android.R.id.list was gone! Of course, i need to edit my new layout and fix it properly, but the key issue here was that i had overridden the fragment layout in its onCreateView method. ActionBarSherlock DID NOT have a problem with this, but with the Android support library, if u do this, you MUST have a ListView in your XML Layout, with the android:id="#id/android:list" as stated in the info linked to above.
Hope this helps (coming from a total newb in Android app dev)!
in my application I use SherlockActionBar with tab navigation.
In the activity MyFragmentActivity that extend SherlockFragmentActivity I add 3 tab with the fragment
mTabsAdapter.addTab(
bar.newTab().setText(getString(R.string.filmtab)),
FragmentFilm.class, null);
mTabsAdapter.addTab(
bar.newTab()
.setText(getString(R.string.cinematab)),
FragmentCinema.class, null);
mTabsAdapter.addTab(
bar.newTab()
.setText(getString(R.string.dintornitab)),
FragmentPdi.class, null);
The FragmentPdi class have this code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.tab_pdi_info, container, false);
return view;
}
and the layout is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/list_places"
android:layout_width="wrap_content"
android:layout_height="fill_parent" >
</ListView>
</RelativeLayout>
In the MyFragmentActivity I want find the listview for populate it in this way:
final ListView elencoPlaces = (ListView)findViewById(R.id.list_places);
....
but I have NullPointerException!
Why??
In the other fragment (FragmentFilm and FragmentCinema) I have other view like textview without this
problem!!
Please help me!
Thank you.
P.S. Is this the correct way for populate dinamically the views in fragment, or I must populate the view in the fragment class?? If the second how I can pass varible from the activity to the fragment??
if all you have in the layout file is a listview, don't bother overriding oncreateview. the default layout will give you that much. then you can use the methods built into the ListFragment - like getListView() and setListAdapter().
Ok, but I dont undestand why I have another fragment the FragmentCinema where I have this xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:paddingTop="10dip" android:id="#+id/otherCinemas" android:layout_width="fill_parent" android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:orientation="horizontal" android:id="#+id/plotSeparatorOtherCin" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="#id/txtProgrammation">
<ImageView android:layout_gravity="center_vertical" android:background="#drawable/palm_divider_line" android:layout_width="20.0dip" android:layout_height="wrap_content" android:layout_marginRight="5.0dip" />
<TextView android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="#string/altricinema" android:textStyle="bold" />
<ImageView android:id="#+id/showOtherCinemas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_freccia_cinema"
/>
<ImageView android:layout_gravity="center_vertical" android:background="#drawable/palm_divider_line" android:layout_width="fill_parent" android:layout_height="wrap_content" />
</LinearLayout>
<ListView
android:id="#+id/listOtherCinemas"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_below="#id/plotSeparatorOtherCin"
android:visibility="gone" >
</ListView>
</RelativeLayout>
and this code of class:
public class FragmentCinema extends SherlockFragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.tab_cinema_info, container, false);
return view;
}
}
and when I use the findViewbyId
final ListView cinemasOther = (ListView)findViewById(R.id.listOtherCinemas);
it works! But in FragmentPdi dont work!!
If you want to use ListView in ListFragments, your ListView must have id android:id="#+id/android:list"!