Unable to get onClick method in Fragment to work using existing solutions

0

I have a ViewPager that holds three fragments (within a tabbed layout). The third and final fragment holds two ImageButtons (up and down arrows) and an ImageView that cycles through different images depending on which directional arrow is hit. So far, I've been unable to get the onClick methods on the ImageButtons to work.

I understand that the code first looks for the onClick method in the parent Activity's source, if I used the onClick in the Fragment's XML. So I tried defining an onClick listener based on existing solutions to similar questions on StackOverflow, but this approach doesn't seem to be working. Am I doing something wrong or is there another mistake altogether?

Here's the Fragment's XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#2E2E2E" >

   <ImageButton
       android:id="@+id/pageUpButton"
       android:layout_width="fill_parent"
       android:layout_height="0dp"
       android:layout_weight="1"
       android:layout_gravity="center"
       android:src="@drawable/uparrow"
       android:layout_marginTop="5dp"
       android:contentDescription="@string/contentDesc"
       android:background="@drawable/arrow_imagebutton_selector" />

   <ImageView
        android:id="@+id/recipeDirectionsImage"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
       android:layout_weight="10"
        android:contentDescription="@string/contentDesc" />

   <ImageButton
       android:id="@+id/pageDownButton"
       android:layout_width="fill_parent"
       android:layout_height="0dp"
       android:layout_weight="1"
       android:layout_gravity="center"
       android:src="@drawable/downarrow"
       android:contentDescription="@string/contentDesc"
       android:background="@drawable/arrow_imagebutton_selector" />

   <!-- make list recipePagesList --> 
</LinearLayout>

Fragment's java code: Note: I've only shown the use of one of the buttons in this code Note: pageUp and pageDown are the previous and next pages respectively.

public class RecipeDirectionsFragment extends Fragment //implements OnClickListener
{
    int REQUEST_CODE = 0, RESULT_OK = 1, page_num = 1;
    public ImageView recipePage;

//    private ImageButton pageButton = null;
      private ImageButton upPageButton = null;
      private ImageButton downPageButton = null;


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

        recipePage = (ImageView) rootView.findViewById(R.id.recipeDirectionsImage);
        changePage();

        upPageButton = (ImageButton)rootView.findViewById(R.id.upButton);
        downPageButton = (ImageButton)rootView.findViewById(R.id.downButton);

//      pageButton = (ImageButton)rootView.findViewById(R.id.upButton);
//      pageButton.setOnClickListener(this);

        upPageButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                pageUp(v);
            }
        });

        downPageButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                pageDown(v);
            }
        });

        return rootView;
    }

    public void changePage()
    {
        //recipePage = (ImageView) getView().findViewById(R.id.recipeDirectionsImage);
        switch(page_num)
        {
            case 1: recipePage.setImageResource(R.drawable.recipe_1_3); break;
            case 2: recipePage.setImageResource(R.drawable.recipe_1_4); break;
            case 3: recipePage.setImageResource(R.drawable.recipe_1_5); break;
            case 4: recipePage.setImageResource(R.drawable.recipe_1_6); break;
            case 5: recipePage.setImageResource(R.drawable.recipe_1_7); break;
            case 6: recipePage.setImageResource(R.drawable.recipe_1_8); break;
        }
    }

    public void pageUp(View view)
    {
        //Toast.makeText(getActivity(), "up", Toast.LENGTH_SHORT).show();
        page_num = (page_num > 1) ? page_num-1 : 1;
        changePage();
    }

    public void pageDown(View view)
    {
        //Toast.makeText(getActivity(), "down", Toast.LENGTH_SHORT).show();
        page_num = (page_num < 6) ? page_num+1 : 6;
        changePage();
    }

}

With the above code, every time I switch to this fragment, the app just crashes. It doesn't even show me load the fragment.

I've even tried using this alternate overridden onClick function and making the class implement onClickListener :

    @Override
        public void onClick(View v) 
        {
            switch (v.getId()) 
            {
                case R.id.upButton: Toast.makeText(getActivity(), "up", Toast.LENGTH_SHORT).show();
                                    break;

                case R.id.downButton: Toast.makeText(getActivity(), "down", Toast.LENGTH_SHORT).show();
                                      break;
            }
        }

This too doesn't work and crashes the app.

Another solution I came across recommended using the paeUp and pageDown functions in the activity instead but I need to use the variable page_num and don't know how to access it in the Activity using some sort of a FragmentManager. Also, I would rather keep the functions in the Fragment and follow the approaches shown earlier in the question.

I'm working with API 21 and don't know if that makes any difference.

Edit

Logcat output snippet at the moment the fragment fails to load (gives a dialogue "Unfortunately {appname} has stopped" and rolls back to the previous activity)

03-12 21:29:19.965: D/AndroidRuntime(25773): Calling main entry com.android.commands.am.Am
03-12 21:29:19.970: I/ActivityManager(546): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.culami/.WelcomePageActivity} from uid 2000 on display 0
03-12 21:29:19.974: D/AndroidRuntime(25773): Shutting down VM
03-12 21:29:19.977: I/art(25773): Debugger is no longer active
03-12 21:29:19.985: E/art(25773): Thread attaching while runtime is shutting down: Binder_2
03-12 21:29:19.985: I/AndroidRuntime(25773): NOTE: attach of thread 'Binder_2' failed
03-12 21:29:20.017: I/ActivityManager(546): Start proc com.example.culami for activity com.example.culami/.WelcomePageActivity: pid=25791 uid=10088 gids={50088, 9997, 3003} abi=armeabi-v7a
03-12 21:29:20.054: I/art(25791): Late-enabling -Xcheck:jni
03-12 21:29:20.282: D/OpenGLRenderer(25791): Render dirty regions requested: true
03-12 21:29:20.290: D/Atlas(25791): Validating map...
03-12 21:29:20.343: I/Adreno-EGL(25791): <qeglDrvAPI_eglInitialize:410>: QUALCOMM Build: 10/28/14, c33033c, Ia6306ec328
03-12 21:29:20.344: I/OpenGLRenderer(25791): Initialized EGL, version 1.4
03-12 21:29:20.363: D/OpenGLRenderer(25791): Enabling debug mode 0
03-12 21:29:20.507: I/ActivityManager(546): Displayed com.example.culami/.WelcomePageActivity: +527ms
03-12 21:29:20.874: I/MicrophoneInputStream(1077): mic_close com.google.android.speech.audio.w@3d6762c
03-12 21:29:20.916: D/audio_hw_primary(182): disable_audio_route: reset and update mixer path: audio-record
03-12 21:29:20.916: D/audio_hw_primary(182): disable_snd_device: snd_device(36: voice-rec-mic)
03-12 21:29:20.923: I/HotwordRecognitionRnr(1077): Hotword detection finished
03-12 21:29:20.926: I/HotwordRecognitionRnr(1077): Stopping hotword detection.
03-12 21:29:21.733: I/ActivityManager(546): START u0 {cmp=com.example.culami/.UserDashboardActivity} from uid 10088 on display 0
03-12 21:29:21.741: D/audio_hw_primary(182): select_devices: out_snd_device(2: speaker) in_snd_device(0: none)
03-12 21:29:21.741: D/ACDB-LOADER(182): ACDB -> send_afe_cal
03-12 21:29:21.741: D/audio_hw_primary(182): enable_snd_device: snd_device(2: speaker)
03-12 21:29:21.744: D/audio_hw_primary(182): enable_audio_route: apply and update mixer path: low-latency-playback
03-12 21:29:21.926: I/ActivityManager(546): Displayed com.example.culami/.UserDashboardActivity: +188ms
03-12 21:29:22.592: I/ActivityManager(546): START u0 {cmp=com.example.culami/.RecipeDashboardActivity} from uid 10088 on display 0
03-12 21:29:22.914: I/ActivityManager(546): Displayed com.example.culami/.RecipeDashboardActivity: +313ms
03-12 21:29:23.732: I/ActivityManager(546): START u0 {cmp=com.example.culami/.ActiveRecipeActivity} from uid 10088 on display 0
03-12 21:29:24.128: I/ActivityManager(546): Displayed com.example.culami/.ActiveRecipeActivity: +376ms
03-12 21:29:25.487: D/AndroidRuntime(25791): Shutting down VM
03-12 21:29:25.488: E/AndroidRuntime(25791): FATAL EXCEPTION: main
03-12 21:29:25.488: E/AndroidRuntime(25791): Process: com.example.culami, PID: 25791
03-12 21:29:25.488: E/AndroidRuntime(25791): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
03-12 21:29:25.488: E/AndroidRuntime(25791):    at com.example.culami.RecipeDirectionsFragment.onCreateView(RecipeDirectionsFragment.java:39)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:486)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.view.ViewPager.populate(ViewPager.java:1073)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.support.v4.view.ViewPager$3.run(ViewPager.java:249)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.view.Choreographer.doCallbacks(Choreographer.java:580)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.view.Choreographer.doFrame(Choreographer.java:549)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.os.Handler.handleCallback(Handler.java:739)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.os.Handler.dispatchMessage(Handler.java:95)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.os.Looper.loop(Looper.java:135)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at android.app.ActivityThread.main(ActivityThread.java:5221)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at java.lang.reflect.Method.invoke(Native Method)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at java.lang.reflect.Method.invoke(Method.java:372)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
03-12 21:29:25.488: E/AndroidRuntime(25791):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
03-12 21:29:25.489: W/ActivityManager(546):   Force finishing activity com.example.culami/.ActiveRecipeActivity
03-12 21:29:25.538: I/OpenGLRenderer(546): Initialized EGL, version 1.4
03-12 21:29:25.992: W/ActivityManager(546): Activity pause timeout for ActivityRecord{128c44a3 u0 com.example.culami/.ActiveRecipeActivity t502 f}
03-12 21:29:26.887: D/audio_hw_primary(182): disable_audio_route: reset and update mixer path: low-latency-playback
03-12 21:29:26.887: D/audio_hw_primary(182): disable_snd_device: snd_device(2: speaker)
03-12 21:29:27.052: E/(180): invalid crash request of size 4 (from pid=25647 uid=0)
03-12 21:29:27.153: W/qcom_sensors_hal(546): hal_sensor1_data_cb: SENSOR1_MSG_TYPE_BROKEN_PIPE
03-12 21:29:27.160: E/Diag_Lib(25866):  Diag_LSM_Init: Failed to open handle to diag driver, error = 2
03-12 21:29:27.160: E/Sensors(25866): sns_fsa_la.c(386):fsa: fflush failed, 9
03-12 21:29:27.161: E/Sensors(25866): sns_fsa_la.c(386):fsa: fflush failed, 9
03-12 21:29:27.186: W/Sensors(25866): sns_smr_la.c(446):smr_la: smr_apps_la_thread_main is starting, fd=11, sns_smr.en_rx_msg_ptr=b6f7e9d0
03-12 21:29:27.196: W/Sensors(25866): sns_sam_app.c(6827):sns_sam_reg_algo: Registering algo service 16, err 0
03-12 21:29:27.204: E/Sensors(25866): sns_debug_main.c(565):Debug Config File missing in EFS!
03-12 21:29:27.250: I/Process(25791): Sending signal. PID: 25791 SIG: 9
03-12 21:29:27.265: D/audio_hw_primary(182): select_devices: out_snd_device(2: speaker) in_snd_device(0: none)
03-12 21:29:27.265: D/ACDB-LOADER(182): ACDB -> send_afe_cal
03-12 21:29:27.265: D/audio_hw_primary(182): enable_snd_device: snd_device(2: speaker)
03-12 21:29:27.268: D/audio_hw_primary(182): enable_audio_route: apply and update mixer path: low-latency-playback
03-12 21:29:27.292: I/WindowState(546): WIN DEATH: Window{b7fc8b3 u0 com.example.culami/com.example.culami.UserDashboardActivity}
03-12 21:29:27.300: I/WindowState(546): WIN DEATH: Window{4829921 u0 com.example.culami/com.example.culami.RecipeDashboardActivity}
03-12 21:29:27.304: W/InputDispatcher(546): channel '2e2367ca com.example.culami/com.example.culami.WelcomePageActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
03-12 21:29:27.304: E/InputDispatcher(546): channel '2e2367ca com.example.culami/com.example.culami.WelcomePageActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
03-12 21:29:27.304: W/InputDispatcher(546): channel 'd9487ff com.example.culami/com.example.culami.ActiveRecipeActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
03-12 21:29:27.304: E/InputDispatcher(546): channel 'd9487ff com.example.culami/com.example.culami.ActiveRecipeActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
03-12 21:29:27.308: I/WindowState(546): WIN DEATH: Window{d9487ff u0 com.example.culami/com.example.culami.ActiveRecipeActivity}
03-12 21:29:27.308: W/InputDispatcher(546): Attempted to unregister already unregistered input channel 'd9487ff com.example.culami/com.example.culami.ActiveRecipeActivity (server)'
03-12 21:29:27.313: I/WindowState(546): WIN DEATH: Window{2e2367ca u0 com.example.culami/com.example.culami.WelcomePageActivity}
03-12 21:29:27.313: W/InputDispatcher(546): Attempted to unregister already unregistered input channel '2e2367ca com.example.culami/com.example.culami.WelcomePageActivity (server)'
03-12 21:29:27.423: I/ActivityManager(546): Process com.example.culami (pid 25791) has died
03-12 21:29:27.460: I/ActivityManager(546): Start proc com.example.culami for activity com.example.culami/.RecipeDashboardActivity: pid=25875 uid=10088 gids={50088, 9997, 3003} abi=armeabi-v7a
03-12 21:29:27.545: I/art(25875): Late-enabling -Xcheck:jni
03-12 21:29:27.816: D/OpenGLRenderer(25875): Render dirty regions requested: true
03-12 21:29:27.822: D/Atlas(25875): Validating map...
03-12 21:29:27.848: I/Adreno-EGL(25875): <qeglDrvAPI_eglInitialize:410>: QUALCOMM Build: 10/28/14, c33033c, Ia6306ec328
03-12 21:29:27.849: I/OpenGLRenderer(25875): Initialized EGL, version 1.4
03-12 21:29:27.866: D/OpenGLRenderer(25875): Enabling debug mode 0
03-12 21:29:28.002: W/InputMethodManagerService(546): Got RemoteException sending setActive(false) notification to pid 25791 uid 10088
03-12 21:29:28.013: I/ActivityManager(546): Displayed com.example.culami/.RecipeDashboardActivity: +587ms
: E/(): Device disconnected: 1
: E/(): Device disconnected
java
android
android-fragments
onclick
onclicklistener
asked on Stack Overflow Mar 12, 2015 by Darth Coder • edited Mar 8, 2020 by halfer

3 Answers

2

You are not findViewById for right name. As much i can see you are inflating image button with diff name but finding with diff/wrong name.

 pageDownButton is realId and u are using downButton

It might solve you problem.

answered on Stack Overflow Mar 13, 2015 by Manmohan Badaya
1

I think the problem simply is in your condition:

public void pageUp(View view)
{
    page_num = (page_num > 1) ? page_num-1 : 1;
    changePage();
}

The start value is 1 so of course this statement assign 1 again to page_num. You should use:

public void pageUp(View view)
{
    page_num = (page_num < 6) ? page_num++ : 6;
    changePage();
}
answered on Stack Overflow Mar 12, 2015 by yshahak
1

log tells that virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference so I think that problem is upPageButton = (ImageButton)rootView.findViewById(R.id.upButton); ImageButton upPageButton = (ImageButton) rootView.findViewById(R.id.upButton); upPageButton become a temporary variable.You should know the difference between temporary variable and member variable. So try to remove ImageButton upPageButton = (ImageButton) rootView.findViewById(R.id.upButton); ImageButton downPageButton = (ImageButton) rootView.findViewById(R.id.downButton); I wish it will work.

answered on Stack Overflow Mar 13, 2015 by MaybeMercy • edited Mar 13, 2015 by MaybeMercy

User contributions licensed under CC BY-SA 3.0