The question is published on by Tutorial Guruji team.
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
Answer
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.