我正在使用ViewPager托管的不同片段。
这样做的主要目的是因为我需要将纸质表格转换为数字表格,并且出于用户友好的目的,我决定让用户在所有片段之间滑动并完成每个片段,直到结束为止。表格。
我的目标是在最近刷过的片段的末尾构造一个对象,因此,那时我将拥有来自以下片段的所有数据。
我进行了研究,发现我可以使用setArguments()
将一束数据从每个片段传递到下一个片段,直到结尾,这是一个好主意,因为如果用户想要返回,他们可以更改一些参数并保持滑动的过程直到最后,最后一个片段中,我将使用所有片段中的所有参数来创建一个唯一的对象,其中包含代表整个表单的所有数据。
这是我尝试过的
首先,我创建了一个简单的ViewPager
适配器,以便在滑动时在不同片段之间切换
class MyPagerAdapter(fm:FragmentManager): FragmentStatePagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
return when(position){
0 -> FragmentA.newInstance()
1 -> FragmentB.newInstance()
2 -> FragmentC.newInstance()
else -> {
FragmentA()
}
}
}
override fun getCount(): Int {
return 3
}
}
然后我在MainActivity的viewpager中使用该适配器
class MainActivity : FragmentActivity(), MainContract.MainView {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupViewPager()
}
override fun setupViewPager() {
viewPager.adapter = MyPagerAdapter(supportFragmentManager)
viewPager.disableScroll(true)
selectIndex(0)
}
override fun selectIndex(newIndex: Int) {
viewPager.currentItem = newIndex
}
override fun getFragment(position: Int): Fragment {
return MyPagerAdapter(supportFragmentManager).getItem(position)
}
}
这是我需要将参数从 FragmentA 传递给 FragmentB
的地方class FragmentA : Fragment() {
companion object {
fun newInstance(): FragmentA = FragmentA()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_A, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
fab_continue.setOnClickListener {
val name = etxt_name.text.toString().trim()
val phone = etxt_phone.text.toString().trim()
val bundle = Bundle()
bundle.putString("name",name)
bundle.putString("phone",phone)
(activity as MainActivity).getFragment(1).arguments = bundle
(activity as MainActivity).selectIndex(1)
}
}
我假设是
(activity as MainActivity).getFragment(1).arguments = bundle
获取并填充下一个片段,该片段为 FragmentB 并将参数传递给它
而
(activity as MainActivity).selectIndex(1)
只需使用 FragmentB
滑动到下一页现在,问题在于,应用启动时,会立即执行 FragmentB 中的 getArguments ,但我什至还没有刷过它,或者从中传递了参数> FragmentA ,并为 getArguments 生成空值。
使用上面的代码,我认为从 FragmentA 按下fab按钮后,getFragment(1)
方法将实例化 FragmentB ,但是似乎没有做应该做的事。
所以在我的FragmentB
class FragmentB: Fragment() {
companion object {
fun newInstance(): FragmentB = FragmentB()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("Argumentos:",""+arguments?.getString("name")) //This returns null
}
arguments?.getString("name")
返回null
答案 0 :(得分:1)
我认为您应该使用默认的“工厂方法”模板。创建Fragment
时选中这些复选框
之后,您可以看到带有构造函数newInstance()
像这样在活动中创建片段
BlankFragment.newInstance("First Thing", "Second String")
对于Fragment
,将生成访问方式
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
现在您可以拥有这些值param1
和param2
。
如果要使用构造方法:
public class BlankFragment extends Fragment {
public BlankFragment()
{} // Empty Constructor required
public BlankFragment(int someParam)
{
// your constructor
}
}
这也可以,但是您将有2个构造函数,而您只能使用一种工厂方法(并且它是由AndroidStudio自动生成的!)
答案 1 :(得分:1)
推荐的简单解决方案是使用View Model guide中所述的ViewModel
。喜欢的东西:
MyViewModel model = ViewModelProviders.of(yourActivity).get(MyViewModel.class); // in your activity
// in your fragments
model = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
model.yourFunctionToChangeData(yourData);
// observer result in other fragments
model.getSelected().observe(this, { yourData ->
// Update the UI.
});
通过使用ViewModel
,该模型在Activity中创建一次,并在Activity
内部的所有片段之间共享。