在片段之间传递数据

Posted

技术标签:

【中文标题】在片段之间传递数据【英文标题】:Pass data between fragments 【发布时间】:2016-11-21 23:24:39 【问题描述】:

我有一个 MainActivity 和两个片段。在 FragmentA 中,我有一个回收站视图。如果我点击那里的“添加”按钮,FragmentB 是打开的。我想做的是将文本写入一些 EditTexts 并将数据发送回 FragmentA(并在回收器视图中呈现该数据)。你能给我一些建议吗?谢谢

片段B

public class NewContactFragment extends Fragment 

    EditText name, number, email;
    public String mName;
    public String mNumber;
    public String mEmail;
    boolean isFavourite = false;

    public NewContactFragment() 
        // Required empty public constructor
    

    public static NewContactFragment newInstance() 
        NewContactFragment fragment = new NewContactFragment();
        Bundle bundle = new Bundle();
        fragment.setArguments(bundle);

        return fragment;

    

    @Override
    public void onCreate(Bundle savedInstanceState) 
        setHasOptionsMenu(true);
        super.onCreate(savedInstanceState);
    

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) 
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this, view);

        //set title
        ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.new_contact);
    

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

        name = (EditText) view.findViewById(R.id.ed_name);
        number = (EditText) view.findViewById(R.id.ed_number);
        email = (EditText) view.findViewById(R.id.ed_email);

        mName = name.getText().toString();
        mNumber = number.getText().toString();
        mEmail = email.getText().toString();

        return view;
    

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
        inflater.inflate(R.menu.new_contact_menu, menu);
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        switch (item.getItemId()) 
            case R.id.action_done:
                //TODO: save editTexts and return to ContactListFragment

                break;
            case R.id.action_favourite:
                getActivity().invalidateOptionsMenu();
                //Toast.makeText(getContext(), "isFavourite is: " + isFavourite, Toast.LENGTH_SHORT).show();
                break;
        
        return super.onOptionsItemSelected(item);
    

片段A

public class ContactListFragment extends Fragment implements View.OnClickListener 

    private static final String TAG = "newcontact";
    FloatingActionButton fabButton;
    SearchView searchView;
    RecyclerView recyclerView;
    ContactsAdapter contactsAdapter;
    List<Contact> mContact = new ArrayList<>();

    public static ContactListFragment newInstance() 
        Bundle args = new Bundle();
        ContactListFragment fragment = new ContactListFragment();
        fragment.setArguments(args);
        return fragment;
    

    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    

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

        searchView = (SearchView) view.findViewById(R.id.search_view);
        fabButton = (FloatingActionButton) view.findViewById(R.id.fab_button);
        fabButton.setOnClickListener(this);

        recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        mContact = SugarRecord.listAll(Contact.class);
        contactsAdapter = new ContactsAdapter(getActivity(), mContact);
        recyclerView.setAdapter(contactsAdapter);

        inputFilter();

        return view;
    

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) 
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this, view);

        //show actionBar
        ((MainActivity) getActivity()).getSupportActionBar().show();
        //show title
        ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.app_name);
    

    @Override
    public void onSaveInstanceState(Bundle outState) 
        super.onSaveInstanceState(outState);
    

    public void inputFilter() 
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() 
            @Override
            public boolean onQueryTextSubmit(String query) 
                return false;
            

            @Override
            public boolean onQueryTextChange(String newText) 
                contactsAdapter.filterList(newText);
                return true;
            
        );
    

    @Override
    //Fab button listener
    public void onClick(View v) 
        ((MainActivity) getActivity()).showFragment(new NewContactFragment(), TAG);
    

【问题讨论】:

你可以使用接口,***.com/questions/5194548/… How to pass values between Fragments的可能重复 【参考方案1】:

片段通常应该只与它们的直接父活动通信。片段通过其父活动进行通信,允许活动管理来自与其他片段或活动协调的片段的数据的输入和输出。将 Activity 视为管理与其中包含的每个片段的所有交互的控制器。

这方面的一些例外是从另一个片段或nested child fragments 中呈现的dialog fragments。这两种情况都是 Fragment 嵌套了子 Fragment 的情况,因此允许向上通信到其父 Fragment(即 Fragment)。

要记住的重要一点是,片段不应直接相互通信,并且通常应与其父活动通信。片段应该是模块化的、独立的和可重用的组件。在大多数情况下,片段允许其父 Activity 响应意图和回调。

片段和活动可以通过三种方式进行通信:

Bundle - Activity 可以构造片段并设置参数 方法 - Activity 可以调用片段实例上的方法 监听器 - Fragment 可以通过接口在活动上触发监听器事件

换言之,沟通一般应遵循以下原则:

Activity可以用data during construction初始化片段 活动可以将数据传递给片段using methods on the fragment instance 片段可以与它们的父活动通信using an interface and listeners 片段应将数据传递给仅通过其父活动路由的其他片段 片段可以在dialog fragments 之间传递数据 片段可以包含nested child fragments

在Creating and Using Fragments了解更多关于 Fragment 及其通信的信息

【讨论】:

深入回答真的@isnotmenow

以上是关于在片段之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章

kotlin:如何在两个片段之间传递数据

通过导航组件在底部导航片段之间传递数据

如何在导航抽屉中的两个片段之间传递数据

如何在底部导航片段(或导航抽屉)之间传递数据?

通过适配器在片段之间传递数据(Kotlin Android)

通过片段之间的导航传递数据android studio