Reputation: 3240
In my android app, with ViewPager
, I got FragmentActivity
for creating ViewPager
.
In onCreate
method I try to set OnClickListener
for Button
. But after compiling my app crashed. If I remove all setOnClickListener
s everything working.
Can you help me?
public class MainActivity extends FragmentActivity {
AdvicePageAdapter pageAdapter;
Spinner categoriesSpinner;
Button blueButton, greenButton, pinkButton, greyButton, yellowButton;
private OnClickListener oclBtn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Fragment> fragments = getFragments();
pageAdapter = new AdvicePageAdapter(getSupportFragmentManager(), fragments);
ViewPager pager = (ViewPager)findViewById(R.id.viewpager);
pager.setAdapter(pageAdapter);
blueButton = (Button) findViewById(R.id.blueButton);
greenButton = (Button) findViewById(R.id.greenButton);
pinkButton = (Button) findViewById(R.id.pinkButton);
greyButton = (Button) findViewById(R.id.greyButton);
yellowButton = (Button) findViewById(R.id.yellowButton);
oclBtn = new OnClickListener (){
@Override
public void onClick(View v){
}
};
blueButton.setOnClickListener(oclBtn);
greenButton.setOnClickListener(oclBtn);
pinkButton.setOnClickListener(oclBtn);
greyButton.setOnClickListener(oclBtn);
yellowButton.setOnClickListener(oclBtn);
}
}
My logcat
04-12 11:31:33.567: E/AndroidRuntime(2748): FATAL EXCEPTION: main
04-12 11:31:33.567: E/AndroidRuntime(2748): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.eugene.greatadvice/com.eugene.greatadvice.MainActivity}: java.lang.NullPointerException
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.os.Handler.dispatchMessage(Handler.java:99)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.os.Looper.loop(Looper.java:137)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.app.ActivityThread.main(ActivityThread.java:5103)
04-12 11:31:33.567: E/AndroidRuntime(2748): at java.lang.reflect.Method.invokeNative(Native Method)
04-12 11:31:33.567: E/AndroidRuntime(2748): at java.lang.reflect.Method.invoke(Method.java:525)
04-12 11:31:33.567: E/AndroidRuntime(2748): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
04-12 11:31:33.567: E/AndroidRuntime(2748): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-12 11:31:33.567: E/AndroidRuntime(2748): at dalvik.system.NativeStart.main(Native Method)
04-12 11:31:33.567: E/AndroidRuntime(2748): Caused by: java.lang.NullPointerException
04-12 11:31:33.567: E/AndroidRuntime(2748): at com.eugene.greatadvice.MainActivity.onCreate(MainActivity.java:83)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.app.Activity.performCreate(Activity.java:5133)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-12 11:31:33.567: E/AndroidRuntime(2748): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
04-12 11:31:33.567: E/AndroidRuntime(2748): ... 11 more
Main Layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textViewAdvice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
FragmentFile:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/grey" >
<TextView
android:id="@+id/categoriesTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft = "15dip"
android:layout_marginTop = "15dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/categoriesTitle"
android:textColor="@color/white"
android:textSize="17sp" />
<TextView
android:id="@+id/setingsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft = "15dip"
android:layout_marginBottom = "15dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/settingsTitle"
android:textColor="@color/white"
android:textSize="35sp"/>
<Spinner
android:id="@+id/categorieSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft = "15dip"
android:layout_marginRight = "15dip"
android:layout_marginTop = "15dip"
android:layout_below="@+id/categoriesTitle"
android:entries="@array/categories_array"
android:background="@color/white"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:textSize="17sp" />
<TextView
android:id="@+id/colorsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/categorieSpinner"
android:layout_below="@+id/categorieSpinner"
android:layout_marginTop="20dp"
android:text="@string/colorsTitle"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/white"
android:textSize="17sp" />
<View
android:id="@+id/colorsBG"
android:layout_width="84dip"
android:layout_height="84dip"
android:layout_below="@+id/colorsTitle"
android:layout_marginLeft = "13dip"
android:layout_marginTop = "13dip"
android:background="@color/white" />
<Button
android:id="@+id/blueButton"
android:layout_width="80dip"
android:layout_height="80dip"
android:layout_marginLeft = "15dip"
android:layout_marginTop = "15dip"
android:layout_below="@+id/colorsTitle"
android:background="@color/blue"
/>
<Button
android:id="@+id/greenButton"
android:layout_width="80dip"
android:layout_height="80dip"
android:layout_marginLeft = "110dip"
android:layout_marginTop = "15dip"
android:layout_below="@+id/colorsTitle"
android:background="@color/green"
/>
<Button
android:id="@+id/pinkButton"
android:layout_width="80dip"
android:layout_height="80dip"
android:layout_marginLeft = "205dip"
android:layout_marginTop = "15dip"
android:layout_below="@+id/colorsTitle"
android:background="@color/pink"
/>
<Button
android:id="@+id/greyButton"
android:layout_width="80dip"
android:layout_height="80dip"
android:layout_marginLeft = "15dip"
android:layout_marginTop = "110dip"
android:layout_below="@+id/colorsTitle"
android:background="@color/lightGrey"
/>
<Button
android:id="@+id/yellowButton"
android:layout_width="80dip"
android:layout_height="80dip"
android:layout_marginLeft = "110dip"
android:layout_marginTop = "110dip"
android:layout_below="@+id/colorsTitle"
android:background="@color/yellow"
/>
</RelativeLayout>
Full activity code
package com.eugene.greatadvice;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Spinner;
public class MainActivity extends FragmentActivity {
AdvicePageAdapter pageAdapter;
Spinner categoriesSpinner;
Button blueButton, greenButton, pinkButton, greyButton, yellowButton;
View colorsBG;
public OnClickListener oclBtn = new OnClickListener()
{
@Override
public void onClick(View v)
{
if(v == blueButton)
{
}
if(v == greenButton)
{
}
if(v == pinkButton)
{
}
if(v == greyButton)
{
}
if(v == yellowButton)
{
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Fragment> fragments = getFragments();
pageAdapter = new AdvicePageAdapter(getSupportFragmentManager(), fragments);
ViewPager pager = (ViewPager)findViewById(R.id.viewpager);
pager.setAdapter(pageAdapter);
colorsBG = findViewById(R.id.colorsBG);
//init actions
categoriesSpinner = (Spinner) findViewById(R.id.categorieSpinner);
blueButton = (Button) findViewById(R.id.blueButton);
greenButton = (Button) findViewById(R.id.greenButton);
pinkButton = (Button) findViewById(R.id.pinkButton);
greyButton = (Button) findViewById(R.id.greyButton);
yellowButton = (Button) findViewById(R.id.yellowButton);
blueButton.setOnClickListener(oclBtn);
greenButton.setOnClickListener(oclBtn);
pinkButton.setOnClickListener(oclBtn);
greyButton.setOnClickListener(oclBtn);
yellowButton.setOnClickListener(oclBtn);
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
fList.add(SettingsFragment.newInstance(""));
fList.add(AdviceFragment.newInstance(""));
return fList;
}
private class AdvicePageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public AdvicePageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
}
Upvotes: 0
Views: 639
Reputation: 87064
But after compiling my app crashed.
That NullPointerException
is happening because you're trying to access the view of a Fragment
at an inappropriate time when it's not in a valid state. Those buttons are part of the fragment layout, which fragment is only instantiated in the onCreate()
callback, its view will be created after the method onCreate()
so trying to find those buttons in the non existent fragment view will make the references null.
What you're doing is also wrong because it's not a very good way to handle that interaction. Fragments are supposed to be designed as self contained items, that can be plugged where needed, searching for a fragment's views from the Activity
breaks this and ties the fragment to the Activity
(not to mention the high chances of errors). To avoid this(along with the above problem) use an interface to transmit the click events from the fragment to the activity if this is what you want:
/**
* An interface that will transmit the click events to the Activity
*/
public interface ClickDispatch {
void onClickReceived(View btn);
}
The activity will implement this interface
public class MainActivity extends FragmentActivity implements ClickDispatch {
// code...
@Override
public void onClickReceived(View btn) {
// one of the fragment's buttons(btn) was clicked so do stuff
}
Then remove the finding of the buttons and setting the listener on them in the Activity's onCreate()
method and do it in the fragment where you have the buttons:
ClickDispatch mListener;
// in the fragment class
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// this is where the activity is passed to the fragment, we use this to cast the
// activity to our listener to pass it the click events
mListener = (ClickDispatch) activity;
}
// in the onCreateView method of the fragment:
View inflatedView = inflater.inflate(/*your layout*/);
blueButton = (Button) inflatedView.findViewById(R.id.blueButton);
greenButton = (Button) inflatedView.findViewById(R.id.greenButton);
pinkButton = (Button) inflatedView.findViewById(R.id.pinkButton);
greyButton = (Button) inflatedView.findViewById(R.id.greyButton);
yellowButton = (Button) inflatedView.findViewById(R.id.yellowButton);
OnClickListener oclBtn = new OnClickListener (){
@Override
public void onClick(View v){
// dispatch the click event to the Activity
if (mListener != null) {
mListener.onClickReceived(v);
}
}
};
blueButton.setOnClickListener(oclBtn);
greenButton.setOnClickListener(oclBtn);
pinkButton.setOnClickListener(oclBtn);
greyButton.setOnClickListener(oclBtn);
yellowButton.setOnClickListener(oclBtn);
Upvotes: 2
Reputation: 39191
Your Buttons and other Views are being inflated into your Fragment, not your Activity, so findViewById()
is returning null
for those ids. If you mean for the Buttons, etc. to be in the Activity, move those elements from FragmentFile to activity_main.xml
. Otherwise, move the View initializations and methods to your Fragment classes.
Upvotes: 1