Kristiyan Gergov
Kristiyan Gergov

Reputation: 161

How to set match_parent and wrap_content depending on condition in xml?

I need to set the layout_height of TextView depending on some condition. I have tried with importing LayoutParams but it did not work. Any ideas?

android:layout_height="condition ? wrap_content : match_parent"

I need to do it in xml not with code

Upvotes: 9

Views: 4496

Answers (5)

Khemraj Sharma
Khemraj Sharma

Reputation: 58934

You can do it with a custom Binding Adapter.

Create Binding Adapter as below

public class DataBindingAdapter {
    @BindingAdapter("android:layout_width")
    public static void setWidth(View view, boolean isMatchParent) {
        ViewGroup.LayoutParams params = view.getLayoutParams();
        params.width = isMatchParent ? MATCH_PARENT : WRAP_CONTENT;
        view.setLayoutParams(params);
    }
}

Then use this attribute in your View.

<TextView
    android:layout_width="@{item.isMatchParent, default = wrap_content}"
    ...
/>

Note:

default = wrap_content is important, because width and height should be specified when view is created, whether binding happens after bit time of view rendering.

Explaination

Why it is not possible without BindingAdapter.

Because Android does not provide View.setWidth(), size can be set by class LayoutParams, so you have to use LayoutParams. You can not use LayoutParams in xml because again here is no View.setWidth() method.

That's why below syntax gives error

Cannot find the setter for attribute 'android:layout_width' with parameter type int

<data>

    <import type="android.view.ViewGroup.LayoutParams"/>

<data>

android:layout_width="@{item.matchParent ? LayoutParams.MATCH_PARENT : LayoutParams.WRAP_CONTENT}"

Setting Visibility by xml works, because there is View.setVisibility() method available

Below syntax works

<data>
    <import type="android.view.View"/>
    <variable
        name="sale"
        type="java.lang.Boolean"/>
</data>

<FrameLayout android:visibility="@{sale ? View.GONE : View.VISIBLE}"/>

Upvotes: 17

Kevin Kurien
Kevin Kurien

Reputation: 842

<layout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools">  

    <data>  

        <variable  
            name="user"  
            type="<package name>.UserModel" />  

        <import type="android.view.View"/>  
    </data>  

    <RelativeLayout  
        android:layout_width="match_parent"  
        android:layout_height="match_parent">  

        <TextView  
             android:layout_width="@{user.email.trim().length()>10 ? wrap_content : match_parent}""  
             android:layout_height="wrap_content"  
             android:text="@{user.email}"  />  

    </RelativeLayout>  
</layout>    

Here try this I got this solution from here

Upvotes: -1

Kevin Kurien
Kevin Kurien

Reputation: 842

You should change it via LayoutParams:

    if(condition){
    LayoutParams params = (LayoutParams) textView.getLayoutParams();
    params.height = MATCH_PARENT;
    textView.setLayoutParams(params);}
else{
LayoutParams params = (LayoutParams) textView.getLayoutParams();
    params.height = WRAP_CONTENT;
    textView.setLayoutParams(params);}

Upvotes: 2

Clint Paul
Clint Paul

Reputation: 313

if(a == b ) {

view.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));

} 
else 
{
view.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
}

Upvotes: 0

KKumar Technologies
KKumar Technologies

Reputation: 267

I think you use ConstraintLayouts that provides all solutions

Upvotes: 0

Related Questions