2016-04-11 4 views
18

मैं अपने एंड्रॉइड ऐप में लेआउट को बाध्य करने के लिए डेटा बाइंडिंग का उपयोग कर रहा हूं।मेरे बाध्यकारी के लिए inflate विधि नहीं मिला है (एंड्रॉइड, डेटा बाइंडिंग का उपयोग करना।)

मैंने अपना लेआउट (my_custom.xml) सेट किया है और बाध्यकारी वर्ग जेनरेट किया गया है (MyCustomBinding), लेकिन एंड्रॉइड स्टूडियो को बाध्यकारी वर्ग की .inflate (...) विधि को तुरंत नहीं लगता है, अंकन यह एक त्रुटि के रूप में (लाल पाठ!)।

हालांकि यह कोड सही लगता है, क्योंकि यह संकलित करता है और एक एपीके में ठीक बनाता है।

मैं एंड्रॉइड स्टूडियो को सही तरीके से अपडेट करने के लिए कैसे प्राप्त करूं?

कोड उदाहरण:

public class MyCustomView extends FrameLayout { 
    public MyCustomView(Context context) { 
     this(context, null, 0); 
    } 
    public MyCustomView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 
    public MyCustomView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     MyCustomBinding binding = MyCustomBinding.inflate(inflater, this, true); 
     binding.aButton.setText("Whatever"); 
    } 
} 

लेआउट के रूप में परिभाषित किया गया है:

यह मेरा कस्टम देखें कोड है (लाल रंग से हाइलाइट)

: यहाँ

<?xml version="1.0" encoding="utf-8"?> 
<layout 
    xmlns:android="http://schemas.android.com/apk/res/android"> 
    <data> 
    </data> 
    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     > 
     <TextView 
      android:id="@+id/a_button" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Click me!" 
      android:padding="10dp" 
      android:background="#000" 
      android:textColor="#fff" 
      android:layout_gravity="center" 
      /> 
    </FrameLayout> 
</layout> 

और मुद्दा है enter image description here

+0

कृपया अपना कोड पोस्ट करें। क्या आप गतिविधि या टुकड़े का उपयोग कर रहे हैं? –

+0

"MyCutom बाइंडिंग" कक्षा कोड पोस्ट करें। –

+0

यह मुझे एंड्रॉइड स्टूडियो 2.2 में एक बग होने के लिए प्रतीत होता है। मैं महीनों तक इस मुद्दे के बिना डेटा बाइंडिंग का उपयोग कर रहा हूं जब तक कि मैंने आज अपग्रेड नहीं किया, और अब मैं इसे भी देख रहा हूं। यदि आप इसका अनुसरण करना चाहते हैं तो एक [बग रिपोर्ट] (https://code.google.com/p/android/issues/detail?id=222194) है। –

उत्तर

8

कुछ एंड्रॉयड स्टूडियो में पूरा नहीं कर रहा है क्योंकि आप वास्तव में बंधन लागू नहीं किया है डेटा। एक बार जब आप अपने लेआउट के data तत्व में एक चर जोड़ते हैं, तो inflate विधि आपकी अपेक्षा के अनुसार मिल जाएगी। उस ने कहा, आपको वास्तव में बाध्यकारी के माध्यम से सीधे टेक्स्ट फ़ील्ड के मान को सेट करके डेटाबेसिंग का लाभ नहीं मिल रहा है। आपको इसके बजाय अपने बाध्यकारी में एक व्यू मॉडल सेट करना चाहिए, और उसके बाद बाइंडिंग को तदनुसार दृश्यों को अपडेट करना चाहिए।उदाहरण के लिए:

बनाने एक दृश्य मॉडल:

public class MyViewModel { 
    public final ObservableField<String> name; 
    public MyViewModel(String name) { 
     this.name = new ObservableField<>(name); 
    } 
} 

और अपने लेआउट में इसका इस्तेमाल

<?xml version="1.0" encoding="utf-8"?> 
<layout xmlns:android="http://schemas.android.com/apk/res/android"> 
    <data> 
     <variable name="model" type="com.victoriaschocolates.conceirge.MyViewModel" /> 
    </data> 
    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     > 
     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@{model.name}" 
      android:padding="10dp" 
      android:background="#000" 
      android:textColor="#fff" 
      android:layout_gravity="center" 
      /> 
    </FrameLayout> 
</layout> 

(ध्यान दें variabledata तत्व में घोषणा की, और यह कैसे TextView के में संदर्भित है text विशेषता)

फिर अपने कस्टम दृश्य में दोनों को बाध्य करें:

public class MyCustomView extends FrameLayout { 

    public MyCustomView(Context context) { 
     this(context, null, 0); 
    } 

    public MyCustomView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     MyCustomBinding binding = MyCustomBinding.inflate(inflater, this, true); 
     MyViewModel model = new MyViewModel("Whatever"); 
     binding.setModel(model); 
    } 
} 
बेशक

, यह शायद डेटा कस्टम दृश्य कक्षा में एक सेटर के माध्यम से में पारित कर दिया है करने के लिए बेहतर अभी भी हो सकता है, या यहाँ तक कि कंटेनर देखने से में पारित (http://developer.android.com/tools/data-binding/guide.html#includes देखें)

+0

धन्यवाद! हां, मुझे एहसास है कि डेटा बाध्यकारी का उपयोग करने का इच्छित तरीका मोड विज्ञापन का उपयोग करना है, फिर xml में मानों को बांधना है। मुझे मॉडल ऑब्जेक्ट आदि बनाने के विरोध में कोड में बाइंडिंग करने के लिए कुछ समय लगता है। – treesAreEverywhere

+0

इसके लिए मेरा समाधान अब एक खाली मॉडल वर्ग को परिभाषित करना है: पब्लिक क्लास एम्प्टीमोडेल {}, और फिर इसे एक चर के रूप में परिभाषित करें [[]], वास्तव में किसी भी विचार को बाध्य किए बिना। – treesAreEverywhere

2

आप अपने बाइंडिंग लेआउट के लिए एक कस्टम वर्ग के नाम सेट करने का प्रयास कर सकते हैं, और यह स्पष्ट करने के लिए जो आप उपयोग कर लेआउट आपके कस्टम दृश्य में संदर्भित:

<layout> 
    <data class="MyCustomBinding"> 
    </data> 
</layout> 

अगर यह काम नहीं करता है, DataBindingUtil बजाय MyCustomBinding उपयोग करते हैं, जो आधार DataBinding वर्ग वापस आती है और एक inflate() विधि है:

MyCustomBinding binding = DataBindingUtil.inflate(inflater, this, true); 

docs से:

कभी-कभी बाध्यकारी अग्रिम में नहीं जाना जा सकता है। ऐसे मामलों में, बंधन DataBindingUtil वर्ग का उपयोग कर बनाया जा सकता है:

ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater, layoutId, 
parent, attachToParent); 
ViewDataBinding binding = DataBindingUtil.bindTo(viewRoot, layoutId); 
+1

उत्तर के लिए धन्यवाद। मुझे विश्वास नहीं है कि यह मेरे प्रश्न का सबसे अच्छा तरीका है। मुझे लगता है कि यह उन मामलों में से एक नहीं है जहां MyCustomBinding ज्ञात नहीं है। मैं * एंड्रॉइड स्टूडियो में कक्षा आयात करता हूं, और यह संकलित करता है। यह अजीब हिस्सा यह है कि .inflate() विधि पहचाना नहीं गया है। – treesAreEverywhere

+0

यह संकलित करता है? ओह। मेरी गलती - लेकिन क्या आपने कक्षा को कक्षा में स्थापित करने का प्रयास किया है? – yennsarah

+1

हां यह संकलित करता है। एंड्रॉइड स्टूडियो में विश्वास है कि यह ज्यादातर एक मुद्दा है। मैंने कक्षा में कक्षा को स्थापित करने का प्रयास किया है। हालांकि यह मुझे बाध्यकारी के वर्गनाम को बदलने की अनुमति देता है, यह दुर्भाग्यवश समस्या को ठीक नहीं करता है। – treesAreEverywhere

0

आप की जरूरत है कि न सामानों का प्रकार, डेटा बाइंडिंग में डेटाबाइंडिंग क्लास क्लास शामिल है, हम यहां जाते हैं।

public MyCustomView(Context context, AttributeSet attrs, int defStyle){ 
    super(context, attrs, defStyle); 
    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    MyCustomBinding binding = DataBindingUtil.inflate(inflater, this, true); 
    binding.aButton.setText("Whatever"); 
} 
संबंधित मुद्दे