Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/182.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何通过另一个片段中的onClick调用片段中的方法?_Java_Android_Android Fragments_Interface - Fatal编程技术网

Java 如何通过另一个片段中的onClick调用片段中的方法?

Java 如何通过另一个片段中的onClick调用片段中的方法?,java,android,android-fragments,interface,Java,Android,Android Fragments,Interface,我正在构建一个包含2个片段的应用程序。第一个片段有一个ImageView和两个TextView,第二个片段有一组按钮和编辑文本。在第二个片段中,我有一个名为Save的按钮。单击此按钮时,我想将第一个片段中的图像下载到我的设备文件夹ImageView、URI、位图和画布对象都在第一个片段中 因为片段之间不能直接通信,所以我想用一个接口来实现这一点。我所做的是: 我已经在第二个片段中声明了我的接口 在MainActivity中应用了接口方法的逻辑,MainActivity是两个片段之间的共享活动 在

我正在构建一个包含2个片段的应用程序。第一个片段有一个ImageView和两个TextView,第二个片段有一组按钮和编辑文本。在第二个片段中,我有一个名为Save的按钮。单击此按钮时,我想将第一个片段中的图像下载到我的设备文件夹ImageView、URI、位图和画布对象都在第一个片段中

因为片段之间不能直接通信,所以我想用一个接口来实现这一点。我所做的是:

我已经在第二个片段中声明了我的接口 在MainActivity中应用了接口方法的逻辑,MainActivity是两个片段之间的共享活动 在第一个片段中输入了方法的必要参数。 没用
但我不认为这是正确的顺序,所以它不起作用也就不足为奇了。如何应用界面,使第二个片段中的按钮单击可下载第一个片段中的图像?

您可以尝试以下三个选项之一:

一,。使用回调通过活动进行通信

如中所示,您可以在片段2中定义一个接口,然后在单击按钮时调用该接口。保存片段2的活动为该接口提供了一个实现,在该接口中,该活动调用片段1中的方法来下载映像。例如:

提供下载方法的片段1

片段2定义和调用接口

对按钮单击作出反应并调用下载方法的活动

通过这种方式,您可以避免将片段链接在一起,而让活动在片段1和片段2之间建立松散的连接

这只是一个例子,我没有时间测试它。但我希望这能有所帮助

二,。使用本地广播

我建议使用LocalBroadcastManager在片段1中发送一个广播,即单击按钮并在片段2中接收该广播,然后下载图像。这是一篇关于地方广播的好文章

三,。另一个选项是使用ViewModel

ViewModel最近由新的Android Jetpack引入,旨在以生命周期意识的方式存储和管理与UI相关的数据。ViewModel类允许数据在配置更改(如屏幕旋转)后继续存在。从

它还可以用于在两个片段之间共享数据:您的活动基本上持有ViewModel,该活动中的片段可以通过调用ViewModelProviders.ofgetActivity.getSharedViewModel.class来访问它; 我认为,在您的场景中,您可以使用观察者或某种LiveData通过ViewModel对按钮单击做出反应


感谢@Elletlar帮助我改进答案。

为什么LocalBroadcastManager是首选方式?暂时忽略实现,最重要的设计考虑是什么?片段应该是可以安排在不同活动中的独立模块。让1个片段调用另一个片段中的接口是不可取的,因为它们耦合得太紧了。您可以以这样的方式实现第一个示例:在活动中调用回调,而不是将片段耦合在一起。@Elletlar我很乐意这样做。不幸的是,我在这方面没有太多经验。ViewModel相对于其他反应式框架的优势在于它是。但我可能更倾向于使用RxJava/RxKotlin而不是EventBus,原因如下:1。Rx存在于多种语言和平台2.高级功能:过滤3。作为一名承包商,我收到了很多关于RX4的面试问题。在StackOverflow上搜索这两个术语表明,RxJava/RxKotlin比EventBus更受欢迎/流行。话虽如此,我始终发现EventBus是可靠可靠的。@Elletlar我修改了我的答案。
public class Fragment1 extends Fragment {
    OnButtonClickedListener mCallback;

    public void startImageDownload() {
        // Download the image
    }

    // ...
}
public class Fragment2 extends Fragment {
    OnButtonClickedListener mCallback;

    // Some kind of init method called by onCreate etc. 
    private void init() {
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Call the listener if present
                if(mCallback != null) {
                    mCallback.onButtonClicked();
                }
            }
        });
    }

    public void setOnButtonClickedListener(Activity activity) {
        mCallback = activity;
    }

    // Container Activity must implement this interface
    public interface OnButtonClickedListener {
        public void onButtonClicked();
    }

    // ...
}
public static class MainActivity extends Activity implements Fragment2.OnButtonClickedListener {
    Fragment1 mFragment1;

    @Override
    public void onAttachFragment(Fragment fragment) {
        if (fragment instanceof Fragment2) {
            // Register the listener
            Fragment2 fragment2 = (Fragment2) fragment;
            fragment2.setOnButtonClickedListener(this);
        } else if (fragment instanceof Fragment1) {
            // Keep a reference to fragment 1 for calling the "download" method
            mFragment1 = (Fragment1) fragment;
        }
    }

    @Override
    public void onButtonClicked() {
        // Handle the button click
        mFragment1.startImageDownload();
    }
}