简体   繁体   English

双向绑定Android

[英]Two way binding Android

Maybe I am missing something small here, but I cannot get my binding to work. 也许我在这里缺少一些小东西,但是我无法束缚工作。 I set it up as follow: 我将其设置如下:

public class Toolbar extends Fragment {

//Interaction handlers
//interface for interaction with Activity
public interface ToolBarInteraction{
    public void Search(String screenName);
}

private ToolbarBind modelData;
private ToolBarInteraction mListener;

public static Toolbar newInstance() {
    return new Toolbar();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    FragmentToolbarBinding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_toolbar);
    modelData = ToolbarBind.newInstance();
    modelData.searchedText.set("Hello");
    binding.setModelData(modelData);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    checkMListener();

    View view = inflater.inflate(R.layout.fragment_toolbar, container, false);

    //get button to set onClick event
    Button button = (Button)view.findViewById(R.id.btnSearch);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String hello = modelData.searchedText.get();
        }
    });

    return view;
}

public void OnSearchClicked(View view){
    mListener.Search(modelData.searchedText.get());
}

private void checkMListener(){
    try{
        mListener = (ToolBarInteraction) getActivity();
    } catch (ClassCastException ex) {
        throw new ClassCastException(getActivity().toString()
                + " must implement the ToolBarInteraction Interface");
    }
}
}

Here is the code for ToolbarBind: 这是ToolbarBind的代码:

public class ToolbarBind extends BaseObservable {
private String _searchText;

public final ObservableField<String> searchedText = new ObservableField<String>();

//factory method
public static ToolbarBind newInstance(){ return new ToolbarBind(); }
}

And in my fragment, I set the binding up as follow, all within the layout tag: 在我的片段中,我将绑定设置如下,所有这些都在layout标签中:

<data>
    <variable
        name="modelData"
        type="Common.CommonObjects.ToolbarBind"/>
</data>

And for binding to property: 并绑定到属性:

<EditText
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:hint="Search"
     android:text="@={modelData.searchedText}"/>

As can be seen, in the onCreate I set the text to "Hello", but even when the view displays on the phone, the EditText is not populated with this text. 可以看到,在onCreate我将文本设置为“ Hello”,但是即使在电话上显示视图时,也不会用此文本填充EditText。 When I change the value, and click my button, the value I get back in the event is "Hello", not my new text entered while the app is running. 当我更改值并单击我的按钮时,在事件中返回的值是“ Hello”,而不是应用程序运行时输入的新文本。

What am I missing? 我想念什么?

The problem with your code is that you set the Activity 's content view to something in onCreate(...) but you inflate and use something different in onCreateView(...) as your fragment's view, which gets the model data (not the other one you created in onCreate(...) ). 代码的问题是,您将Activity的内容视图设置为onCreate(...)某个内容,但在onCreateView(...)中将其充气并使用其他内容作为片段的视图,从而获取模型数据(而不是您在onCreate(...)创建的另一个。 I don't know exactly what you try to achieve, but I'm gonna guess that you don't want to change the Activity 's content view to something from the fragment, so I'm just gonna show you a variation of what could you use, however, you should change it to whatever pleases you. 我不知道究竟你试图达到的目标,但我会猜你不想改变Activity的内容,以便从该片段的东西,所以我只是要告诉你的变化是什么可以使用,但是,您应该将其更改为任何您喜欢的东西。

Remove onCreate(...) completely then use only onCreateView(...) to inflate the fragment_toolbar layout using data binding: 完全删除onCreate(...)然后仅使用onCreateView(...)通过数据绑定来增加fragment_toolbar布局:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    checkMListener();

    FragmentToolbarBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_toolbar, container, false);

    // FIXME you're losing data here; watch out: checking whether savedInstanceState == null is not enough because returning from backstack it will be null
    modelData = ToolbarBind.newInstance();

    // FIXME modify this so it sets the data from savedInstanceState when configuration changes
    modelData.searchedText.set("Hello");


    binding.setModelData(modelData);

    //get button to set onClick event
    binding.btnSearch.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String hello = modelData.searchedText.get();
        }
    });

    return binding.getRoot();
}

Watch out for the FIXME parts. 当心FIXME零件。 You could move the modelData init to onCreate(...) which would save it from the backstack-return thing, however, configuration change will still call onCreate(...) unless you call setRetainInstance(true) on the fragment ( do not ). 可以modelData init移到onCreate(...) ,以将其从后退返回中保存,但是,除非对片段调用setRetainInstance(true) ,否则配置更改仍将调用onCreate(...)不要 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM