Binding current layout elements in Android MVVM - android

Is it possible to use data binding to bind current layout elements? For example I would like to show some text when checkbox is clicked, so I would like to have something like this:
<CheckBox
android:id="#+id/myCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="check me"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some text"
android:visibility="#{myCheckBox.isChecked() ? View.VISIBLE : View.GONE}" />
I know how to do this from java code, I just wonder if there is a way to implement such behaviour by only modifying xml files?

Create one observable field in your ViewModel.
public class ViewModel {
public ObservableBoolean mCheckBox = new ObservableBoolean(false);
}
And modify your layout xml file:
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="#={viewModel.mCheckBox}"
android:text="check me" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some text"
android:visibility="#{viewModel.mCheckBox ? View.VISIBLE : View.GONE}" />

Related

Trying to set alpha with data binding from another view's visibility

I have an example running like this:
<Switch
android:id="#+id/sw_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="true"
android:enabled="#{!swAuto.checked}"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:text="Zustand"
android:textColor="#{swAuto.checked ? #color/outlet_preview_card_text_disabled : #color/outlet_preview_card_text}"
android:textSize="14sp"
tools:textColor="#color/outlet_preview_card_text"/>
But I need to set the alpha in another view depending on another's view visibility like:
<LinearLayout
android:id="#+id/ll_global_outlet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:background="#drawable/round_background_white"
android:orientation="vertical"
android:alpha="#{ivProgressBar.visibility == View.VISIBLE ? 0.90 : 1}"
android:padding="10dp">
But I am getting this error:
Error:(45, 30) Could not resolve the two-way binding attribute 'visibility' on type 'android.widget.ImageView'
Any idea what I am doing wrong?
this is the view I should depend on:
<ImageView
android:id="#+id/iv_progress_bar"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="visible"
android:background="#drawable/progress_bar_animation"/>
In case someone wonders I couldn't do it that way.
I decided that when my VM calls startProgressBar() this method will update my model having a field called isUpdating which will be Bindable and my VM extends Observable so with this:
android:alpha="#{shDevice.isUpdating ? 0.3f : 1.0f}"
would do what I want

Animate Textviews within elements of a listview separately

I’ve got a layout which consists of multiple views arranged in a relative layout. This layout will be inflated within an adapter of a listview.
Now I want to animate each element of my listview separately (not the element itself, but a textview within it), for instance on an onClick event. The animation should consist of a transition of a textview, and a fading of another one.
I don’t really have an idea here. I’ve got my ArrayList of Objects which holds the data for the elements of my listview. This ArrayList is given to the adapter which fills the textviews.
I guess I need a way now to approach the textviews. But how do I do that? I fiddled around with the getView Method of the Adapter class, without any success. To get the position of the clicked element within the adapter/arraylist is no problem at all.
Any ideads/different approaches?
I tried to attach an ObjectAnimator in my Adapter, which looks like this:
ObjectAnimator animation = ObjectAnimator.ofFloat(holder.txtPlayerPoints,"x", 200);
animation.setDuration(2000);
holder.txtPlayerPoints.setTag(R.id.tag_animation_in,animation);
And in my onClick I tried to start it like so:
((ObjectAnimator ) textView.getTag(R.id.tag_animation_in)).start();
The reference to the textView is correct, but it didn't move. The Debugger also says that the "mTag" porperty of my textView is "null". Any suggestions?
Edit: Here's the layout of each element:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp">
<TextView
android:layout_width="fill_parent"
android:layout_height="#dimen/bar_upper_height"
android:paddingLeft="#dimen/bar_name_padding"
android:text="Hendrik"
android:textSize="#dimen/font_player_name"
android:id="#+id/txtNamePlayer"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="#color/txt_default"
android:textStyle="bold"
android:textColor="#android:color/white"
android:gravity="center_vertical" />
<TextView
android:layout_width="#dimen/bar_rank_width"
android:layout_height="#dimen/bar_rank_height"
android:layout_marginLeft="#dimen/bar_upper_margin"
android:layout_marginBottom="#dimen/bar_upper_margin"
android:textSize="#dimen/font_bar_info"
android:text="1"
android:id="#+id/txtRankPlayer"
android:layout_alignLeft="#id/txtNamePlayer"
android:layout_alignBottom="#id/txtNamePlayer"
android:background="#android:color/white"
android:textStyle="bold"
android:textColor="#color/txt_default"
android:gravity="center_vertical|center_horizontal" />
<ImageView
android:layout_width="#dimen/bar_arrow_width"
android:layout_height="#dimen/bar_rank_height"
android:id="#+id/imgActivePlayer"
android:layout_toRightOf="#id/txtRankPlayer"
android:layout_marginLeft="#dimen/bar_upper_margin"
android:layout_alignBottom="#id/txtNamePlayer"
android:layout_marginBottom="#dimen/bar_upper_margin"
android:background="#drawable/active_player" />
<TextView
android:layout_width="#dimen/bar_rank_height"
android:layout_height="#dimen/bar_rank_height"
android:layout_marginRight="#dimen/bar_upper_margin"
android:layout_marginBottom="#dimen/bar_upper_margin"
android:text="12"
android:id="#+id/txtPointsPlayer"
android:layout_alignRight="#id/txtNamePlayer"
android:layout_alignBottom="#id/txtNamePlayer"
android:background="#android:color/white"
android:textStyle="bold"
android:textColor="#color/txt_default"
android:textSize="#dimen/font_bar_info"
android:gravity="center_vertical|center_horizontal" />
<TextView
android:layout_width="#dimen/bar_rank_height"
android:layout_height="#dimen/bar_rank_height"
android:layout_marginRight="#dimen/bar_upper_margin"
android:layout_marginBottom="#dimen/bar_upper_margin"
android:layout_toLeftOf="#id/txtPointsPlayer"
android:layout_alignBottom="#id/txtNamePlayer"
android:text="0"
android:id="#+id/txtCurrScorePlayer"
android:background="#color/txt_disabled"
android:textColor="#android:color/white"
android:textSize="#dimen/font_bar_info"
android:gravity="center_vertical|center_horizontal" />
<LinearLayout
android:orientation="horizontal"
android:id="#+id/aheadBehindPlayer"
android:layout_width="fill_parent"
android:layout_height="#dimen/bar_lower_height"
android:layout_below="#+id/txtNamePlayer"
android:layout_centerHorizontal="true"
android:background="#color/txt_disabled"
android:gravity="center_vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ahead"
android:textSize="#dimen/font_bar_info"
android:textColor="#android:color/white"
android:id="#+id/textView2"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="15"
android:textSize="#dimen/font_bar_info"
android:textColor="#android:color/white"
android:id="#+id/txtPlayerAhead"
android:layout_weight="5"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="15"
android:textColor="#android:color/white"
android:textSize="#dimen/font_bar_info"
android:id="#+id/txtPlayerBehind"
android:textStyle="bold"
android:gravity="right"
android:layout_weight="5" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/behind"
android:textColor="#android:color/white"
android:textSize="#dimen/font_bar_info"
android:id="#+id/textView5"
android:gravity="right"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>
I want to animate txtPointsPLayer and txtCurrScorePlayer.
Just attach an ObjectAnimator to each view (using setTag()) and then retrieve it later during onClick. To create an animator you can do something like:
// Animate X from 0 to 200
ObjectAnimator animation2 = ObjectAnimator.ofFloat(myview,"x", 200);
animation2.setDuration(2000);
myview.setTag(animation2)
And then during onClick you get a reference to it and start it
((ObjectAnimator ) myview.getTag()).start()
Hope it helps.
I guess this is pretty much opinion based. Even though, I'm not an android expert, I believe that whatever approach you choose you will still need to get a reference of each TextView inside the ListView, specify the OnClickListener and start the animation. So, I'd approach this in such a way that I don't keep my activity/fragment polluted with child-views-specific logic by creating a custom view that extends from the TextView class where I would define everything related to this TextViews. So, basically, the activity/fragment only needs to know how the ListView...it doesn't care about the items inside it or what the items are doing...this is from an architecture-specific perspective

Change layout_bellow attribute field to another field programmatically

Given the following code:
<RelativeLayout
android:id="#+id/rel"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/textPersonalInfoEmpty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="20dp"
android:hint="Edit to set your personal info"
android:textSize="16sp"
android:visibility="gone" />
<EditText
android:id="#+id/editName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="15dp"
android:hint="Name"
android:visibility="gone"
android:textSize="16sp" />
<Button
android:id="#+id/insertGameId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/editName"
android:layout_marginTop="20dp"
android:text="Insert" />
</RelativeLayout>
The TextView and the EditText are visible depending the user interaction and both will never be visible at the same time. One per time only!
The problem is the third component(Button) need to change the attribute android:layout_below depending on which component is visible.
I need to this programmatically.
Any help?
Use Relativelayout for your textview and edittext. And relativelayout's height:wrap-content
Then give an id to your relativelayout
and then add this line your xml file for your button
<Button
android:layout_below="#id/RealtiveLayoutid" />
Thats all
First, use a ToggleButton instead of Button. It can have all the attributes that you assigned to it.
Next add this to the ToggleButton:
<ToggleButton
....
android:textOn="#string/ifTextView"
android:textOff="#string/ifTextBox"
android:onClick="onToggleClicked"
/>
Then this for the activity
public void onToggleClicked(View v) {
boolean on = ((ToggleButton) v).isChecked();
if(on) {
theTextView.setVisibility(View.VISIBLE);
theTextBox.setVisibility(View.INVISIBLE);
} else {
theTextBox.setVisibility(View.VISIBLE);
theTextView.setVisibility(View.INVISIBLE);
}
}
Remember to import the required classes.

How to handle onClick on a RelativeLayout that is part of HorizontalScrollView

I have RelativeLayouts in HorizontalScrollView. When a user clicks on one of the layouts (or any of its childs) I need to change the background color of the certain RelativeLayout and get its ID for further process. I saw this might be done with DuplicateParentState or with onTouchEvent. Which way is recommended?
My XML file after editing the XML file as proposed:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<youme.appyoume.com.ExDialog>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:clickable="true"
android:duplicateParentState="true"
android:onClick="onClick"
android:src="#drawable/ic_launcher" />
<EditText
android:id="#+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:duplicateParentState="true"
android:ems="10"
android:focusable="false"
android:focusableInTouchMode="false"
android:inputType="textMultiLine"
android:text="text" >
<requestFocus />
</EditText>
</youme.appyoume.com.ExDialog>
</RelativeLayout>
Thanks,
Simon
If you want to use the custom class youve created in your xml you just use the entire root name of the object. So for instance if you have a class in
com.your.package.customButton
you would write in your xml
<RelativeLayout
...layoutstuff config>
<com.your.package.customButton
...customButton layout config/>
</RelativeLayout>
if your subclassing a relativelayout you would use it like this
<youme.appyoume.com.ExDialog
...layout setup stuff>
<Button
...button setup stuff
/>
</youme.appyoume.com.ExDialog>
You could always assign a tag to it for future reference using setTag and getTag and just use setOn Click Listener and put what ever you need to happen in there

How to use referencing? is it through using #id or need to declare global variable?

this is part of my main.xml
<TextView
android:id="#id/infoname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="35dp"
android:text="Hi Name"
android:textSize="25sp" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome to Program"
android:textAppearance="?android:attr/textAppearanceLarge" />
this is part of my editinfo.xml
<EditText
android:id="#+id/infoname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="3 to 10 characters"
android:layout_weight="1"/>
from editing the id/infoname from edit text(for example input is MyName)
how could i do something like Hi MyName from the content main.xml
thanks :)
You're trying to change the text property of your EditText programmatically?
In your Java file's onCreate:
EditText yourEditText = (EditText)findViewById(R.id.yourEditText);
yourEditText.setText("MyName");
You're getting a reference to your EditText object and setting the text property.

Categories

Resources