2016-06-17 3 views
12

मैं नए एंड्रॉइड डेटा बाइंडिंग का उपयोग कर रहा हूं और यह बहुत अच्छा काम करता है। मैं एडिटटेक्स्ट, टेक्स्ट व्यू, रेडियो और चेकबॉक्स का उपयोग कर डेटा बाइंडिंग करने में सक्षम हूं। अब, मैं स्पिनर में डाटाबेसिंग करने में सक्षम नहीं हूं। Android spinner data binding with xml layoutएंड्रॉइड स्पिनर डेटा एक्सएमएल का उपयोग कर बाध्यकारी और चयनित मान दिखाएं

लेकिन, फिर भी समाधान खोजने के लिए सक्षम नहीं:

नीचे दिए गए लिंक में कुछ सुराग मिले। दो तरह से डाटाबेसिंग करने की भी आवश्यकता है। स्पिनर डेटा चयनित मूल्य को प्रतिबिंबित करना चाहिए।

क्या कोई मुझे उदाहरण के साथ दिखा सकता है?

<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

मैंने पाया somethings उपयोगी हो सकता है, लेकिन यह बाध्यकारी दो तरह से डेटा के लिए आधिकारिक दस्तावेज में नहीं है।

1. दो तरह से डेटा के लिए '@ =' उपयोग

2. दो-तरफा कस्टम बाध्यकारी जरूरतों "BindingAdapter" और "InverseBindingAdapter" एनोटेशन डेटा बाइंडिंग इस लक्ष्य को हासिल करने के लिए।

पहले आइटम के लिए, ब्लॉगर के बहुत से दो तरीकों से डेटा बाध्यकारी के लिए "@ =" का उपयोग दिखाते थे। https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/

दूसरे मद के लिए, के रूप में @George माउंड यहाँ उत्तर दिया (Edit text cursor resets to left when default text of edittext is a float value) EditText दो तरह से में "BindingAdapter" और "InverseBindingAdapter" एनोटेशन का उपयोग कर बाँध जा सकता है।

निर्देशों के बाद, आप स्पिनर के लिए अपनी दो-तरफा बाध्यकारी विधि बना सकते हैं।

सबसे पहले, अपने ViewModel बनाने या दूसरे Pojo

ViewModel

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

Pojo

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

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

का उपयोग यह अपने xml में जोड़ें।

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

तीसरे,, अपने 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(); 
    } 

} 

जोड़ने अपने देखा के रूप में यह "selectedValue" का इस्तेमाल किया डिफ़ॉल्ट चयनित मूल्य के लिए चर के रूप में, लेकिन "selectedValueAttrChanged" क्या है ?? मैंने सोचा कि यह मुश्किल है (मुझे पता नहीं है कि इसे क्यों कहा जाता है जब यह शून्य नहीं होता है), इसे xml में जोड़ने की आवश्यकता नहीं है क्योंकि यह केवल स्पिनर में आइटम को सुनने के लिए कॉलबैक है।और फिर आप इसे इटम्स सेलेक्टेड लिस्टर सेट करते हैं और इसे इनवर्क्स बाइंडिंग लिस्टर ऑनचेंज() फ़ंक्शन (दस्तावेज़ीकरण और उदाहरण यहां: https://developer.android.com/reference/android/databinding/InverseBindingAdapter.html) डिफ़ॉल्ट ईवेंट "एंड्रॉइड: टेक्स्ट एट्रैच चेंज" होगा और यदि आप कस्टम दो-तरफा बाइंड इनवर्ड्सबिंड चाहते हैं, "AttrChanged" आप प्रत्यय के साथ विशेषता का उपयोग करने की आवश्यकता है घटना के लिए

डिफ़ॉल्ट मान विशेषता के साथ "AttrChanged" प्रत्यय नाम है। उपरोक्त उदाहरण में, डिफ़ॉल्ट मान एंड्रॉइड होगा: 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

मैं इस से एक NullPointerException मिल , newTextAttrChanged शून्य है, भले ही आपने कहा कि यह –

+0

^^ शायद आप अपने xml में "@" के बाद "@" गायब हैं। यह 'बांधना चाहिए: चयनित वैल्यू = "@ = {viewModel.text}" ' –

0

@Long रेंजर मैं वास्तव में अपने जवाब पसंद है, लेकिन मुझे लगता है कि वहाँ कुछ हम loop.like तोड़ने के लिए क्या करने की जरूरत है इस के लिए मदद कर सकते हैं:

@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); 
    } 
} 
संबंधित मुद्दे