Android子片段向父片段传递值

5

当我尝试在关闭片段时从片段中获取值时遇到了一些问题。我的片段A会打开片段B,当片段B中的按钮被点击时,我想要获取一个值并传回到片段A以显示。然而,我不确定该如何实现。

片段A:

@Click(R.id.buttonAttach)
void buttonAttachClicked(View v){
        SupportAttachFileFragment fragment = new SupportAttachFileFragment_();
        fragment.show(getFragmentManager(), null);

        // get value here and display
        textViewLogCounter.setText();
    }
}

片段 B:

当这个按钮被点击时,我希望将值传回片段 A 并显示出来。

@Click(R.id.buttonAttach)
void buttonAttachClicked(View v){
    System.out.println("TOTAL " + selectedRows.size());
    dismiss();
}

我不确定如何做到这一点。我考虑使用Bundle,但Bundle是将参数传递给新的Activity。在这种情况下,我的Fragment已经打开,但我想要返回一些值。

有什么想法吗?谢谢!


尝试这个 https://dev59.com/WGAg5IYBdhLWcg3w3uMR#23079798 - Ankita
https://developer.android.com/reference/android/arch/lifecycle/ViewModel - AskNilesh
3个回答

7
您可以使用共享的 ViewModel。在活动范围内创建 ViewModel,它将对活动及其所有片段可用。
MyViewModel sharedViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel::class.java)

然后观察您所需的sharedViewModel数据。如果您在任何片段或活动中更改sharedViewModel的数据,它将更改所有片段和活动的数据。请参见下面的图像或阅读doc

enter image description here


4

所有片段到片段的通信都是通过共享的ViewModel或相关联的Activity完成的。两个片段不应直接通信。

片段之间通信的不同方式:

  1. The recommended way to communicate between fragments is to create a shared ViewModel object. Both fragments can access the ViewModel through their containing Activity. The Fragments can update data within the ViewModel and if the data is exposed using LiveData the new state will be pushed to the other fragment as long as it is observing the LiveData from the ViewModel. To see how to implement this kind of communication, read the 'Share data between Fragments' section in the ViewModel guide.

  2. You can define an interface in the Fragment class and implement it within the Activity. The Fragment captures the interface implementation during its onAttach() lifecycle method and can then call the Interface methods in order to communicate with the Activity.

    public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback;

    // Container Activity must implement this interface
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    
        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnHeadlineSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }
    
    ...
    

    }

现在,Fragment可以通过使用OnHeadlineSelectedListener接口的mCallback实例调用onArticleSelected()方法(或其他方法)向Activity发送消息。
例如,在用户单击列表项时,以下方法将在Fragment中被调用。 Fragment使用回调接口将事件传递给父Activity。
@Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Send the event to the host activity
        mCallback.onArticleSelected(position);
    }

实现接口

为了从片段中接收事件回调,托管该片段的活动必须实现片段类中定义的接口。

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article
    }
}

向片段传递消息

主活动可以通过使用findFragmentById()捕获片段实例并直接调用片段的公共方法,向片段传递消息。

例如,假设上面展示的活动可能包含另一个用于显示由上述回调方法返回的数据中指定的项的片段。在这种情况下,活动可以将接收到的信息传递给另一个将显示该项的片段:

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article

        ArticleFragment articleFrag = (ArticleFragment)
                getSupportFragmentManager().findFragmentById(R.id.article_fragment);

        if (articleFrag != null) {
            // If article frag is available, we're in two-pane layout...

            // Call a method in the ArticleFragment to update its content
            articleFrag.updateArticleView(position);
        } else {
            // Otherwise, we're in the one-pane layout and must swap frags...

            // Create fragment and give it an argument for the selected article
            ArticleFragment newFragment = new ArticleFragment();
            Bundle args = new Bundle();
            args.putInt(ArticleFragment.ARG_POSITION, position);
            newFragment.setArguments(args);

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            // Replace whatever is in the fragment_container view with this fragment,
            // and add the transaction to the back stack so the user can navigate back
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);

            // Commit the transaction
            transaction.commit();
        }
    }
}

来自官方文档存档版本


2

要在片段之间共享数据,您可以使用ViewModel。

ViewModel为活动的不同片段提供了通信层。要在片段关闭时获取数据,也可以使用onActivityResult。

有关详细示例,请参阅此链接- Android:从子片段传递数据到父片段


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接