java - 从 fragment 中调用 Activity 的方法

标签 java android bluetooth fragment

简介

我有一个蓝牙应用程序,它包含一个 Activity,它有 3 个按钮:

  • 设置可见性并创建服务器连接
  • 查找设备并创建客户端连接
  • 发送一些东西

我有以下类(class):

  • 主要 Activity :我拥有所有方法和按钮监听器
  • 3 个不同的线程类:ClientConnection、ServerConnection 和 ConnectedThread

现在我必须稍微改变一下设计,而不是使用 ActionBar 上的 Tabs 来创建一个 Activity,我需要创建 2 个 fragment :服务器和客户端。

所以,基本上,我必须在服务器 fragment 中定义服务器和发送按钮,在客户端 fragment 中定义客户端按钮,并设置它们的监听器。

问题

在每个 fragment 中,当使用一个按钮时,我应该调用其在主 Activity 中发布的相应方法。我想这样做,而不是复制每个 fragment 中的所有方法和接口(interface),只是为了更简单。

我尝试将方法设置为静态,但方法中有一些定义不能用静态引用调用。示例:

public class ServerFragment extends Fragment { 
    //...  
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.server_layout, container, false);

        btnServer = (Button) view.findViewById(R.id.buttonServer);   
        btnServer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                onClickServer();
            }
        });
        //...

_

public class BluetoothActivity extends Activity {
    //...
    public void onClickServer() {
        Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
        startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE);
    }

如果我将 onClickServer() 设置为静态,我必须将 REQUEST_DISCOVERABLE 也设置为静态,而 startActivityForResult() 不会让我在那里使用静态变量。

我该怎么做?

更新——抛出 NullpointerException

作为建议,我创建了一个名为 ClickInterface 的新类,并在那里定义了 2 个接口(interface),一个用于服务器,另一个用于客户端。

不,从 fragment 中,我试图调用 onClick 方法中的方法,但是在我调用回调方法的行中抛出了一个 NPE:

public class ServerFragment extends Fragment implements OnClickListener {

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.server_layout, container, false);

        btnServer = (Button) view.findViewById(R.id.buttonServer);
        btnServer.setOnClickListener(this);

        return view;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.buttonServer:
                serverFragCallback.onServer(); //HERE I RECEIVE THE NPE
                break;
        }
    }

这是 logcat 的输出:

03-20 16:33:57.581: E/AndroidRuntime(24884): FATAL EXCEPTION: main
03-20 16:33:57.581: E/AndroidRuntime(24884): Process: com.uax.bluetoothconnection, PID: 24884
03-20 16:33:57.581: E/AndroidRuntime(24884): java.lang.NullPointerException
03-20 16:33:57.581: E/AndroidRuntime(24884):    at com.uax.bluetoothconnection.ServerFragment.onClick(ServerFragment.java:43)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at android.view.View.performClick(View.java:4633)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at android.view.View$PerformClick.run(View.java:19330)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at android.os.Handler.handleCallback(Handler.java:733)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at android.os.Handler.dispatchMessage(Handler.java:95)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at android.os.Looper.loop(Looper.java:157)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at android.app.ActivityThread.main(ActivityThread.java:5356)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at java.lang.reflect.Method.invokeNative(Native Method)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at java.lang.reflect.Method.invoke(Method.java:515)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
03-20 16:33:57.581: E/AndroidRuntime(24884):    at dalvik.system.NativeStart.main(Native Method

最佳答案

你想要的是一个回调接口(interface),用于从 Fragment 到 Activity 的通信。 docs已经为此提供了一个很好的例子。

定义您的 Activity 实现的接口(interface):

public interface Callback {
    void doSomething();
}
public class YourActivity implements Callback {
    ...
    @Override
    public void doSomething() {
         // your implementation here
    }
}

如果单击其中一个按钮,则在您的 Fragment 中使用此界面。

public class ServerFragment extends Fragment { 

    Callback iCallback;
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            iCallback = (Callback) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException();
        }
    }

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

        btnServer = (Button) view.findViewById(R.id.buttonServer);   
        btnServer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                iCallback.doSomething();
            }
        });
    }
}

通过这种方法,您可以将逻辑留在 Activity 中,并在 Fragment 中处理 UI 事件。通过 Fragment 中的事件,您可以调用 Activity 中的方法。

关于java - 从 fragment 中调用 Activity 的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22536565/

相关文章:

java - 是否可以在android中建立多个蓝牙通信

java - 使用单个replaceAll 审查选定的单词(用**** 替换它们)?

java - 将数组值列表分配为字符串

android - 如何在android模拟器中运行wifi点对点应用程序..?

android - 如何防止 Android 中可怕的 KSOAP2 连接超时

android - 如何在android中选择和取消选择recyclerview

java - 如何在 Android 中获取远程设备自定义蓝牙名称?

java - 如何从Intellij的Gradle的checkstyle中排除文件夹

java - ftp 上的同时连接数

java - 有没有办法像在 Eclipse 中一样将 .jar 库添加到 Android Studio?