2015-08-31 9 views
12

मैं नए Android डाटा बाइंडिंग पुस्तकालय (1.0-RC1) बाहर कोशिश कर रहा हूँ छोड़ दिया करने के लिए रीसेट करने और मैं तीन स्ट्रिंग क्षेत्र (नाम, ईमेल और आयु) और के साथ एक उपयोगकर्ता वस्तु बना दिया है उन्हें मेरे लेआउट में 3 एडिटटेक्स से लिंक किया गया।Edittext कर्सर के बाद एंड्रॉयड डाटा बाइंडिंग अद्यतन

पहले फ़ील्ड (नाम) पर मैंने टेक्स्टवॉचर रखा। लगता है सब कुछ अच्छी तरह से काम कर रहा है। मैंने को सूचित किया हैप्रॉपर्टी नाम फ़ील्ड में लूप को यह देखने के लिए जांच कर रहा है कि पाठ सेट करने के लिए अनुमति देने से पहले टेक्स्ट अलग है या नहीं।

समस्या यह है कि, जब भी मैं नाम फ़ील्ड में टाइप करता हूं, कर्सर प्रत्येक वर्ण के बाद EditText के बाईं ओर रीसेट करता है। मैं समाधान के लिए चारों ओर घूमता हूं लेकिन एक कर्सर मुद्दे के लिए सबसे अधिक सुझाव सुझाव कहते हैं कि संपादन टेक्स्ट के संदर्भ को पकड़ें और कर्सर की स्थिति को मैन्युअल रूप से समायोजित करें। लेकिन मैं ऐसा करने से बचना चाहता हूं क्योंकि मुझे संपादन दृश्य में ViewByID खोजने की आवश्यकता है और डेटा बाइंडिंग का बिंदु ऐसा करने से बचने का प्रयास करना था। आपके सहयोग के लिए धन्यवाद।

मेरे लेआउट इस तरह दिखता है:

<layout> 

<data> 
    <variable name="user" type="com.carlpoole.databindingstest.User"/> 
</data> 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:bind="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" 
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> 

    <EditText 
     android:layout_width="200dp" 
     android:layout_height="wrap_content" 
     android:id="@+id/name" 
     android:text="@{user.name}" 
     bind:addTextChangedListener="@{user.nameChanged}" 
     /> 

    <EditText 
     android:layout_width="200dp" 
     android:layout_height="wrap_content" 
     android:id="@+id/email" 
     android:layout_below="@+id/name" 
     android:text="@{user.email}"/> 

    <EditText 
     android:layout_width="200dp" 
     android:layout_height="wrap_content" 
     android:id="@+id/age" 
     android:layout_below="@+id/email" 
     android:text="@{user.age}"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/age" 
     android:text="@{user.name}"/> 

</RelativeLayout> 

मेरे उपयोगकर्ता वस्तु इस तरह दिखता है:

import android.databinding.BaseObservable; 
import android.databinding.Bindable; 
import android.text.Editable; 
import android.text.TextWatcher; 

public class User extends BaseObservable { 

    private String name; 
    private String email; 
    private String age; 

    public User(String name, String email, String age) { 
     this.name = name; 
     this.email = email; 
     this.age = age; 
    } 

    public User(){}; 

    @Bindable 
    public String getName() { 
     return name; 
    } 

    @Bindable 
    public String getEmail() { 
     return email; 
    } 

    @Bindable 
    public String getAge() { 
     return age; 
    } 

    public final TextWatcher nameChanged = new TextWatcher() { 
     @Override 
     public void afterTextChanged(Editable s) { 
      if(!s.toString().equalsIgnoreCase(name)) 
       setName(s.toString()); 
     } 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {} 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) {} 
    }; 

    public void setName(String name) { 
     this.name = name; 
     notifyPropertyChanged(com.carlpoole.databindingstest.BR.name); 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public void setAge(String age) { 
     this.age = age; 
    } 
} 

मेरे गतिविधि इस

import android.databinding.DataBindingUtil; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import com.carlpoole.databindingstest.databinding.ActivityMainBinding; 

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); 
     User user = new User("Carl Poole", "[email protected]", "26"); 
     binding.setUser(user); 

    } 
} 
+1

"मैं नाम क्षेत्र में notifyPropertyChanged पाश रोका यह देखने के लिए कि पाठ सेट नाम को कॉल करने की अनुमति देने से पहले टेक्स्ट अलग है या नहीं, "- हालांकि, अगर मैं सट्टेबाजी करने वाले व्यक्ति थे, तो मैं यह होगा कि यह आपके कर्सर की समस्याएं पैदा कर रहा है। आपके पास पहली जगह 'टेक्स्टवॉचर' क्यों है? – CommonsWare

+0

@CommonsWare TextWatcher संपादन टेक्स्ट में अद्यतन के लिए सुनता है ताकि यह उपयोगकर्ता ऑब्जेक्ट में नाम चर के लिए अद्यतन को आग लगा सके। इसके बिना, यह नहीं पता होगा।अगर मैं AfterTextChanged विधि से setName कॉल को हटा देता हूं तो यह ठीक काम करता प्रतीत होता है, ऐसा लगता है कि समस्या यह हो सकती है कि मैं डेटा बाइंडिंग लाइब्रेरी का उपयोग कैसे कर रहा हूं –

+1

"इसके बिना, यह नहीं पता" - मॉडल को अपडेट करें उपयोगकर्ता आपको मॉडल को अपडेट करने के लिए कहता है ("DONE" बटन पर क्लिक करता है, होम के माध्यम से गतिविधि छोड़ देता है आदि)। – CommonsWare

उत्तर

8

आपका सबसे अच्छा शर्त की तरह दिखता है यहां एक कस्टम का उपयोग करना है @BindingAdapter जो पहले से ही EditText का संदर्भ होगा। EditText में टेक्स्ट आपके मॉडल से मेल खाता है, तो आप अपने कर्सर मुद्दे को हल करेंगे, इस तरह से आप बाध्यकारी से बच सकते हैं।

सबसे पहले, android:text="@{user.name}" से bind:binding="@{user.name}" बदलें। फिर, अपनी परियोजना में कहीं भी इस स्थिर विधि को जोड़ें। हम उन सभी को BindingAdapters.java नामक कक्षा में रखते हैं। वैसे, आरसी 2 में शुरू करने से आप गैर स्थैतिक बाध्यकारी एडाप्टर विधियां बना सकते हैं, लेकिन शायद यह आपकी सबसे बड़ी चिंता नहीं है।

@BindingAdapter("binding") 
public static void bindEditText(EditText editText, CharSequence value) { 
    if (!editText.getText().toString().equals(value.toString())) { 
    editText.setText(value); 
    } 
} 
+1

डेटा बाइंडिंग गाइड अभी भी आरसी 1 को संदर्भित करता है। आरसी 2 पहले से ही बाहर है या यह अभी भी काम में है? – curioustechizen

+2

आरसी 2 अभी तक उपलब्ध नहीं है। जल्द ही आपके पास एक सहायक पुस्तकालय में आ रहा है। –

+0

मुझे कस्टम व्यू के साथ डाटाबेसिंग करने के लिए टेक्स्टवॉचर का उपयोग करना पड़ा, और एक ही समस्या मिली। आपका समाधान मेरे लिए पूरी तरह से काम किया। धन्यवाद। – rajath

2

समस्या सेटर भ्रम के साथ है: अपने सेटर, के रूप में DataBinding प्रलेखन द्वारा सिफारिश की, notifyPropertyChanged प्रणाली को बुलाती है। लेकिन अधिसूचनाप्रॉपर्टी चेंज विधि, अन्य चीजों के साथ, कर्सर को रीसेट करता है जो आपकी समस्या का कारण बनती है। यूआई को अपडेट करने के लिए सेटटर के लिए उनकी आवश्यकता नहीं है जब यह यूआई (टेक्स्टवॉचर) था जो सेटर को कॉल कर रहा था। समाधान तब होता है जब सेटर्स केवल अधिसूचना को कॉल करते हैंप्रॉपर्टी चेंज विधि जब कुछ बैकएंड गणना/हेरफेर को यूआई को अपडेट किया जाना चाहिए।

2

बाध्यकारी व्यवहार है कि EditText के शुरू करने के कर्सर को रीसेट करता है अजीब डेटा को ठीक करने के लिए, आपको निम्न InverseBindingAdapter जोड़ सकते हैं:

@InverseBindingAdapter(attribute = "android:text") public static 
String getText(EditText view) { 

String text = view.getText().toString(); 
view.setSelection(text.length()); 

return text; 

}

+1

यह एक साफ समाधान की तरह दिखता है –

संबंधित मुद्दे