从底部对话框片段中获取价值

时间:2018-04-12 10:56:12

标签: android fragment bottom-sheet dialogfragment

我从片段A开始使用bottomSheetDialogFragment。 我想从该bottomSheetDialogFragment中选择日期,然后在片段A中设置它。

选择日期已经完成,我只想在片段A中获取它以在某些字段中设置它。

我怎样才能获得价值? 有什么建议吗?

8 个答案:

答案 0 :(得分:5)

创建一个像这样的接口类

public interface CustomInterface {

    public void callbackMethod(String date);
}

ActivityFragment中实施此界面。并创建此接口的对象。

private CustomInterface callback;

onCreateonCreateView

中对其进行初始化
callback=this;

现在,当您调用它时,在BottomSheetDialogFragment构造函数中传递此回调。

yourBottomSheetObject = new YourBottomSheet(callback);
yourBottomSheetObject.show(getSupportFragmentManager()," string");

现在在BottomSheetFragment的构造函数

私人CustomInterface回调;

public SelectStartTimeSheet(CustomInterface callback){

this.callback=callback;

}

最后使用此回调对象设置日期

callback.callbackMethod("your date");

并且您将在callbackMethod函数中的片段或活动中收到此日期。

答案 1 :(得分:2)

Android 导航架构组件

例如:

假设您使用 navController 从片段 A 中打开片段 B。

并且您想要一些从片段 B 到片段 A 的数据。

class B :BottomSheetDialogFragment() {

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.your_layout, container, false)

        root.sampleButton.setOnClickListener {
            val navController = findNavController()
            navController.previousBackStackEntry?.savedStateHandle?.set("your_key", "your_value")
            dismiss()

        }
}

并在您的片段 A 中:

findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>("your_key")
                ?.observe(viewLifecycleOwner) {
    
                    if (it == "your_value") {
                        //your code
    
                    }
    
                }

答案 2 :(得分:1)

如果使用的是BottomSheetDialogFragment,则由于它是一个片段,因此应创建您的接口并在该片段的onAttach生命周期方法上绑定到该接口,并根据您的侦听器/回调类型对活动进行适当的转换。

例如,当有人单击片段的内部recyclerview项时,在您的活动中实现此界面并调度更改

这是一种众所周知的模式,在here

中有更好的解释

一个大建议是重新考虑您的应用程序架构,因为最好的方法是始终通过Bundle在Android组件之间传递原始/简单/微小的数据,并且您的组件以后可以检索其依赖项所需要的状态。

例如,您永远不要传递大型对象,例如位图,数据类,DTO或视图引用。

  • 首先,关于Parcel正在进行一些序列化过程,这会影响应用程序的响应速度
  • 第二秒可能会导致您遇到TransactionTooLarge类型的错误。

希望有帮助!

答案 3 :(得分:0)

重写片段的构造函数是一个不好的做法,如文档所述:

  

每个片段都必须有一个        *空构造函数,因此可以在还原其时实例化它        *活动状态。

如果您使用另一个将回调作为参数传递的构造函数,则当该片段被框架重新存储时,您的应用程序将崩溃

推荐的方法是使用viewModel和livedata。

答案 4 :(得分:0)

您也可以使用LocalBroadcastManager。正如hglf所说,如果您仍想使用接口callBack方式,最好保留片段的空构造函数,并使用newInstance(Type value)实例化片段。

答案 5 :(得分:0)

您可以按以下方式使用do:

选择帐户片段代码


class SelectAccountFragment(val clickListener: OnOptionCLickListener) : BottomSheetDialogFragment() {


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.bottom_fragment_accounts, container, false)
    }



    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val list = DataProcessorApp(context).allUsers

        val rvAccounts = view.findViewById<RecyclerView>(R.id.rvAccounts)

        rvAccounts.layoutManager = LinearLayoutManager(context)
        rvAccounts.adapter = AccountsAdapter(context, list)

        Log.e(tag,"Accounts "+list.size);

        tvAccountAdd.setOnClickListener {
            val intent = Intent(context,LoginActivity::class.java)
            startActivity(intent)
        }

        tvManageAccounts.setOnClickListener {
            Log.e(tag,"Manage Click")
            clickListener.onManageClick()
        }
    }


    interface OnOptionCLickListener{
        fun onManageClick()
    }

}


现在显示并调用另一个片段/活动,如下所示

 SelectAccountFragment accountFragment = new SelectAccountFragment(() -> {

          //get fragment by tag and dismiss it

          BottomSheetDialogFragment fragment = (BottomSheetDialogFragment) getChildFragmentManager().findFragmentByTag(SelectAccountFragment.class.getSimpleName();
          if (fragment!=null){
               fragment.dismiss();
          }

});

accountFragment.show(getChildFragmentManager(),SelectAccountFragment.class.getSimpleName());

答案 6 :(得分:0)

您可以使用 Navigation 库的好处:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val navController = findNavController();
    // After a configuration change or process death, the currentBackStackEntry
    // points to the dialog destination, so you must use getBackStackEntry()
    // with the specific ID of your destination to ensure we always
    // get the right NavBackStackEntry
    val navBackStackEntry = navController.getBackStackEntry(R.id.your_fragment)

    // Create our observer and add it to the NavBackStackEntry's lifecycle
    val observer = LifecycleEventObserver { _, event ->
        if (event == Lifecycle.Event.ON_RESUME
            && navBackStackEntry.savedStateHandle.contains("key")) {
            val result = navBackStackEntry.savedStateHandle.get<String>("key");
            // Do something with the result
        }
    }
    navBackStackEntry.lifecycle.addObserver(observer)

    // As addObserver() does not automatically remove the observer, we
    // call removeObserver() manually when the view lifecycle is destroyed
    viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
        if (event == Lifecycle.Event.ON_DESTROY) {
            navBackStackEntry.lifecycle.removeObserver(observer)
        }
    })
}

有关详细信息,请阅读the document

答案 7 :(得分:-2)

接受的答案是错误的。

您只能在调用show()时使用用户Fragment A的childFragmentManager。

像这样:

val childFragmentManager = fragmentA.childFragmentManager
bottomSheetDialogFragment.show(childFragmentManager, "dialog")