android– 我们如何获取数据绑定以使用已保存的实例状态?

android– 我们如何获取数据绑定以使用已保存的实例状态?,第1张

概述TL;DR:如果与数据绑定一起使用的布局具有EditText,并且有一个用于android:text的绑定表达式,则绑定表达式将覆盖保存实例状态值…即使我们没有明确触发绑定评估.用户在配置更改消失之前键入的内容.我们如何解决这个问题,以便在配置更改时使用保存的实例状态值?我们有一个愚蠢的模

TL; DR:如果与数据绑定一起使用的布局具有EditText,并且有一个用于android:text的绑定表达式,则绑定表达式将覆盖保存的实例状态值…即使我们没有明确触发绑定评估.用户在配置更改消失之前键入的内容.我们如何解决这个问题,以便在配置更改时使用保存的实例状态值?

我们有一个愚蠢的模型:

public class Model {  public String getTitle() {    return("Title");  }}

我们有一个引用该模型的布局:

<?xml version="1.0" enCoding="utf-8"?><layout xmlns:androID="http://schemas.androID.com/apk/res/androID"  xmlns:app="http://schemas.androID.com/apk/res-auto">  <data>    <variable      name="model"      type="com.commonsware.databindingstate.Model" />  </data>  <androID.support.constraint.ConstraintLayout xmlns:tools="http://schemas.androID.com/tools"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    tools:context="com.commonsware.databindingstate.MainActivity">    <EditText androID:ID="@+ID/Title"      androID:layout_wIDth="0dp"      androID:layout_height="wrap_content"      androID:inputType="text"      app:layout_constraintleft_toleftOf="parent"      app:layout_constraintRight_toRightOf="parent"      app:layout_constrainttop_totopOf="parent" />  </androID.support.constraint.ConstraintLayout></layout>

请注意,此布局没有绑定表达式;我们稍后会谈到这一点.

布局用于动态片段:

public class FormFragment extends Fragment {  @Nullable  @OverrIDe  public VIEw onCreateVIEw(LayoutInflater inflater,                           @Nullable VIEwGroup container,                           @Nullable Bundle savedInstanceState) {    return(MainBinding.inflate(inflater, container, false).getRoot());  }}

请注意,我们不会在任何地方调用setModel()来将模型推送到绑定中. MainBinding(对于上面显示的main.xml布局)仅用于夸大布局.

此代码(具有合适的FragmentActivity来设置FormFragment)正确使用已保存的实例状态.如果用户在EditText中键入内容,然后旋转屏幕,则新重新创建的EditText会显示输入的文本.

现在,让我们更改布局为androID:text添加绑定表达式:

<?xml version="1.0" enCoding="utf-8"?><layout xmlns:androID="http://schemas.androID.com/apk/res/androID"  xmlns:app="http://schemas.androID.com/apk/res-auto">  <data>    <variable      name="model"      type="com.commonsware.databindingstate.Model" />  </data>  <androID.support.constraint.ConstraintLayout xmlns:tools="http://schemas.androID.com/tools"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    tools:context="com.commonsware.databindingstate.MainActivity">    <EditText androID:ID="@+ID/Title"      androID:layout_wIDth="0dp"      androID:layout_height="wrap_content"      androID:inputType="text"      androID:text="@{model.Title}"      app:layout_constraintleft_toleftOf="parent"      app:layout_constraintRight_toRightOf="parent"      app:layout_constrainttop_totopOf="parent" />  </androID.support.constraint.ConstraintLayout></layout>

现在,如果用户在EditText中键入内容并旋转屏幕,则新重新创建的EditText为空.绑定表达式将覆盖从保存的实例状态恢复的框架.

尽管事实上我没有在绑定上调用setModel(),但这仍然存在.我当然可以看到我在绑定上调用setModel()的位置,它将使用模型中的数据替换EditText内容.但我不这样做.

我可以在官方设备(Google Pixel,AndroID 8.0)和生态系统设备(Samsung galaxy S8,AndroID 7.1)上重现此行为.

这可以通过自己保存状态并在某些时候恢复它来“手动”解决.例如,多个注释建议双向绑定,但这与其他设计目标(例如,不可变模型对象)相反.这似乎是数据绑定的一个相当基本的限制,所以我希望有一些我错过的东西,我可以配置为自动使用保存的实例状态.

解决方法:

我认为ianhanniballake提到了一个相关的答案,但也许还有更多.以下是我对该参考如何应用于这些情况的解释.

使用您提供的XML,以下代码将交替从已保存的实例状态还原并从模型还原.当恢复保存的实例状态时,可能是没有实例化的模型要从中恢复.那是mCount是偶数的时候.如果存在模型,则基本上忽略保存的实例状态并且绑定接管.这里有一个比我们想要的更多的逻辑,但它不是明确地保存和恢复.

为了论证,mCount只是一个技巧.将使用标志或是否存在模型的其他指示.

public class MainActivity extends AppCompatActivity {    private ActivityMainBinding binding;    private int mCount;    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        binding = DataBindingUtil.setContentVIEw(this, R.layout.activity_main);        mCount = (savedInstanceState == null) ? 0 : savedInstanceState.getInt("mCount", 0);        if (mCount % 2 == 1) {            // 1st, 3rd, 5th, etc. rotations. Explicitly execute the bindings and let the framework            // restore from the saved instance state.            binding.executePendingBindings();        } else {            // First creation and 2nd, 4th, etc. rotations. Set up our model and let the            // framework restore from the saved instance state then overwrite with the bindings.            // (Or maybe it just ignores the saved instance state and restores the bindnings.)            Model model = new Model();            binding.setModel(model);        }        mCount++;    }    @OverrIDe    public voID onSaveInstanceState(Bundle bundle) {        super.onSaveInstanceState(bundle);        bundle.putInt("mCount", mCount);    }}
总结

以上是内存溢出为你收集整理的android – 我们如何获取数据绑定以使用已保存的实例状态?全部内容,希望文章能够帮你解决android – 我们如何获取数据绑定以使用已保存的实例状态?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1118485.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存