【问题标题】:Call a Fragment's method from parent Activity using a ViewPager使用 ViewPager 从父 Activity 调用 Fragment 的方法
【发布时间】:2015-06-24 23:47:42
【问题描述】:

我有一些来自 Slidenerd 的 Scrolltab 视频系列的示例代码,它运行良好。但是,我不能从父活动中调用片段内的方法。例如,我在片段 A 中包含了一个名为 doSomething() 的方法。我想从 MainActivity 的 onResume() 回调中调用它。

编辑: 由于空指针异常,使用“接受的答案”适用于该应用程序,但不适用于我正在处理的实际应用程序。

错误日志

06-25 13:02:19.308    3862-3862/com.felhr.agweigh D/AndroidRuntime﹕ Shutting down VM
06-25 13:02:19.308    3862-3862/com.felhr.agweigh W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x416ecda0)
06-25 13:02:19.308    3862-3862/com.felhr.agweigh E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.felhr.agweigh, PID: 3862
    java.lang.RuntimeException: Error receiving broadcast Intent { act=com.felhr.usbservice.USB_PERMISSION_GRANTED flg=0x10 } in com.felhr.agweigh.MainActivity$3@41da2c10
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:782)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5479)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at com.felhr.agweigh.FragmentPlotCSV.createSpinner(FragmentPlotCSV.java:102)
            at com.felhr.agweigh.MainActivity$3.onReceive(MainActivity.java:894)
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:772)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5479)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)

清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.felhr.agweigh" >
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-feature android:name="android.hardware.usb.host"
        android:required="true" />

    <application
        android:logo="@drawable/rinstrumlogo"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/RinstrumActionBarTheme" >
        <activity
            android:name="com.felhr.agweigh.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="com.felhr.agweigh.UsbService"
            android:enabled="true" >
        </service>

    </application>

</manifest>

主活动

public class MainActivity extends FragmentActivity {

ViewPager viewPager = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    viewPager = (ViewPager)findViewById(R.id.pager);
    FragmentManager fragmentManager = getSupportFragmentManager();
    viewPager.setAdapter(new MyAdapter(fragmentManager));
}

@Override
protected void onResume() {
    super.onResume();
}
}

我的适配器

class MyAdapter extends FragmentPagerAdapter
{
public MyAdapter(FragmentManager fm)
{
    super(fm);
}

@Override
public Fragment getItem(int i) {
    Fragment fragment = null;
    Log.d("SWIPE","get Item is called"+i);
    if (i==0)
    {
        fragment=new FragmentA();
    }
    if (i==1)
    {
        fragment=new FragmentB();
    }
    if (i==2)
    {
        fragment=new FragmentC();
    }
    return fragment;
}

@Override
public int getCount() {
    Log.d("SWIPE","get count is called");
    return 3;
}

// talks to title to give the page
@Override
public CharSequence getPageTitle(int position) {
    if (position == 0) {
        return "Tab 1";
    }
    if (position == 1) {
        return "Tab 2";
    }
    if (position == 2) {
        return "Tab 3";
    }
    return null;
}
}

片段A

/**
 * Created by Luke on 20/04/2015.
 */
public class FragmentA extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_a, container, false);
    }

    public void doSomething(){
        // call this method from main activity
        }
    }

片段B

/**
 * Created by Luke on 20/04/2015.
 */
public class FragmentB extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_a, container, false);
    }
}

片段C

/**
 * Created by Luke on 20/04/2015.
 */
public class FragmentC extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_a, container, false);
    }
}

【问题讨论】:

    标签: android android-fragments android-activity android-viewpager swipe


    【解决方案1】:

    仅供参考,您的问题并非特定于使用 ViewPager。

    根据设计,活动不知道您的 FragmentA 除了它是一个 Fragment 之外的任何信息,因此它不知道它包含一个 doSomething() 方法。当您知道它是 FragmentA 时,快速而肮脏的方法是从适配器获取片段并将其转换为 FragmentA。我说这是一种“快速而肮脏”的方式,因为您希望将活动和片段之间的事情解耦——即您的 Activity 不需要了解您的 FragmentA 实现,只需了解 Fragment。

    当您构建更复杂的应用程序时,您需要考虑使用事件总线以一种很好的解耦方式在片段和活动之间发送消息。以下是一些流行的 android 事件总线: http://square.github.io/otto/ https://github.com/greenrobot/EventBus

    【讨论】:

      【解决方案2】:

      你可以这样做-

          @Override
          protected void onResume() {
              super.onResume();
              FragmentA _fragA = new FragmentA();
              _fragA.doSomething();
      
          }
      

      您可以使用以下元素在清单文件中注册您的接收器:

             <receiver android:name="MyReceiver" >
                  <intent-filter>
                      <action android:name="com.example.Broadcast" >
                          </action>
                  </intent-filter>
              </receiver>
      

      嵌套元素用于指定接收者应响应的事件。

      【讨论】:

      • 你是否也在实现 BroadCart Receiver,那么请给我看一下你的广播接收器部分的清单。
      • 是的,我是......基本上我正在尝试在收到表明 USB 端口已准备就绪的意图后在 FragmentReadCSV 中运行一个方法
      • 请在清单中注册您的接收器,我已经为此提供了样本。请查看我的编辑。
      • 我这样做了,但我认为问题是我在广播接收器中这样做:FragmentPlotCSV fragmentPlotCSV = new FragmentPlotCSV(); fragmentPlotCSV.createSpinner();
      • 请显示该课程
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      • 2012-08-17
      • 1970-01-01
      相关资源
      最近更新 更多