Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Data Binding layout_width and layout_height

I need to be able to dynamically set an EditText's height property. I am using data binding for other properties throughout my app, so I would love to be able to use data binding to control the height of my elements. Here is a stripped down version of my xml:

<?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="loginVM" type="com.testing.stuff.ViewModels.LoginViewModel" /> </data>  <EditText android:inputType="number"             android:id="@+id/txtVerificationCode"             android:layout_height="@{loginVM.compact ? @dimen/verificationHeightCompact : @dimen/verificationHeightFull}"             android:layout_width="match_parent"             android:paddingRight="16dp"             android:paddingLeft="16dp"             android:focusable="true"             android:focusableInTouchMode="true"             android:layout_marginLeft="10dp"             android:alpha="@{loginVM.verificationOpacity}"             android:layout_marginStart="10dp"             android:textAlignment="center"             android:visibility="visible"             android:hint="Enter verificationCode"             android:text="@{loginVM.verificationCode}" /> </layout>  

And here is a stripped down version of my View Model:

public class LoginViewModel extends BaseObservable { public final ObservableField<String> verificationCode;  public final ObservableField<Boolean> compact;  @Bindable public String getVerificationCode() {     if (this.verificationCode == null) {         return "";     } else {         return this.verificationCode.get();     } }  public void setVerificationCode(String verificationCode) {     this.verificationCode.set(verificationCode);     invalidateProperties(); }  @Bindable public Boolean getCompact(){return this.compact.get();}  public void setCompact(Boolean value) {     this.compact.set(value);     this.invalidateProperties(); }  @BindingAdapter("android:layout_height") public static void setLayoutHeight(EditText view, float height) {     ViewGroup.LayoutParams layoutParams = view.getLayoutParams();     layoutParams.height = (int)height;     view.setLayoutParams(layoutParams); }  public LoginViewModel(Context ctx) {     verificationCode = new ObservableField();     compact = new ObservableField(); } 

The dimensions are in the dimens.xml file. And I am modifying the properties in the view model. But, when I launch the app, I'm getting the following error immediately after launch (the bindingadapter is not firing on debug). I have several other elements on the screen but this particular one is the one I need to change the height when a particular action occurs:

FATAL EXCEPTION: main  Process: com.testing.stuff, PID: 32752  java.lang.RuntimeException: Unable to start activity   ComponentInfo{com.testing.stuff/com.testing.stuff.Login}:  java.lang.RuntimeException: Binary XML file line #69: You must supply  a layout_height attribute.  Caused by: java.lang.RuntimeException: Binary XML file line #69: You  must supply a layout_height attribute. 

There are a few posts on SO regarding this issue but no definitive answers or the approach did not work. Surely this is an implementation that is common. Thanks in advance for the help.

like image 319
John Murphy Avatar asked Feb 09 '16 14:02

John Murphy


People also ask

Can I use ViewBinding and data binding together?

View binding doesn't support layout variables or layout expressions, so it can't be used to declare dynamic UI content straight from XML layout files. View binding doesn't support two-way data binding.

Which is better ViewBinding and databinding?

Note: In many cases, view binding can provide the same benefits as data binding with simpler implementation and better performance. If you are using data binding primarily to replace findViewById() calls, consider using view binding instead.

What is one way binding and two-way binding in Android?

Updating the views from the data source is a simple one-way binding. In that case, you'll only access data from the data source and update the layout. Two-way data binding is nothing but updating the data source if there are any changes in the layout and vice versa.

What is two-way data binding Android?

The @={} notation, which importantly includes the "=" sign, receives data changes to the property and listen to user updates at the same time. // Avoids infinite loops.


1 Answers

In Java

@BindingAdapter("layout_height") public static void setLayoutHeight(View view, float height) {     LayoutParams layoutParams = view.getLayoutParams();     layoutParams.height = height;     view.setLayoutParams(layoutParams); } 

And in your XML

app:layout_height="@{ viewModel.isBig ? @dimen/dp_20 : @dimen/dp_5 }" 

import the app like this

xmlns:app="http://schemas.android.com/apk/res-auto" 
like image 64
Linh Avatar answered Sep 22 '22 01:09

Linh