How to fix a bug in the Basic Fragments example code from the official Android tutorial

217
January 31, 2018, at 10:09 PM

I have downloaded the example code for the official Fragments tutorial here, after updating it to use gradle and work with the latest version of Android Studio, I found it throws a NullPointerException when clicking on an article and when running on an emulator with a large screen (i.e. tablet sized screen - on a phone sized screen it works fine). You can find the updated code here. The exception is:

java.lang.NullPointerException
    at com.example.fragmentbasics.ArticleFragment.updateArticleView(ArticleFragment.java:64)
    at com.example.fragmentbasics.MainActivity.onArticleSelected(MainActivity.java:66)
    at com.example.fragmentbasics.HeadlinesFragment.onListItemClick(HeadlinesFragment.java:75)
    at android.support.v4.app.ListFragment$2.onItemClick(ListFragment.java:60)
    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)

As far as I understand, the layout article_view should be inflated into the main activity when the fragment ArticleFragment is created. This layout has a TextView with the id "article". This should happen regardless of the screen size.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState) {
    ...
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.article_view, container, false);
}

But for some reason, later on when updateArticleView is called on ArticleFragment, no view with the id "article" is found which causes the NPE above.

public void updateArticleView(int position) {
    TextView article = (TextView) getActivity().findViewById(R.id.article);
    article.setText(Ipsum.Articles[position]);
    mCurrentPosition = position;
}

What changes do we need to make to the example code to avoid this NPE and make the sample code work in all screen sizes?

Update:

The issue has been resolved thanks to Roberto Martucci's answer below. I have updated the master branch of the github repository to include the fix.

Answer 1

Since it is a fragment, you should call findViewById on its root view and not on the activity content. Apply these changes to avoid the exception:

private View rootView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
  Bundle savedInstanceState) {
    ...
   // Inflate the layout for this fragment
   rootView = inflater.inflate(R.layout.article_view, container, false)
   return rootView;
}
public void updateArticleView(int position) {
    if(rootView != null) {
        TextView article = (TextView) rootView.findViewById(R.id.article);
        article.setText(Ipsum.Articles[position]);
    }
    mCurrentPosition = position;
}

UPDATE

I tested your code and I probably found the solution. You have to add article_view.xml to layout-large as previously suggested in the other answers but it has to have the following structure. Your TextView needs to have a parent container, so I wrapped it in a FrameLayout.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView
        android:id="@+id/article"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        android:textSize="18sp" />
</FrameLayout>
Answer 2

After checking a little bit, I found it...

Your structure has to be like this:

layout
   -article_view.xml
   -news_articles.xml
layout-small
   -article_view.xml
layout-large
   -article_view.xml
layout-xlarge
    -article_view.xml

Tried it, and it's working.

Edit: Or any other way, but you have to have article_view.xml inside all these folders.

Rent Charter Buses Company
READ ALSO
Annotation Processor generating files but not able access them in app (mainActivity)

Annotation Processor generating files but not able access them in app (mainActivity)

Here is my sample project https://githubcom/ilagarwal/uclego where I am generating file using Kotlin annotation

173
What are System programming for designing a Keyboard with embedded storage device

What are System programming for designing a Keyboard with embedded storage device

A hardware manufacturing company receives a query from one of its customer to embed a storage drive in a keyboard, dedicated for user’s private dataThe newly devised keyboard must be market compatible in terms of space (As 1 TB drives are easily available...

223
How to implement a ViewPager with different Fragments / Layouts

How to implement a ViewPager with different Fragments / Layouts

When I start an activity which implements viewpager, the viewpager created various fragmentsI want to use different layouts for each fragment, but the problem is that viewpager shows only two layouts at the max (second layout on all of the remaining fragments...

188
How to use CMake ExternalProject_Add or alternatives in a cross platform way?

How to use CMake ExternalProject_Add or alternatives in a cross platform way?

I would like to build a third-party project that already has CMake as part of my project's CMake stripsExternalProject_Add is for this purpose, but I have found it can only be made to work with a specific generator, and I wanted to work on many platforms...

1278