Java Android使用自定义构造函数重新创建片段

Java Android使用自定义构造函数重新创建片段,java,android,android-fragments,Java,Android,Android Fragments,是否可以重新创建依赖于构造函数传递的LiveData的片段?我可以在娱乐后使用LiveData或ViewModel 我有一个viewPager2,它使用适配器创建片段。这些片段需要LiveData才能正常工作。在屏幕旋转之前一切都正常,因为android想要重新创建片段,但使用非arg构造函数,所以我无法再获取LiveData。有什么可以解决这个问题的吗 碎片 public class SensorFragment extends Fragment { private SensorVie

是否可以重新创建依赖于构造函数传递的LiveData的片段?我可以在娱乐后使用LiveData或ViewModel

我有一个viewPager2,它使用适配器创建片段。这些片段需要LiveData才能正常工作。在屏幕旋转之前一切都正常,因为android想要重新创建片段,但使用非arg构造函数,所以我无法再获取LiveData。有什么可以解决这个问题的吗

碎片

public class SensorFragment extends Fragment {
    private SensorViewModel viewModel;

    public static SensorFragment withSensor(LiveData<Sensor> sensor) {
        SensorViewModelFactory factory = new SensorViewModelFactory(sensor);
        SensorViewModel viewModel = factory.create(SensorViewModel.class);
        SensorFragment sensorFragment = new SensorFragment();
        sensorFragment.setViewModel(viewModel);
        return sensorFragment;
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {
        SensorFragmentBinding binding = DataBindingUtil
            .inflate(inflater, R.layout.sensor_fragment, container, false);

        binding.setLifecycleOwner(this);
        binding.setViewModel(viewModel);

        return binding.getRoot();
    }

    private void setViewModel(SensorViewModel viewModel) {
        this.viewModel = viewModel;
    }
}
编辑 我已经这样更改了SensorFragment(现在它可以工作了)

公共类SensorFragment扩展了片段{
专用实时数据传感器;
带传感器的公共静态传感器(LiveData传感器){
SensorFragment SensorFragment=新的SensorFragment();
传感器碎片。设置传感器(传感器);
返回感测器片段;
}
@凌驾
创建视图时的公共视图(@NonNull LayoutInflater充气机,@null可查看组容器,
@可为空的捆绑包savedInstanceState){
SensorFragmentBinding=DataBindingUtil
.充气(充气机,右侧布局,传感器碎片,容器,假);
SensorViewModel viewModel=ViewModelProviders.of(this.get)(SensorViewModel.class);
如果(传感器!=null)
viewModel.setSensor(传感器);
binding.setLifecycleOwner(此);
binding.setViewModel(viewModel);
返回binding.getRoot();
}
公共传感器(LiveData传感器){
该传感器=传感器;
}
}

在我看来,您的活动应该创建/初始化一个ViewModel,并在ViewPager中与其片段共享同一个ViewModel

例如:

MyActivity.java:

public class MyActivity extends AppCompatActivity{

    @Override
    void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState)
        setContent(...)

        MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        ...
    }
}
在你的片段中:

MyFragment.java:

public class MyFragment1 extends Fragment {

    @Override
    void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState)
        setContent(...)

        MyViewModel myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
        ...
    }
}

原因是在重新创建活动时,ViewModel不会被销毁。ViewModel中的所有数据保持原样。它经受住了方向的变化。

有一种方法可以在一个活动的两个单独片段中访问viewmodel的一个实例。只需将活动传递到片段中的
ViewModelProviders.of(getActivity())
方法

public class SensorAdapter extends FragmentStateAdapter {
    private List<LiveData<Sensor>> sensors;

    ...

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return SensorFragment.withSensor(sensors.get(position));
    }

    ...
}
在温度计碎片和传感器碎片访问视图模型中,如下所示:

ThermometerViewModel viewModel = ViewModelProviders.of(getActivity())
            .get(ThermometerViewModel.class);

通常,对viewmodel的引用存储在片段中,而不是livedatas。当您需要访问livedata时,只需通过viewmodel获取它。

没有正确的方法将参数非参数属性传递到片段中。因此,您将无法以这种方式实现您的目标。此外,您构建的
SensorViewModel
不正确,它不会在配置更改后继续存在。那么我应该如何构建SensorViewModel呢?您创建
ThermometerViewModel
的方式是正确的,您应该以同样的方式创建
SensorViewModel
。您想从
SensorFragment
访问
ThermometerViewModel
中托管的LiveData,我说得对吗?是的,您说得对。ViewPager2适配器从温度计VIEWModel获取传感器列表,并将每个传感器传递给传感器碎片
public class MyActivity extends AppCompatActivity{

    @Override
    void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState)
        setContent(...)

        MyViewModel myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        ...
    }
}
public class MyFragment1 extends Fragment {

    @Override
    void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState)
        setContent(...)

        MyViewModel myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
        ...
    }
}
ThermometerViewModel viewModel = ViewModelProviders.of(getActivity())
            .get(ThermometerViewModel.class);