Google's tutorial app (which uses the support library by default)
http://developer.android.com/shareables/training/FragmentBasics.zip
contains a two-pane layout for -large
screens. After successfully compiling and running with min/target SDK at 4/15, I deleted all support library stuff and am trying to modernize to SDK 14/19 as an exercise.
Here is the two-pane layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.example.HeadlinesFragment"
android:id="@+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.ArticleFragment"
android:id="@+id/article_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
When the ArticleFragment
is instantiated, the XML that ships with the tutorial is not wrapped in a ViewGroup:
// ArticleFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// If activity recreated (such as from screen rotate), restore
// the previous article selection set by onSaveInstanceState().
// This is primarily necessary when in the two-pane layout.
if (savedInstanceState != null) {
mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
}
// Inflate the layout for this fragment
return inflater.inflate(R.layout.article_view, container, false);
}
and
// res/layout/article_view.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/article"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textSize="18sp" />
This arrangement returns null when something like this is run later: getActivity().findViewById(R.id.article);
I discovered through trial and error and the hierarchy viewer, that the solution to this is to wrap the article_view
in a LinearLayout
:
<?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="horizontal" >
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/article"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textSize="18sp" />
</LinearLayout>
Did something change between the support library and the modern Fragment implementations?
Updated to include MainActivity callback and ArticleFragment update code:
// MainActivity.java
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener {
public void onArticleSelected(int position) {
ArticleFragment articleFrag = (ArticleFragment)
getFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
articleFrag.updateArticleView(position);
}...
// ArticleFragment.java
public void updateArticleView(int position) {
TextView article = (TextView) getView().findViewById(R.id.article);
article.setText(Ipsum.Articles[position]);
mCurrentPosition = position;
}
Updated to include stack trace:
09-18 19:04:45.239 1291-1291/com.example.fragmentbasicsrebuild E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.fragmentbasicsrebuild.ArticleFragment.updateArticleView(ArticleFragment.java:74)
at com.example.fragmentbasicsrebuild.MainActivity.onArticleSelected(MainActivity.java:66)
at com.example.fragmentbasicsrebuild.HeadlinesFragment.onListItemClick(HeadlinesFragment.java:75)
at android.app.ListFragment$2.onItemClick(ListFragment.java:160)
at android.widget.AdapterView.performItemClick(AdapterView.java:298)
at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:2788)
at android.widget.AbsListView$1.run(AbsListView.java:3463)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)