java - Android 使用自定义构造函数重新创建 fragment

标签 java android android-fragments

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

我有一个 viewPager2,它使用适配器创建 fragment 。 fragment 需要 LiveData 才能正常工作。一切工作正常,直到屏幕旋转,因为然后 android 想要重新创建 Fragment 但使用非参数构造函数,所以我无法再获取 LiveData。有什么可以帮助解决这个问题吗?

fragment

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;
    }
}

ViewModel 工厂使用自定义构造函数创建 ViewModel

public class SensorViewModelFactory implements ViewModelProvider.Factory {
    private LiveData<Sensor> sensor;

    public SensorViewModelFactory(LiveData<Sensor> sensor) {
        this.sensor = sensor;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        return (T) new SensorViewModel(sensor);
    }
}

创建 fragment 的ViewPager2适配器。

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

    ...

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

    ...
}

保存 ViewPager2 的 fragment

public class ThermometerFragment extends Fragment {

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

        ThermometerViewModel viewModel = ViewModelProviders.of(this)
            .get(ThermometerViewModel.class);
        SensorAdapter sensorAdapter = new SensorAdapter(this);
        viewModel.getThermometer().observe(this, thermometer ->
            sensorAdapter.setSensors(thermometer.getSensors()));

        binding.setAdapter(sensorAdapter);

        return binding.getRoot();
    }

}

编辑 我已经像这样更改了 SensorFragment(现在它可以工作了)

public class SensorFragment extends Fragment {
    private LiveData<Sensor> sensor;

    public static SensorFragment withSensor(LiveData<Sensor> sensor) {
        SensorFragment sensorFragment = new SensorFragment();
        sensorFragment.setSensor(sensor);
        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);

        SensorViewModel viewModel = ViewModelProviders.of(this).get(SensorViewModel.class);
        if (sensor != null)
            viewModel.setSensor(sensor);

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

        return binding.getRoot();
    }

    public void setSensor(LiveData<Sensor> sensor) {
        this.sensor = sensor;
    }
}

最佳答案

IMO,您的 Activity 应该创建/初始化一个 ViewModel,并与其在 ViewPager 中的 Fragments 共享相同的 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);
        ...
    }
}

在你的 fragment 中:

MyFragment.java:

public class MyFragment1 extends Fragment {

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

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

原因是重新创建 Activity 时 ViewModel 不会被销毁。 ViewModel 中的所有数据都保持原样。它在方向改变后仍然存在。

关于java - Android 使用自定义构造函数重新创建 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59487479/

相关文章:

java - findViewById 在 Fragment 中找不到 ImageButton

java - 在 Java Card 2.2.1 平台中存储日期和时间

java.sql.SQLException : Communication failure during handshake. 是否有服务器在本地主机 :3306? 上运行

java - 在循环体周围使用 try/catch block 抽象循环

android - 设置 TextView 可绘制对象的颜色

android - 在 ImageView 中绘制文本

android - BottomSheetDialogFragment AdjustResize SoftInput 不起作用

android - 如何删除android view pager中两个 fragment 之间的空格?

java - Spring Boot JAR 应用程序未从资源文件夹中读取 chromedriver.exe

Android:自动启动应用程序和加载首选项