2

I have a simple Android app. The layout folder shows an activity_main.xml file and a fragment_main.xml file. In that fragment.xml file I have placed a button that I've named buttonTest.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.snapvest.thunderbird.app.MainActivity$PlaceholderFragment">

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TEST"
        android:id="@+id/buttonTest"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

in the MainActivity.java file I'm trying to gain access to that buttonTest.

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }

    // Get access to the buttons
    final Button buttonTest = (Button)findViewById(R.id.buttonTest);
}

It compiles just fine. But when I run it the buttonTest variable comes back as a null pointer. Why is it not finding the buttonTest object?

Roger Garrett
  • 349
  • 1
  • 7
  • 13

3 Answers3

6

I think I found the solution. MainActivity.java sets up the activity_main.xml which then uses fragment_main.xml as its (initially) single, primary fragment. That's why we are supposed to actually put all of our UI for the activity primarily in fragment_main.xml (and actually put NOTHING in activity_main.xml).

Near the bottom of MainActivity.java there is a section that initializes the fragment_main.xml. And it is THERE that I need to gain access to the buttons and other objects of the UI for the fragment. Such as:

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        // Get access to the buttons
        final Button buttonAvailableOptions = (Button)rootView.findViewById(R.id.buttonAvailableOptions);

        return rootView;
    }
}

Most of that, above, is automatically added by Android Studio. The part starting with "Get access to the button" is mine and is where you set up any access to or processing of the buttons and other UI objects.

Roger Garrett
  • 349
  • 1
  • 7
  • 13
  • I found the answer here : http://stackoverflow.com/questions/23653778/nullpointerexception-accessing-views-in-oncreate – cabaji99 Aug 21 '15 at 15:20
1

The reason why findViewById() is failing to find the button is because setContentView() primes findViewById() to only look in the layout.xml file you gave to setContentView(), and your button is not located in R.layout.activity_main. If your button is located in the Fragment (which it appears to be) then you should be accessing and manipulating it from the Fragment, not the Activity. This ensures that your Activity and Fragment logic stay decoupled, allowing you to re-use the Fragment with different Activities.

NasaGeek
  • 2,138
  • 1
  • 15
  • 19
  • Both activity_main.xml and fragment_main.xml reside in the layout folder. When I initially start up Android Studio and add this as a new app, i t automatically creates both the activity and the fragment xml files, and it even highlight (auto-selects) fragment_main.xml for initial editing. That says to me that my layout should indeed reside in fragment_main.xml (and not in activity_main.xml). As for where I should try to access the button from, there is a MainActivity.java file but nothing corresponding explicitly to the fragment. IN fact, MainActivity.java is the ONLY java file. – Roger Garrett Feb 12 '14 at 23:25
  • If I change the setContentView(R.layout.activity_main); to setContentView(R.layout.fragment_main); [i.e. to the FRAGMENT]then I can indeed gain access to the button and get a non-null pointer to it. But then the app reports "Unfortunately, SnapVest has stopped working". – Roger Garrett Feb 12 '14 at 23:31
0

You can use like this.

final Button buttonAvailableOptions = getActivity().findViewById(R.id.buttonAvailableOptions);
maxileft
  • 225
  • 4
  • 15