2016-06-17 12 views
12

新しいAndroidデータバインディングを使用しています。 EditText、TextView、ラジオ、チェックボックスを使用してデータバインディングを実行することができます。今、私はスピナーでデータ結合を行うことができません。 Android spinner data binding with xml layoutAndroidスピナーXMLを使用したデータバインディングと選択した値の表示

しかし、まだ解決策を見つけることができません:

はリンクの下にあるいくつかの手がかりを見つけました。また、双方向データバインディングを実行する必要があります。スピナーデータの選択値を反映する必要があります。

例を教えてもらえますか?

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

    <data> 
     <import type="android.view.View" /> 
     <variable 
      name="viewModel" 
      type="com.ViewModels.model" /> 
    </data> 

    <Spinner 
        android:id="@+id/assessmemt_spinner" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_alignParentRight="true" 
        android:layout_margin="@dimen/carview_margin" 
        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> 

ビューモデル::ここで

は私xmlコードです

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; } 
    } 

答えて

14

私は代が役に立つかもしれません見つかりましたが、それが結合双方向のデータのための公式ドキュメントではありません。

1.双方向のデータのための「@ =」使用量がこれを達成するために、「BindingAdapter」と「InverseBindingAdapter」注釈ニーズを結合

2.双方向のカスタムデータを結合。

最初の項目では、多くのブロガーが双方向データバインディングで「@ =」を使用していました。 https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/

@George Moundがここで答えたように(Edit text cursor resets to left when default text of edittext is a float value)、EditTextは "BindingAdapter"と "InverseBindingAdapter"アノテーションを使って双方向でバインドできます。

この手順に従えば、スピナーの双方向バインド方法を構築できます。

まず、あなたのViewModelを作成するか、第二に

public class ViewModel { 
    private String text; 
    public String getText() { 
     return text; 
    } 

    public void setText(String text) 
    { 
     this.text = text; 
    } 
} 

POJO

のViewModel

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

POJO

を使用し、あなたのXMLにそれを追加します。

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

第三に、それがデフォルトに選択された値のための変数として "SelectedValueの" を使用しますが、 "selectedValueAttrChanged" 何で、あなたの見たように、あなたのbindingUtil

public class SpinnerBindingUtil { 

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

} 

を追加する??私はこれが難しいと思った(呼び出されたときにnullではない理由は分かりません)、xmlに追加する必要はありません。これは、スピナーで変更されたアイテムを聴くためのコールバックであるためです。そして、あなたはonItemSelectedListenerを設定し、InverseBindingListenerを呼び出すように設定します。onchange()関数(ドキュメントと例:https://developer.android.com/reference/android/databinding/InverseBindingAdapter.htmlデフォルトのイベントは "android:textAttrChanged"で、カスタム双方向バインドinversebindを使用する場合は、あなたは接尾辞を持つ属性を使用する必要がある「AttrChanged」イベントの

デフォルト値は 「AttrChanged」接尾辞属性名です。上記の例では、デフォルト値は android:textAttrChanged(提供されていなくても)です。

あなたがコードを実行すると最後に、あなたの活動とあなたの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を

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

スピナー。これは多くの人

+2

は、 、newTextAttrChangedは、たとえあなたが –

+0

ではないと言っていてもnullです^^おそらく、あなたのxmlの "@"の後ろに "="がありません。 'bind:selectedValue =" @ = {viewModel.text} "のようになります。 –

0

@Longレンジャー私は本当にあなたの答えなどのために役立つことを願って、私たちはloop.likeにこれを破るために行う必要があるものがあると思う:私はこのことからNullPointerExceptionが取得

@BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) 
public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, final String newSelectedValue, final InverseBindingListener newTextAttrChanged) { 
    pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
     @Override 
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
      if(newSelectedValue != null && newSelectedValue.equlas(parent.getSelectedItem()){ 
       return; 
      } 
      newTextAttrChanged.onChange(); 
     } 
     @Override 
     public void onNothingSelected(AdapterView<?> parent) { 
     } 
    }); 
    if (newSelectedValue != null) { 
     int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); 
     pAppCompatSpinner.setSelection(pos, true); 
    } 
} 
関連する問題