问题
I am building an Android app, where I want to toggle the visibility of some view elements based on a button click. I am trying to archive it with data-binding instead of using findViewById(), but all the solutions I've have found until now doesn't update the layout, when the variable is changed.
Here is what I have so far. (I've simplified the code, to focus on the problem)
Activicy.java
public class RecipeActivity extends AppCompatActivity {
private Recipe recipe;
private ActivityRecipeBinding binding;
private RecipeBinderHelper rbhelper = new RecipeBinderHelper();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
recipe = intent.getParcelableExtra("recipe");
binding = DataBindingUtil.setContentView(this, R.layout.activity_recipe);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(recipe.getName());
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
binding.recipeContent.setRecipe(recipe);
binding.recipeContent.setHelper(rbhelper);
binding.Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//HERE I CHANGE THE VALUE OF THE VARIBLE
rbhelper.setPresentationViewVisible(false);
binding.notifyChange();
}
});
}
}
Helper class
public class RecipeBinderHelper{
private Boolean presentationElementsVisible;
private Boolean timerElementsVisible;
public RecipeBinderHelper(){
this.presentationElementsVisible = true;
this.timerElementsVisible = false;
}
public void setPresentationViewVisible(boolean presentationElementsVisible) {
this.presentationElementsVisible = presentationElementsVisible;
}
public Boolean getPresentationElementsVisible() {
return presentationElementsVisible;
}
//getters and setters for private Boolean timerElementsVisible;
}
Layout
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<variable
name="helper"
type="com.myapps.recipeApp.RecipeBinderHelper"/>
<variable
name="recipe"
type="com.myapps.recipeApp.Recipe"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.myapp.recipeApp.RecipeActivity"
tools:showIn="@layout/activity_recipe">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/r_source"
android:textStyle="bold"
android:text="@{recipe.source}"
android:visibility="@{helper.presentationElementsVisible ? View.VISIBLE : View.GONE}" />
<!-- More TextViews here -->
<!-- Button is located in parret layout -->
</RelativeLayout>
</layout>
回答1:
I highly recommend to read George Mount's posts about Android data-binding, they are very useful.
To solve the problem I extended the helper class as an BaseObservable as described in the documentation.
Helper class
public class RecipeBinderHelper{
private Boolean presentationElementsVisible;
private Boolean timerElementsVisible;
public RecipeBinderHelper(){
this.presentationElementsVisible = true;
this.timerElementsVisible = false;
}
public void setPresentationViewVisible(boolean presentationElementsVisible) {
this.presentationElementsVisible = presentationElementsVisible;
//Notifying change in the setter.
notifyPropertyChanged(BR.presentationElementsVisible);
}
//assigning Bindable annotation to the getter
@Bindable
public Boolean getPresentationElementsVisible() {
return presentationElementsVisible;
}
//getters and setters for private Boolean timerElementsVisible;
}
The binding.notifyChange();
in the Activity is not necessary and can be removed.
The app now removes the TextView as desired, when the button is clicked.
One peculiar thing is that Android Studio (2.1.2, Ubuntu) gives me a Cannot resolve symbol 'BR'
warning, but the app compiles and runs as expected.
来源:https://stackoverflow.com/questions/38240968/dynamically-toggle-visibility-of-layout-elements-with-android-data-binding