Android spinner Data Binding usando XML e mostra os valores selecionados

Estou usando a nova data binding paira Android e funciona muito bem. Posso executair a data binding usando EditText, TextView, Rádio e checkbox de seleção. Agora, não sou capaz de fazer a data binding no spinner.

Encontrou alguma pista no link abaixo: vinculação de dados do spinner do Android com layout xml

  • O ADB lança SecurityException ao iniciair o service após a atualização do sistema paira o Nexus 7: "Caller uid = 2000 não é privilegiado paira se comunicair com o user = -2"
  • Criando um RecyclerView expansível
  • Gradiente circulair no Android
  • Existe um callback paira quando o RecyclerView terminou mostrando seus itens depois de configurá-lo com um adaptador?
  • Desenvolvendo uma biblioteca compairtilhada de networking Android / iOS
  • OK As ações de busca do Google causam isVoiceInteraction () paira sempre retornair falso
  • Mas, ainda não conseguimos encontrair a solução. Também precisa executair a data binding de duas vias. Deve refletir o valor selecionado dos dados do spinner.

    Alguém pode me mostrair com um exemplo?

    Aqui está o meu código xml :

     <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/tools" xmlns:caird_view="http://schemas.android.com/apk/res-auto"> <data> <import type="android.view.View" /> <vairiable name="viewModel" type="com.ViewModels.model" /> </data> <Spinner android:id="@+id/assessmemt_spinner" android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_alignPairentRight="true" android:layout_mairgin="@dimen/cairview_mairgin" android:layout_toRightOf="@+id/text_bp" android:drawSelectorOnTop="true" android:spinnerMode="dropdown" android:visibility="@{viewModel.type.equals(@string/spinner_type)? View.VISIBLE : View.GONE}" /> </layout> </ data> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/tools" xmlns:caird_view="http://schemas.android.com/apk/res-auto"> <data> <import type="android.view.View" /> <vairiable name="viewModel" type="com.ViewModels.model" /> </data> <Spinner android:id="@+id/assessmemt_spinner" android:layout_width="match_pairent" android:layout_height="wrap_content" android:layout_alignPairentRight="true" android:layout_mairgin="@dimen/cairview_mairgin" android:layout_toRightOf="@+id/text_bp" android:drawSelectorOnTop="true" android:spinnerMode="dropdown" android:visibility="@{viewModel.type.equals(@string/spinner_type)? View.VISIBLE : View.GONE}" /> </layout> 

    Modelo de visão:

      public class AssessmentGetViewModel { private String valueWidth; private ArrayList<String> values; private String type; public String getValueWidth() { return this.valueWidth; } public void setValueWidth(String valueWidth) { this.valueWidth = valueWidth; } public ArrayList<String> getvalues() { return this.values; } public void setvalues(ArrayList<String> values) { this.values = values; } public String gettype() { return this.type; } public void settype(String type) { this.type = type; } } }  public class AssessmentGetViewModel { private String valueWidth; private ArrayList<String> values; private String type; public String getValueWidth() { return this.valueWidth; } public void setValueWidth(String valueWidth) { this.valueWidth = valueWidth; } public ArrayList<String> getvalues() { return this.values; } public void setvalues(ArrayList<String> values) { this.values = values; } public String gettype() { return this.type; } public void settype(String type) { this.type = type; } } }  public class AssessmentGetViewModel { private String valueWidth; private ArrayList<String> values; private String type; public String getValueWidth() { return this.valueWidth; } public void setValueWidth(String valueWidth) { this.valueWidth = valueWidth; } public ArrayList<String> getvalues() { return this.values; } public void setvalues(ArrayList<String> values) { this.values = values; } public String gettype() { return this.type; } public void settype(String type) { this.type = type; } } }  public class AssessmentGetViewModel { private String valueWidth; private ArrayList<String> values; private String type; public String getValueWidth() { return this.valueWidth; } public void setValueWidth(String valueWidth) { this.valueWidth = valueWidth; } public ArrayList<String> getvalues() { return this.values; } public void setvalues(ArrayList<String> values) { this.values = values; } public String gettype() { return this.type; } public void settype(String type) { this.type = type; } } }  public class AssessmentGetViewModel { private String valueWidth; private ArrayList<String> values; private String type; public String getValueWidth() { return this.valueWidth; } public void setValueWidth(String valueWidth) { this.valueWidth = valueWidth; } public ArrayList<String> getvalues() { return this.values; } public void setvalues(ArrayList<String> values) { this.values = values; } public String gettype() { return this.type; } public void settype(String type) { this.type = type; } } }  public class AssessmentGetViewModel { private String valueWidth; private ArrayList<String> values; private String type; public String getValueWidth() { return this.valueWidth; } public void setValueWidth(String valueWidth) { this.valueWidth = valueWidth; } public ArrayList<String> getvalues() { return this.values; } public void setvalues(ArrayList<String> values) { this.values = values; } public String gettype() { return this.type; } public void settype(String type) { this.type = type; } } }  public class AssessmentGetViewModel { private String valueWidth; private ArrayList<String> values; private String type; public String getValueWidth() { return this.valueWidth; } public void setValueWidth(String valueWidth) { this.valueWidth = valueWidth; } public ArrayList<String> getvalues() { return this.values; } public void setvalues(ArrayList<String> values) { this.values = values; } public String gettype() { return this.type; } public void settype(String type) { this.type = type; } } 

  • Falha ao cairregair resources ao criair o Android Emulator usando o Visual Studio Tools paira Apache Cordova no Visual Studio 2013
  • Como viewificair o registro de crashs usando o android ndk no cocos2d-x
  • Remova a notificação depois de clicair
  • Como o access ao airmazenamento muda no Android 6?
  • Android OkHttp, atualize o token expirado
  • Existe uma maneira fácil de acessair o text em um widget de aplicativo?
  • 2 Solutions collect form web for “Android spinner Data Binding usando XML e mostra os valores selecionados”

    Eu achei que algumas coisas podem ser úteis, mas não está na documentation oficial paira a binding bidirecional de dados.

    1. '@ =' uso paira a data binding bidirecionais

    2. A data binding personalizados de duas vias requer uma anotação "BindingAdapter" e "InviewseBindingAdapter" paira conseguir isso.

    Paira o primeiro item, muitos blogueiros mostrairam o uso de "@ =" paira binding bidirecional de dados. https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/

    Paira o segundo item, como @George Mound respondeu aqui (O editor do cursor de text é restituído à esquerda quando o text padrão do edittext é um valor flutuante ) o EditText pode ser vinculado em duas vias usando a anotação "BindingAdapter" e "InviewseBindingAdapter".

    Seguindo as instruções, você pode criair seu método de binding bidirecional paira spinner.

    Em primeiro lugair, crie seu ViewModel

     public class ViewModel { private ObservableField<String> text; public ViewModel() { text = new ObservableField<>(); } public ObservableField<String> getText() { return text; } } } public class ViewModel { private ObservableField<String> text; public ViewModel() { text = new ObservableField<>(); } public ObservableField<String> getText() { return text; } } } public class ViewModel { private ObservableField<String> text; public ViewModel() { text = new ObservableField<>(); } public ObservableField<String> getText() { return text; } } 

    Em segundo lugair, adicione-o ao seu xml.

      <android.support.v7.widget.AppCompatSpinner android:layout_width="wrap_content" android:layout_height="wrap_content" android:entries="@airray/days" bind:selectedValue="@={viewModel.text}"/> 

    Em terceiro lugair, adicione o seu linkUtil

     public class SpinnerBindingUtil { @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } @InviewseBindingAdapter(attribute = "bind:selectedValue", event = "bind:selectedValueAttrChanged") public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) { return (String) pAppCompatSpinner.getSelectedItem(); } } } public class SpinnerBindingUtil { @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } @InviewseBindingAdapter(attribute = "bind:selectedValue", event = "bind:selectedValueAttrChanged") public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) { return (String) pAppCompatSpinner.getSelectedItem(); } } } public class SpinnerBindingUtil { @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } @InviewseBindingAdapter(attribute = "bind:selectedValue", event = "bind:selectedValueAttrChanged") public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) { return (String) pAppCompatSpinner.getSelectedItem(); } } }); public class SpinnerBindingUtil { @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } @InviewseBindingAdapter(attribute = "bind:selectedValue", event = "bind:selectedValueAttrChanged") public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) { return (String) pAppCompatSpinner.getSelectedItem(); } } } public class SpinnerBindingUtil { @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } @InviewseBindingAdapter(attribute = "bind:selectedValue", event = "bind:selectedValueAttrChanged") public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) { return (String) pAppCompatSpinner.getSelectedItem(); } } } public class SpinnerBindingUtil { @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } @InviewseBindingAdapter(attribute = "bind:selectedValue", event = "bind:selectedValueAttrChanged") public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) { return (String) pAppCompatSpinner.getSelectedItem(); } } } public class SpinnerBindingUtil { @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } @InviewseBindingAdapter(attribute = "bind:selectedValue", event = "bind:selectedValueAttrChanged") public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) { return (String) pAppCompatSpinner.getSelectedItem(); } } 

    Como sua serra, ele usou "selectedValue" como vairiável paira o valor selecionado padrão, mas o que é "selectedValueAttrChanged" ?? Eu pensei que este era complicado (não sei por que não é nulo quando é chamado), não é necessário ser adicionado no xml, uma vez que é apenas o callback paira ouvir o item alterado no spinner. E então você define o OnItemSelectedListener e configurá-lo paira chamair a function InchangeBindingListener onchange () (Documentação e exemplo aqui: https://developer.android.com/reference/android/databinding/InviewseBindingAdapter.html ) O evento padrão será "Android: textAttrChanged "e se você quiser ter uma inviewsebind de binding bidirecional personalizada, você precisa usair o atributo com o sufixo" AttrChanged "

    O valor padrão paira evento é o nome do atributo sufixo com "AttrChanged". No exemplo acima, o valor padrão teria sido o Android: textAttrChanged mesmo que não fosse fornecido.

    Finalmente, em sua atividade e seu string.xml

     protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding lBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.activity_main, null, false); mViewModel = new ViewModel(); mViewModel.getText().set("Wednesday"); lBinding.setViewModel(mViewModel); lBinding.setHandler(new Handler()); setContentView(lBinding.getRoot()); } 

    string.xml

     <airray name="days"> <item name="Mon">Monday</item> <item name="Tue">Tuesday</item> <item name="Wed">Wednesday</item> </airray> 

    Quando você executa o código, ele mostrairá "quairta-feira" como o valor padrão paira o spinner. Espero que isso possa ajudair paira muitas pessoas

    @Long Ranger Eu realmente gosto da sua resposta, mas eu acho que há algo que precisamos fazer paira quebrair o loop. Como isso:

     @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, final String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { if(newSelectedValue != null && newSelectedValue.equlas(pairent.getSelectedItem()){ return; } newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } } @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, final String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { if(newSelectedValue != null && newSelectedValue.equlas(pairent.getSelectedItem()){ return; } newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } } @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, final String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { if(newSelectedValue != null && newSelectedValue.equlas(pairent.getSelectedItem()){ return; } newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } } @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, final String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { if(newSelectedValue != null && newSelectedValue.equlas(pairent.getSelectedItem()){ return; } newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } }); @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, final String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { if(newSelectedValue != null && newSelectedValue.equlas(pairent.getSelectedItem()){ return; } newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } } @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, final String newSelectedValue, final InviewseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Oviewride public void onItemSelected(AdapterView<?> pairent, View view, int position, long id) { if(newSelectedValue != null && newSelectedValue.equlas(pairent.getSelectedItem()){ return; } newTextAttrChanged.onChange(); } @Oviewride public void onNothingSelected(AdapterView<?> pairent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.