Last active
September 10, 2020 12:50
-
-
Save petrabarus/48131361585b9fc78ef4a9cb56964899 to your computer and use it in GitHub Desktop.
Android Dependent Two-Way Data Binding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> | |
<variable name="property" type="net.petrabarus.testandroid.dynamicdatabinding.PropertyViewModel"/> | |
</data> | |
<RelativeLayout | |
android:id="@+id/activity_main" | |
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" | |
tools:context="net.petrabarus.testandroid.dynamicdatabinding.MainActivity"> | |
<LinearLayout | |
android:orientation="vertical" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_centerHorizontal="true" | |
android:layout_marginTop="17dp" | |
android:id="@+id/test_layout"> | |
<EditText | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:inputType="textPersonName" | |
android:text="@={property.title}" | |
android:ems="10" | |
android:id="@+id/editText" | |
/> | |
<LinearLayout | |
android:orientation="vertical" | |
android:layout_width="match_parent" | |
android:layout_height="377dp" | |
android:id="@+id/dynamic_layout"> | |
<net.petrabarus.testandroid.dynamicdatabinding.ProvinceSpinner | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
app:province="@={property.province}" | |
> | |
</net.petrabarus.testandroid.dynamicdatabinding.ProvinceSpinner> | |
<net.petrabarus.testandroid.dynamicdatabinding.CitySpinner | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
app:province="@{property.province}" | |
app:city="@={property.city}"> | |
</net.petrabarus.testandroid.dynamicdatabinding.CitySpinner> | |
</LinearLayout> | |
</LinearLayout> | |
<Button | |
android:text="Button" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_alignParentBottom="true" | |
android:layout_alignParentRight="true" | |
android:layout_alignParentEnd="true" | |
android:id="@+id/button" | |
android:onClick="handleOnClick" | |
/> | |
</RelativeLayout> | |
</layout> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.petrabarus.testandroid.dynamicdatabinding; | |
import android.content.Context; | |
import android.databinding.BindingAdapter; | |
import android.databinding.InverseBindingAdapter; | |
import android.databinding.InverseBindingListener; | |
import android.databinding.InverseBindingMethod; | |
import android.databinding.InverseBindingMethods; | |
import android.databinding.Observable; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.widget.AdapterView; | |
import android.widget.ArrayAdapter; | |
import android.widget.Spinner; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
@InverseBindingMethods({ | |
@InverseBindingMethod(type = String.class, attribute = "city"), | |
}) | |
public class CitySpinner extends Spinner { | |
private String province; | |
private String city; //support data binding | |
private ArrayList<String> entries = new ArrayList<String>(); | |
public CitySpinner(Context context) { | |
super(context); | |
init(); | |
} | |
public CitySpinner(Context context, int mode) { | |
super(context, mode); | |
init(); | |
} | |
public CitySpinner(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
init(); | |
} | |
private void init() { | |
loadEntries(); | |
} | |
public String getProvince() { | |
return province; | |
} | |
public void setProvince(String province) { | |
this.province = province; | |
loadEntries(); | |
} | |
@InverseBindingAdapter(attribute = "city") | |
public static String getCity(CitySpinner view) { | |
view.province = view.getSelectedItem().toString(); | |
return view.province; | |
} | |
@BindingAdapter("city") | |
public static void setCity(CitySpinner view, String city) { | |
view.city = city; | |
if (view.entries != null) { | |
int selectedPosition = view.entries.indexOf(city); | |
view.setSelection(selectedPosition); | |
} | |
} | |
@BindingAdapter("cityAttrChanged") | |
public static void setProvinceListener(CitySpinner view, final InverseBindingListener cityChange) { | |
if (cityChange == null) { | |
view.setOnItemSelectedListener(null); | |
} else { | |
OnItemSelectedListener listener = new OnItemSelectedListener() { | |
@Override | |
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | |
cityChange.onChange(); | |
} | |
@Override | |
public void onNothingSelected(AdapterView<?> parent) { | |
cityChange.onChange(); | |
} | |
}; | |
view.setOnItemSelectedListener(listener); | |
} | |
} | |
private void loadEntries() { | |
if (province == null) { | |
return; | |
} | |
String[] entries; | |
switch (province) { | |
case "Jawa Barat": | |
entries = new String[] { | |
"Bandung", | |
"Bogor", | |
"Bekasi" | |
}; | |
break; | |
case "DKI Jakarta": | |
entries = new String[] { | |
"Jakarta Timur", | |
"Jakarta Barat", | |
}; | |
break; | |
case "Jawa Timur": | |
entries = new String[] { | |
"Malang", | |
"Surabaya", | |
}; | |
break; | |
default: | |
return; | |
} | |
this.entries = new ArrayList<String>(Arrays.asList(entries)); | |
ArrayAdapter<String> adapter = new ArrayAdapter<String>( | |
getContext(), | |
android.R.layout.simple_list_item_1, | |
entries | |
); | |
setAdapter(adapter); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.petrabarus.testandroid.dynamicdatabinding; | |
import android.databinding.DataBindingUtil; | |
import android.support.v7.app.AppCompatActivity; | |
import android.os.Bundle; | |
import android.view.View; | |
import net.petrabarus.testandroid.dynamicdatabinding.databinding.ActivityMainBinding; | |
public class MainActivity extends AppCompatActivity { | |
private PropertyViewModel propertyViewModel; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); | |
propertyViewModel = new PropertyViewModel(); | |
binding.setProperty(propertyViewModel); | |
} | |
public void handleOnClick(View view) { | |
propertyViewModel.province.set("DKI Jakarta"); | |
propertyViewModel.city.set("Jakarta Barat"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.petrabarus.testandroid.dynamicdatabinding; | |
import android.databinding.ObservableField; | |
public class PropertyViewModel { | |
public ObservableField<String> title = new ObservableField<>(); | |
public ObservableField<String> province = new ObservableField<>(); | |
public ObservableField<String> city = new ObservableField<>(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.petrabarus.testandroid.dynamicdatabinding; | |
import android.content.Context; | |
import android.databinding.BindingAdapter; | |
import android.databinding.InverseBindingAdapter; | |
import android.databinding.InverseBindingListener; | |
import android.databinding.InverseBindingMethod; | |
import android.databinding.InverseBindingMethods; | |
import android.support.v7.widget.AppCompatSpinner; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.widget.AdapterView; | |
import android.widget.ArrayAdapter; | |
import android.widget.Spinner; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
@InverseBindingMethods({ | |
@InverseBindingMethod(type = String.class, attribute = "province"), | |
}) | |
public class ProvinceSpinner extends Spinner { | |
private String province; | |
private ArrayList<String> entries; | |
public ProvinceSpinner(Context context) { | |
super(context); | |
init(); | |
} | |
public ProvinceSpinner(Context context, int mode) { | |
super(context, mode); | |
init(); | |
} | |
public ProvinceSpinner(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
init(); | |
} | |
private void init() { | |
loadEntries(); | |
} | |
@InverseBindingAdapter(attribute = "province") | |
public static String getProvince(ProvinceSpinner view) { | |
view.province = view.getSelectedItem().toString(); | |
return view.province; | |
} | |
@BindingAdapter("province") | |
public static void setProvince(ProvinceSpinner view, String province) { | |
view.province = province; | |
int selectedPosition = view.entries.indexOf(province); | |
view.setSelection(selectedPosition); | |
} | |
@BindingAdapter("provinceAttrChanged") | |
public static void setProvinceListener(ProvinceSpinner view, final InverseBindingListener provinceChange) { | |
if (provinceChange == null) { | |
view.setOnItemSelectedListener(null); | |
} else { | |
OnItemSelectedListener listener = new OnItemSelectedListener() { | |
@Override | |
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | |
provinceChange.onChange(); | |
} | |
@Override | |
public void onNothingSelected(AdapterView<?> parent) { | |
provinceChange.onChange(); | |
} | |
}; | |
view.setOnItemSelectedListener(listener); | |
} | |
} | |
private void loadEntries() { | |
String[] entries = new String[] { | |
"Jawa Barat", | |
"DKI Jakarta", | |
"Jawa Timur" | |
}; | |
this.entries = new ArrayList<String>(Arrays.asList(entries)); | |
ArrayAdapter<String> adapter = new ArrayAdapter<String>( | |
getContext(), | |
android.R.layout.simple_list_item_1, | |
entries | |
); | |
setAdapter(adapter); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment