简体   繁体   English

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

[英]How to call a method in a fragment through the onClick in another fragment?

I am building an app with 2 fragments. 我正在构建一个包含2个片段的应用程序。 The 1st fragment has an ImageView and 2 TextViews and the 2nd fragment has a set of buttons and EditTexts. 第一个片段具有一个ImageView和2个TextView,第二个片段具有一组按钮和EditTexts。 In the 2nd fragment, I have a button called "Save". 在第二个片段中,我有一个名为“保存”的按钮。 When this button is clicked, I want to download the image inside my 1st fragment to my device folder (The ImageView, the URI, the bitmap and canvas objects are all in the 1st fragment). 单击此按钮后,我想将第一个片段中的图像下载到设备文件夹中(ImageView,URI,位图和画布对象都在第一个片段中)。

Because fragments can't communicate with one another directly, I was thinking of doing this with an interface. 由于片段无法直接相互通信,因此我正在考虑使用一种接口来实现。 What I did was: 我所做的是:

  • I've declared my interface in the 2nd fragment 我在第二个片段中声明了我的接口
  • Applied the logic of the interface's method in the MainActivity (which is the shared activity between the 2 fragments) 在MainActivity中应用了接口方法的逻辑(这是两个片段之间的共享活动)
  • Fed the necessary parameters for the method in the 1st fragment. 在第一个片段中为该方法提供了必要的参数。
  • Didn't work 没工作

But I don't think that this was the correct order so it's no surprise that it didn't work. 但是我不认为这是正确的顺序,因此它不起作用也就不足为奇了。 How do I apply the interface in a way that a button click in the 2nd fragment downloads the image in the 1st fragment? 如何以第二个片段中的按钮单击的方式应用界面,以下载第一个片段中的图像?

You could try one of these three options: 您可以尝试以下三个选项之一:

1.) Using callbacks to communicate via the activity 1.)使用回调通过活动进行通信

As shown in this article , you can define an interface in fragment 2 which is then called when the button is clicked. 本文所示,您可以在片段2中定义一个接口,然后在单击按钮时调用该接口。 Your activity (which holds fragment 2) provides an implementation for that interface in which the activity calls a method in fragment 1 for downloading the image. 您的活动(包含片段2)为该接口提供了一个实现,其中该活动调用片段1中的方法来下载图像。 For example: 例如:

Fragment 1 providing the download method 片段1提供下载方法

public class Fragment1 extends Fragment {
    OnButtonClickedListener mCallback;

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

    // ...
}

Fragment 2 defining and calling the interface 片段2定义和调用接口

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

    // ...
}

The Activity reacting on the Button click and calling the download method 该活动对“按钮”单击做出反应并调用下载方法

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

This way you avoid linking the fragments together, instead you have the activity beeing a loose "connection" between fragment 1 and fragment 2. 这样,您可以避免将片段链接在一起,而是可以在片段1和片段2之间进行松散的“连接”操作。

This is just an exmple, i did not had time to test it. 这只是一个例子,我没有时间进行测试。 But i hope it helps. 但我希望它会有所帮助。

2.) Using a local broadcast 2.)使用本地广播

I would recommend using the LocalBroadcastManager for sending a broadcast in fragment 1 (that the button was clicked) and receiving it in fragment 2 (downloading the image). 我建议使用LocalBroadcastManager在片段1中发送广播(单击该按钮)并在片段2中接收广播(下载图像)。 Here is a great article about local broadcasts. 是一篇有关本地广播的精彩文章。

3.) Another option is to use ViewModel 3.)另一个选择是使用ViewModel

The ViewModel was recently introduced by the new Android Jetpack and "is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations." ViewModel最近由新的Android Jetpack引入,并且“被设计为以生命周期意识的方式存储和管理与UI相关的数据。ViewModel类允许数据经受住诸如屏幕旋转之类的配置更改。” (from ViewModel Overview ). (来自ViewModel概述 )。

It can also be used to share data between two fragments : Your activity basically holds the ViewModel and the fragments (inside that activity) can get access to it by calling: ViewModelProviders.of(getActivity()).get(SharedViewModel.class); 它也可以用于在两个片段之间共享数据 :您的活动基本上包含ViewModel,并且这些片段(在该活动内部)可以通过调用以下内容进行访问: ViewModelProviders.of(getActivity()).get(SharedViewModel.class); I think your scenario you could use Observers or some kind of LiveData to react to the button-click via a ViewModel. 我认为您可以使用Observers或某种LiveData通过ViewModel对按钮单击做出反应。

Thanks to @Elletlar for helping me improve my answer. 感谢@Elletlar帮助我改善答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM