无法使用现有解决方案在 Fragment 中获取 onClick 方法

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

我有一个包含三个片段的 ViewPager(在选项卡式布局中)。第三个也是最后一个片段包含两个 ImageButtons(向上和向下箭头)和一个 ImageView,它根据点击的方向箭头循环显示不同的图像。到目前为止,我一直无法使 ImageButtons 上的 onClick 方法正常工作。

我知道代码首先在父 Activity 的源代码中查找 onClick 方法,如果我在 Fragment 的 XML 中使用 onClick 方法。所以我尝试根据 Whosebug 上类似问题的现有解决方案定义一个 onClick 侦听器,但这种方法似乎不起作用。我是做错了什么还是完全是另一个错误?

这是片段的 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>

片段的java代码: 注意:在此代码中我只展示了其中一个按钮的使用 注:pageUp和pageDown分别为上一页和下一页。

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();
    }

}

使用上面的代码,每次我切换到这个片段时,应用程序都会崩溃。它甚至没有显示我加载片段。

我什至尝试过使用这个替代的覆盖 onClick 函数并使 class 实现 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;
            }
        }

这也不起作用并导致应用程序崩溃。

我遇到的另一个解决方案建议在 activity 中使用 paeUp 和 pageDown 函数,但我需要使用变量 page_num 并且不知道如何在 Activity 使用某种 FragmentManager。另外,我宁愿将功能保留在片段中,并按照问题前面显示的方法进行操作。

我正在使用 API 21,不知道这是否有任何不同。

编辑

Logcat 片段加载失败时的输出片段(提供对话 "Unfortunately {appname} has stopped" 并回滚到之前的 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.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

我认为问题出在你的情况上:

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

起始值是 1 所以这个语句当然会再次将 1 赋值给 page_num。 你应该使用:

public void pageUp(View view)
{
    page_num = (page_num < 6) ? page_num++ : 6;
    changePage();
}

日志表明 virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference 所以我认为问题是 upPageButton = (ImageButton)rootView.findViewById(R.id.upButton); ImageButton upPageButton = (ImageButton) rootView.findViewById(R.id.upButton); upPageButton 成为临时变量 variable.You 应该知道临时变量和成员变量的区别吧。 所以尝试删除 ImageButton upPageButton = (ImageButton) rootView.findViewById(R.id.upButton); ImageButton downPageButton = (ImageButton) rootView.findViewById(R.id.downButton); 我希望它会起作用。

您没有找到正确名称的 findViewById。正如我所看到的,您正在使用 diff 名称膨胀图像按钮,但使用 diff/wrong 名称查找。

 pageDownButton is realId and u are using downButton

它可能会解决你的问题。