I'm in the process of making an Android 3 app that has a tab-based navigation. Being quite new to Android I searched for tab tutorials and found a few different approaches, out of which an implementation based on Fragments + ActionBar seemed to be the best. I followed these tutorials
http://www.abelski.com/courses/android3ui/actionbar.pdf (the last few slides) and http://www.youtube.com/watch?v=gMu8XhxUBl8 (same lesson in video format)
...and got to the point where the tabs show up, I can switch between them OK, and simple TextViews inside them show up fine.
Now, problems arise when I want one of the tabs to have a spinner widget that is defined in the fragment's XML file and populate it with items that are defined in the strings.xml file. When I try to access the spinner with getViewById() from the onCreate() method I always get a null value as a result.
As I understand it, to fix this I need to somehow declare the XML of the fragment (similarly like main layout has been done with setContentView(R.layout.main)) so that getViewById() knows where to look for the spinner (Eclipse's autocomplete finds it already though). However, I'm at complete loss how to do this, since none of the tutorials tackled the scenario where you want to modify the XML-based Fragments' contents inside the code.
The main.xml looks like this:
<?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">
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/fragment_placeholder"></LinearLayout>
</LinearLayout>
tab1_fragment.xml like this:
<?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">
<Spinner android:id="@+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
and onCreate method like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar ab = getActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab newAuditTab = ab.newTab().setText(R.string.tabheader_new_audit);
Fragment newAuditFrag = new FragmentTabNewAudit();
newAuditTab.setTabListener(new TabListener(newAuditFrag));
ab.addTab(newAuditTab);
//and the same for other tabs
Spinner spinner = (Spinner) findViewById(R.id.spinner1); // this returns null
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.cell_array, android.R.layout.simple_spinner_item); //cell_array is defined in strings.xml
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
}
Accessing the views that are defined in main.xml via R.id works fine, so in this case the problem isn't related to Eclipse's auto-importing of the R class, I think.
I guess I could define the spinner programmatically to get around the issue, but there is probably a more elegant solution to this, I hope. I can't see the Android big picture well enough yet to quite know where to look.
As the spinner is not a child of the Activity
itself, findViewById
can not find it. As the spinner is a child of the fragment, you might try:
Spinner spinner = (Spinner)newAuditFrag.getView().findViewById(R.id.spinner1);
However, I'm not sure when the view for a fragment is created, so getView()
might also return null that that point in your code. You could then try to move the code into onResume
, which is called after onCreate
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With