Reputation: 7823
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:
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:
<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. 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.
What am I missing?
Upvotes: 0
Views: 118
Reputation: 6393
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(...)
). 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.
Remove onCreate(...)
completely then use only onCreateView(...)
to inflate the fragment_toolbar
layout using data binding:
@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. 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).
Upvotes: 1