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

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

Related

How to switch xml layout from spinner selection

I'm developing a simple BMI calculator for android. I have input fields for lbs, feet, and inches. I want to give users the ability to switch from imperial units to metric, so I added a spinner widget with imperial and metric as options. If the user changes the spinner to metric, I want to be able to change the XML layout so that the input fields are kg and cm. What is the best way to change the XML layout when the user switches between metric and imperial?
I tried creating a new activity that loads the metric layout XML when the user switches to it, but it seems like a poor design to create a new activity just to switch units. I also tried simply using setContentLayout to set the layout to metric.xml if spinner has metric selected and imperial.xml if imperial is selected. This sort of works but the ads and spinner widgets are no longer configured after switching between the layouts. I am still new to android development so I am wondering what the best approach to this would be? I am simply trying to make a slight layout change when the user switches between the different unit options. Any tips appreciated.
Normally, I would put everything inside activity layout xml file and toggle based on the condition like this
<TextView
android:id="#+id/feet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone"/>
<TextView
android:id="#+id/inch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone"/>
And in your spinner adapter selection listener, you can toggle the view you want to show:
feet.setVisibility(View.VISIBLE)
You can use FrameLayout. It allow you to make to different layouts on each other (different views can be located on another views). For example:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="#FFFFFF">
<RelativeLayout
android:id="#+id/digital_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginLeft="294dp"
android:layout_marginTop="64dp">
<Spinner
android:id="#+id/spinner101"
android:layout_width="135dp"
android:layout_height="wrap_content"
android:layout_below="#+id/checkBox100"
android:layout_toEndOf="#+id/textView100"
android:visibility="visible"/>
<TextView
android:id="#+id/textView102"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="#+id/spinner101"
android:text="Value pulse"
android:textSize="20dp"
android:visibility="visible"/>
<TextView
android:id="#+id/textView107"
android:layout_width="wrap_content"
android:layout_height="22dp"
android:layout_alignStart="#+id/textView106"
android:layout_below="#+id/textView103"
android:gravity="center"
android:text="11%"
android:visibility="visible"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/analog_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<EditText
android:id="#+id/editText3"
android:layout_width="136dp"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/spinner2"
android:layout_below="#+id/checkBox3"
android:ems="10"
android:hint="Constant"
android:inputType="textPersonName"
android:textSize="15dp"
android:visibility="invisible" />
<Button
android:id="#+id/button6"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/checkBox9"
android:layout_marginLeft="20dp"
android:onClick="onResetClick"
android:text="Reset" />
<View
android:id="#+id/delitel1"
android:layout_width="234dp"
android:layout_height="2dp"
android:layout_alignStart="#+id/textView7"
android:layout_below="#+id/button6"
android:layout_marginTop="10dp"
android:background="#004f9b" />
<TextView
android:id="#+id/textView14"
android:layout_width="135dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignTop="#+id/delitel1"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="Language:"
android:textSize="20dp"
android:visibility="invisible" />
</RelativeLayout>
So, you need to give different id to each RelativeLayouts. Here there are android:id="#+id/digital_layout" and android:id="#+id/analog_layout".
And in code need to write handler for your spinner:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
digital_layout.setVisibility(View.INVISIBLE);
analog_layout.setVisibility(View.VISIBLE);
break;
case 1:
digital_layout.setVisibility(View.VISIBLE);
analog_layout.setVisibility(View.INVISIBLE);
break;
etc.
}
}

Binding current layout elements in Android MVVM

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}" />

Bind item object in ItemTemplate in MVVMCross

I am developing an MVVMCross multi platform app and I'm having the following trouble with Converters:
I have a listView in Android with the following code:
<MyProjectName.Droid.MvxCustomViews.MvxListView.MvxDroidListView
android:id="#+id/historicList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="#00000000"
android:listSelector="#00000000"
android:fadingEdge="none"
local:MvxBind="ItemsSource Historics;"
local:MvxItemTemplate="#layout/historiclistitem" />
Where, Historics is a List.
Then, I have in the layout resource:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="horizontal">
<ImageView
android:id="#+id/historicIcon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="5dp"
android:layout_gravity="center"
local:MvxBind="AssetImagePath UpdateType, Converter=HistoricTypeToSource" />
<TextView
android:id="#+id/listHistoricType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="Anexo"
android:textColor="#0000FF"
android:textSize="16sp"
android:layout_gravity="center"
local:MvxBind="Text UpdateType, Converter=HistoricTypeToString" />
</LinearLayout>
<TextView
android:id="#+id/listHistoricTypeDetail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Anexo adicionado"
android:textColor="#000000"
local:MvxBind="Text ???, Converter=HistoricDetailsToString" />
The problem is, everything is working fine, but in the listHistoricTypeDetail's TextView's bind I need to pass the entire object, because, depending on each Historic.Action, I will add a text that uses Historic.AdditionalParameter, Historic.NewValue, Historic.OldValue!!!
I'm not figuring out how to pass 3 parameters depending on the value of the bind to the converter, or how to bind the entire object so my converter would be like:
MyConverter : MvxValueConverter
Is that clear? Can anyone help me?
Thanks in regards,
Given the complexity of your conversion, I think it's probably easiest to pass the entire object which you can do just by using a single period:
local:MvxBind="Text ., Converter=HistoricDetailsToString"
or - using Tibet-syntax - as:
local:MvxBind="Text HistoricDetailsToString(.)"
I think the wiki article may also help: https://github.com/MvvmCross/MvvmCross/wiki/Databinding
e.g.:
If $SourcePath$ is omitted or a single period "." is used, then the Source used is the whole of the ViewModel.
from https://github.com/MvvmCross/MvvmCross/wiki/Databinding#swiss

onChildView and hasSiblings with Espresso

I am trying to access a button from a specific view. The same view is displayed 6 times. This is the code I am using.
public void testTimeConfig(){
onData(withDesc("description")).onChildView(withId(R.id.positive)).perform(click());
}
private static Matcher<Object> withDesc(String desc) {
return allOf(is(instanceOf(String.class)), is(desc));
}
When I run, I get an error:
Error performing 'load adapter data' on view 'is assignable from class: class android.widget.AdapterView'.
Is this the best way to access a child view? If so, how?
EDIT
This is the code I am trying to use now.
onView(allOf((withContentDescription("description")), hasSibling(withContentDescription("SettingsLayout")), hasSibling(withId(R.id.positive)))).perform(click());
and
onView(allOf((withContentDescription("description")), hasSibling(withId(R.id.positive)))).perform(click());
With this Error:
No views in hierarchy found matching
The xml
<view
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/setAGoalTitle"
android:layout_alignParentLeft="true"
class="com.xxx"
android:layout_marginTop="30dp"
android:id="#+id/timeGoalWidget"
app:goalLabel="#string/time_min_upper"
app:icon="#drawable/ic_icn_summary_time"
app:step="300"
app:valueFormat="time"
android:gravity="center_horizontal"
android:layout_marginBottom="60dp"
android:contentDescription="setAGoalTimeConfigurator"/>
<view
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/timeGoalWidget"
class="com.xxx"
android:id="#+id/distanceGoalWidget"
app:goalLabel="#string/distance_upper"
app:icon="#drawable/ic_icn_summary_track"
app:step="0.25"
app:valueFormat="decimal_two"
android:gravity="center_horizontal"
android:contentDescription="setAGoalDistanceConfigurator"/>
<view
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/timeGoalWidget"
android:layout_alignLeft="#id/timeGoalWidget"
class="com.xxx"
android:id="#+id/paceGoalWidget"
app:goalLabel="#string/pace_upper"
app:icon="#drawable/ic_icn_summary_pace"
app:valueFormat="time"
app:step="10"
android:gravity="center_horizontal"
android:layout_marginBottom="60dp"
android:contentDescription="setAGoalPaceConfigurator"/>
<view
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#id/distanceGoalWidget"
android:layout_alignTop="#id/paceGoalWidget"
class="com.xxx"
android:id="#+id/speedGoalWidget"
app:goalLabel="#string/speed_upper"
app:icon="#drawable/ic_icn_summary_speed"
app:step="0.5"
app:valueFormat="decimal_two"
android:gravity="center_horizontal"
android:contentDescription="setAGoalSpeedConfigurator"/>
<view
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/paceGoalWidget"
android:layout_alignLeft="#id/paceGoalWidget"
class="com.xxx"
android:id="#+id/inclineGoalWidget"
app:goalLabel="#string/incline_percent_upper"
app:icon="#drawable/ic_icn_summary_elevation"
app:step="0.5"
app:valueFormat="decimal_two"
android:gravity="center_horizontal"
android:contentDescription="setAGoalInclineConfigurator"/>
<view
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#id/speedGoalWidget"
android:layout_alignTop="#id/inclineGoalWidget"
class="com.xxx"
android:id="#+id/caloriesGoalWidget"
app:goalLabel="#string/calories_upper"
app:icon="#drawable/ic_icn_summary_calories"
app:step="10"
app:valueFormat="decimal_zero"
android:gravity="center_horizontal"
android:contentDescription="setAGoalCaloriesConfigurator"/>
</RelativeLayout>
The view xml that is used 6 times.
<ImageButton
android:id="#+id/increaseGoalButton"
android:layout_height="#dimen/view_goal_setting_incrementor_button_height_width"
android:layout_width="#dimen/view_goal_setting_incrementor_button_height_width"
android:background="#drawable/button_goal_widget"
android:gravity="center"
android:src="#drawable/ic_plus"
android:textSize="#dimen/view_goal_setting_incrementor_button_text_size"
android:textColor="#color/goal_configuration_widget_button_text_color"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="1dp"
android:contentDescription="#string/increase"/>
<ImageButton
android:id="#+id/decreaseGoalButton"
android:layout_height="#dimen/view_goal_setting_incrementor_button_height_width"
android:layout_width="#dimen/view_goal_setting_incrementor_button_height_width"
android:background="#drawable/button_goal_widget"
android:gravity="center"
android:src="#drawable/ic_minus"
android:textSize="#dimen/view_goal_setting_incrementor_button_text_size"
android:layout_alignParentRight="true"
android:textColor="#color/goal_configuration_widget_button_text_color"
android:layout_below="#id/increaseGoalButton"
android:contentDescription="#string/decrease"/>
<LinearLayout
android:id="#+id/goalWidgetValueContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_toLeftOf="#id/increaseGoalButton"
android:layout_centerVertical="true"
android:gravity="center_vertical|right"
android:layout_marginRight="#dimen/view_goal_setting_value_margin_right" >
<TextView
android:id="#+id/goalValueTextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#color/goal_configuration_widget_value_text_color"
android:textSize="#dimen/view_goal_setting_value_text_size"
android:lineSpacingExtra="-10sp"
app:typeface="proxima_bold"
android:text="999:00"/>
<TextView
android:id="#+id/goalValueLabelTextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="right"
android:textSize="#dimen/view_goal_setting_value_label_text_size"
android:textColor="#color/goal_configuration_widget_value_text_color"
android:includeFontPadding="false"
android:lineSpacingExtra="10sp"
android:text="#string/incline_percent_upper"/>
</LinearLayout>
It is the ImageView with id increaseGoalButton that I am trying to click.
Based on your last comment you should use onView() instead of onData().
I think you'll be able to click the button using hasSibling() - example
onView(allOf(withId(R.id.positive), hasSibling(withDesc(someString))))
.perform(click());
or examples without your custom matcher (sibling view has text):
onView(allOf(withId(R.id.positive), hasSibling(withText(someString))))
.perform(click());
or (sibling view has content description):
onView(allOf(withId(R.id.positive), hasSibling(withContentDescription(someString))))
.perform(click());
EDITED:
OK, I'd try these two variants:
onView(allOf(withId(R.id.increaseGoalButton), isDescendantOfA(withId(R.id.timeGoalWidget))))
.perform(click());
or
onView(allOf(withId(R.id.increaseGoalButton), withParent(withId(R.id.timeGoalWidget))))
.perform(click());
None of your content descriptions match the string "description" that's why it doesn't find anything.
Assuming the button id is R.id.positive, and the id is unique in the current activity view, you can simply use:
onView(withId(R.id.positive)).perform(click());

View disappearing when inflated

I have a custom ListActivity in which i have a custom ListAdapter that inflates a layout for each item in the list. In eclipse, in the visual editor the layout looks like this
This is made by the following code:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/largeFrame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="1dp"
android:layout_marginRight="3dp"
android:layout_marginTop="5dp"
android:background="#color/mainBack"
android:orientation="vertical" >
<View
android:id="#+id/imageView1"
android:layout_width="5dp"
android:layout_height="fill_parent"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="false"
android:layout_marginLeft="2dp"
android:background="#android:color/darker_gray" />
<TextView
android:id="#+id/newtimeslot_class"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="4dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="#+id/imageView1"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#android:color/black" />
<View
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="2dp"
android:layout_alignRight="#+id/newtimeslot_class"
android:layout_below="#+id/newtimeslot_class"
android:layout_toRightOf="#+id/imageView1"
android:background="#android:color/darker_gray" />
<TextView
android:id="#+id/newtimeslot_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/newtimeslot_class"
android:layout_alignParentRight="true"
android:layout_marginRight="5dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#646464" />
<TextView
android:id="#+id/newtimeslot_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/imageView2"
android:layout_marginRight="5dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#646464" />
<TextView
android:id="#+id/newtimeslot_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/newtimeslot_location"
android:layout_marginBottom="10dp"
android:layout_marginRight="5dp"
android:layout_marginTop="2dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#646464" />
</RelativeLayout>
</FrameLayout>
Unfortunately though, when i run this on an android device, the line to the left completely disappears. It instead looks like
I have just done the usual in terms on inflating it, and i only ever access the TextView objects. So i'm just wondering what could possibly be going on and if someone could help me out of this mess?
Cheers
Edit: The inflation code
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final View view = mInflater.inflate(R.layout.timeslotlayout_new, parent, false);
return view;
}
I suspect the reference #android:color/darker_gray to be the problem.
It might be that on some devices, this value does not exist ?!? (it may be under another name for instance)
Try setting the background attribute to a COLOR value (instead of an android color reference) like this #00000 which represents black (or choose another custom color like this #A9A9A9 for DarkGray ) :
android:background="#A9A9A9"
/OR/
Create an XML file for most basic colors like done HERE, in this manner you are sure that the colors will not change among devices, and most of all, that they will exist on all devices for your application.
So if you do so (see the link), you can create a color like this (the name of the XML file does not matter at all) :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="Black">#000000</color>
<color name="DarkGray">#A9A9A9</color>
</resources>
And reference it in the following way :
android:background="#color/DarkGray"
Note :
No matter if this solved your issue or not, I strongly advise you to follow this manner to be on the safe side.
Maybe you're missing to set this:
android:layout_alignParentLeft="false"
to this:
android:layout_alignParentLeft="true"
And, by the way, android:orientation="vertical" doesn't apply to a relative layout. It applies only to LinearLayout.
And to the newtimeslot_time TextView change the
android:layout_toRightOf="#+id/imageView1"
to
android:layout_toRightOf="#id/imageView1"
Hope it helps!
Cheers!

Categories

Resources