2016-08-13 4 views
0

Android 앱에서 Android Databinding을 사용하려고합니다. 어떤 데이터도없이 객체를 초기화하면 객체 Outlet이 생겼습니다. 모든 것이 잘 작동합니다. 모든 데이터가 잘 수집됩니다. 그러나 데이터로 Object을 초기화하고 레이아웃에 전달하면 Invoking Interface method on Null Views의 불평과 함께 앱이 다운됩니다. 이 아래에있는 내 레이아웃 파일입니다Android 데이터 바인딩 어댑터 Null 포인터 예외

<?xml version="1.0" encoding="utf-8"?> 
    <layout xmlns:android="http://schemas.android.com/apk/res/android"> 

     <data> 
      <import type="java.util.List"/> 
      <import type="android.view.View" /> 
      <variable 
       name="outlet" 
       type="co.deliveryscience.dangote.Network.model.Outlet.Create.Outlet"/> 
     </data> 

     <android.support.v4.widget.NestedScrollView 
      xmlns:app="http://schemas.android.com/apk/res-auto" 
      android:orientation="vertical" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:orientation="vertical"> 

       <android.support.v7.widget.CardView 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_marginBottom="32dp" 
        android:layout_marginLeft="64dp" 
        android:layout_marginRight="64dp" 
        android:layout_marginTop="32dp" 
        android:background="#FFF" 
        android:animateLayoutChanges="true" 
        app:cardCornerRadius="4dp" 
        app:elevation="5dp"> 

        <LinearLayout 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:orientation="vertical" 
         android:paddingBottom="16dp" 
         android:paddingLeft="16dp" 
         android:paddingRight="16dp" 
         android:paddingTop="16dp" 
         android:animateLayoutChanges="true"> 

         <TextView 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          style="@style/HeaderText" 
          android:text="@string/personal_information" 
          android:layout_marginBottom="8dp" 
          android:layout_marginTop="16dp"/> 

         <View 
          android:layout_width="match_parent" 
          android:layout_height="0.5dp" 
          android:background="@color/gray_semi_transparent" 
          android:layout_marginBottom="32dp"/> 

         <LinearLayout 
          android:id="@+id/layoutCreate" 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:orientation="vertical" 
          android:layout_marginBottom="32dp"> 

          <TextView 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content" 
           android:text="@string/name_of_outlet" 
           android:layout_marginBottom="8dp"/> 

          <EditText 
           android:id="@+id/nameOfOutlet" 
           android:layout_width="match_parent" 
           android:layout_height="55dp" 
           android:inputType="textCapWords" 
           android:singleLine="true" 
           android:imeOptions="actionNext" 
           android:text='@{outlet.name ?? ""}' 
           android:addTextChangedListener="@{outlet.onNameChanged}" 
           android:nextFocusDown="@+id/address"/> 

         </LinearLayout> 

         <LinearLayout 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:orientation="horizontal" 
          android:baselineAligned="false"> 

          <LinearLayout 
           android:layout_width="0dp" 
           android:layout_height="wrap_content" 
           android:layout_weight="1" 
           android:orientation="vertical" 
           android:layout_marginRight="8dp" 
           android:layout_marginEnd="8dp"> 

           <TextView 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="@string/ownerfirstname" 
            android:layout_marginBottom="8dp"/> 

           <EditText 
            android:id="@+id/fName" 
            android:layout_width="match_parent" 
            android:layout_height="55dp" 
            android:layout_marginBottom="16dp" 
            android:inputType="textCapWords" 
            android:singleLine="true" 
            android:imeOptions="actionNext" 
            android:text="@{outlet.firstName}" 
            android:addTextChangedListener="@{outlet.onFirstNameChanged}" 
            android:nextFocusRight="@+id/lName"/> 

          </LinearLayout> 

          <LinearLayout 
           android:layout_width="0dp" 
           android:layout_height="wrap_content" 
           android:layout_weight="1" 
           android:orientation="vertical" 
           android:layout_marginLeft="8dp" 
           android:layout_marginStart="8dp"> 

           <TextView 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="@string/ownerlastname" 
            android:layout_marginBottom="8dp"/> 

           <EditText 
            android:id="@+id/lName" 
            android:layout_width="match_parent" 
            android:layout_height="55dp" 
            android:layout_marginBottom="16dp" 
            android:inputType="textCapWords" 
            android:text='@{outlet.lastName == null ? "" : outlet.lastName}' 
            android:addTextChangedListener="@{outlet.onLastNameChanged}" 
            android:singleLine="true" 
            android:imeOptions="actionNext" 
            android:nextFocusDown="@+id/nameOfOutlet"/> 

          </LinearLayout> 

         </LinearLayout> 

         <TextView 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          style="@style/HeaderText" 
          android:text="@string/contact_information" 
          android:layout_marginBottom="8dp" 
          android:layout_marginTop="16dp"/> 

         <View 
          android:layout_width="match_parent" 
          android:layout_height="0.5dp" 
          android:background="@color/gray_semi_transparent" 
          android:layout_marginBottom="32dp"/> 

         <TextView 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:text="@string/address" 
          android:layout_marginBottom="8dp"/> 

         <EditText 
          android:id="@+id/address" 
          android:layout_width="match_parent" 
          android:layout_height="55dp" 
          android:layout_marginBottom="16dp" 
          android:inputType="textPostalAddress" 
          android:text='@{outlet.address == null ? "" : outlet.address}' 
          android:addTextChangedListener="@{outlet.onAddresChanged}" 
          android:imeOptions="actionNext" 
          android:nextFocusDown="@+id/lga"/> 

         <LinearLayout 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:orientation="horizontal" 
          android:layout_marginBottom="16dp" 
          android:baselineAligned="false"> 

          <LinearLayout 
           android:layout_width="0dp" 
           android:layout_height="wrap_content" 
           android:orientation="vertical" 
           android:layout_weight="1" 
           android:layout_marginRight="8dp" 
           android:layout_marginEnd="8dp"> 

           <TextView 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="@string/lga" 
            android:layout_marginBottom="8dp"/> 

           <AutoCompleteTextView 
            android:id="@+id/lga" 
            android:layout_width="match_parent" 
            android:layout_height="55dp" 
            android:imeOptions="actionNext" 
            android:inputType="textCapWords" 
            android:text="@{outlet.lga}" 
            android:singleLine="true" 
            android:nextFocusRight="@+id/state"/> 

          </LinearLayout> 

          <LinearLayout 
           android:layout_width="0dp" 
           android:layout_height="wrap_content" 
           android:orientation="vertical" 
           android:layout_weight="1" 
           android:layout_marginStart="8dp" 
           android:layout_marginLeft="8dp"> 

           <TextView 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="@string/state" 
            android:layout_marginBottom="8dp"/> 

           <AutoCompleteTextView 
            android:id="@+id/state" 
            android:layout_width="match_parent" 
            android:layout_height="55dp" 
            android:imeOptions="actionNext" 
            android:inputType="textCapWords" 
            android:singleLine="true" 
            android:nextFocusDown="@+id/phoneNumber1" /> 

          </LinearLayout> 

         </LinearLayout> 

         <LinearLayout 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:orientation="horizontal" 
          android:layout_marginBottom="16dp" 
          android:baselineAligned="true"> 

          <LinearLayout 
           android:layout_width="0dp" 
           android:layout_height="wrap_content" 
           android:layout_weight="1" 
           android:layout_marginRight="8dp" 
           android:layout_marginEnd="8dp" 
           android:orientation="vertical"> 

           <TextView 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="@string/phone_number_1" 
            android:layout_marginBottom="8dp"/> 

           <EditText 
            android:id="@+id/phoneNumber1" 
            android:layout_width="match_parent" 
            android:layout_height="55dp" 
            android:layout_marginBottom="16dp" 
            android:inputType="phone" 
            android:imeOptions="actionNext" 
            android:addTextChangedListener="@{outlet.onPhoneNumberChanged}" 
            android:text="@{outlet.phoneNumber}" 
            android:singleLine="true" 
            android:nextFocusDown="@+id/phoneNumber2"/> 

          </LinearLayout> 

          <LinearLayout 
           android:layout_width="0dp" 
           android:layout_height="wrap_content" 
           android:layout_weight="1" 
           android:layout_marginLeft="8dp" 
           android:layout_marginStart="8dp" 
           android:orientation="vertical"> 

           <TextView 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="@string/phone_number_2" 
            android:layout_marginBottom="8dp"/> 

           <EditText 
            android:id="@+id/phoneNumber2" 
            android:layout_width="match_parent" 
            android:layout_height="55dp" 
            android:layout_marginBottom="16dp" 
            android:inputType="phone" 
            android:imeOptions="actionNext" 
            android:addTextChangedListener="@{outlet.onOtherPhoneNumberChanged}" 
            android:text="@{outlet.phoneNumber}" 
            android:singleLine="true" 
            android:nextFocusDown="@+id/outletOwnerEmail"/> 

          </LinearLayout> 

         </LinearLayout> 

        </LinearLayout> 

       </android.support.v7.widget.CardView> 

      </LinearLayout> 

     </android.support.v4.widget.NestedScrollView> 
    </layout> 

그리고 나는이 작업을 수행 할 때 내 감시 오브젝트는이

public class Outlet extends BaseObservable { 

     private static final String TAG = "Outlet"; 
     @SerializedName("name") 
     @Expose 
     private String name; 
     @SerializedName("firstName") 
     @Expose 
     private String firstName; 
     @SerializedName("lastName") 
     @Expose 
     private String lastName; 
     @SerializedName("phoneNumber") 
     @Expose 
     private String phoneNumber; 
     @SerializedName("otherNumber") 
     @Expose 
     private String otherNumber; 
     @SerializedName("address") 
     @Expose 
     private String address; 

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

     /** 
     * 
     * @param name 
     *  The name 
     */ 
     public void setName(String name) { 
      setAtomicName(name); 
      notifyPropertyChanged(BR.name); 
     } 

     public void setAtomicName(String basic) { 
      this.name = basic; 
     } 

     public TextWatcher onNameChanged = new SimpleTextWatcher() { 
      @Override 
      public void onTextChanged(String newValue) { 
       Log.e(TAG+"Name", newValue); 
       setAtomicName(newValue); 
      } 
     }; 

     /** 
     * 
     * @return 
     *  The firstName 
     */ 
     @Bindable 
     public String getFirstName() { 
      return firstName; 
     } 

     /** 
     * 
     * @param firstName 
     *  The firstName 
     */ 
     public void setFirstName(String firstName) { 
      setAtomicFirstName(firstName); 
      notifyPropertyChanged(BR.firstName); 
     } 

     public void setAtomicFirstName(String basic) { 
      this.firstName = basic; 
     } 

     public TextWatcher onFirstNameChanged = new SimpleTextWatcher() { 
      @Override 
      public void onTextChanged(String newValue) { 
       Log.e(TAG+"FirstName", newValue); 
       setAtomicFirstName(newValue); 
      } 
     }; 

     /** 
     * 
     * @return 
     *  The lastName 
     */ 
     @Bindable 
     public String getLastName() { 
      return lastName; 
     } 

     /** 
     * 
     * @param lastName 
     *  The lastName 
     */ 
     public void setLastName(String lastName) { 
      setAtomicLastName(lastName); 
      notifyPropertyChanged(BR.lastName); 
     } 

     public void setAtomicLastName(String basic) { 
      this.lastName = basic; 
     } 

     public TextWatcher onLastNameChanged = new SimpleTextWatcher() { 
      @Override 
      public void onTextChanged(String newValue) { 
       Log.e(TAG+"lstname", newValue); 
       setAtomicLastName(newValue); 
      } 
     }; 

     /** 
     * 
     * @return 
     *  The phoneNumber 
     */ 
     @Bindable 
     public String getPhoneNumber() { 
      return phoneNumber; 
     } 

     /** 
     * 
     * @param phoneNumber 
     *  The phoneNumber 
     */ 
     public void setPhoneNumber(String phoneNumber) { 
      setAtomicPhoneNumber(phoneNumber); 
      notifyPropertyChanged(BR.phoneNumber); 
     } 

     public void setAtomicPhoneNumber(String basic) { 
      this.phoneNumber = basic; 
     } 

     public TextWatcher onPhoneNumberChanged = new SimpleTextWatcher() { 
      @Override 
      public void onTextChanged(String newValue) { 
       Log.e(TAG+"phonenumber", newValue); 
       setAtomicPhoneNumber(newValue); 
      } 
     }; 

     /** 
     * 
     * @return 
     *  The otherNumber 
     */ 
     public String getOtherNumber() { 
      return otherNumber; 
     } 

     /** 
     * 
     * @param otherNumber 
     *  The otherNumber 
     */ 
     public void setOtherNumber(String otherNumber) { 
      setAtomicOtherPhoneNumber(otherNumber); 
      notifyPropertyChanged(BR.phoneNumber); 
     } 

     public void setAtomicOtherPhoneNumber(String basic) { 
      this.otherNumber = basic; 
     } 

     public TextWatcher onOtherPhoneNumberChanged = new SimpleTextWatcher() { 
      @Override 
      public void onTextChanged(String newValue) { 
       Log.e(TAG+"otherphone", newValue); 
       setAtomicOtherPhoneNumber(newValue); 
      } 
     }; 

     /** 
     * 
     * @return 
     *  The address 
     */ 
     @Bindable 
     public String getAddress() { 
      return address; 
     } 

     /** 
     * 
     * @param address 
     *  The address 
     */ 
     public void setAddress(String address) { 
      setAtomicAddress(address); 
      notifyPropertyChanged(BR.phoneNumber); 
     } 

     public void setAtomicAddress(String basic) { 
      this.address = basic; 
     } 

     public TextWatcher onAddresChanged = new SimpleTextWatcher() { 
      @Override 
      public void onTextChanged(String newValue) { 
       Log.e(TAG+"address", newValue); 
       setAtomicAddress(newValue); 
      } 
     }; 

     @BindingAdapter({"bind:email"}) 
     public static void checkEmail(EditText editText, String email) { 
      if (editText != null) { 
       editText.addTextChangedListener(new TextWatcher() { 
        @Override 
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
        } 

        @Override 
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
        } 

        @Override 
        public void afterTextChanged(Editable editable) { 
         if (editText.length() > 0) { 
          if (!Utils.emailMatchPattern(editText.getText().toString())) editText.setError("Email Requried"); 
         } 
        } 
       }); 
      } 
     } 
    } 

입니다. Outlet outlet = new Outlet(); 그리고 이것을 내 바인딩 데이터에 할당하십시오. binding.setOutlet(outlet); 나는 어떤 오류도 내지 않을 것입니다. 나는이 작업을 수행한다면, 상기 데이터가 없기 때문에

Outlet outlet = gson.fromJson(realmOutlet.getPayload(), Outlet.class); 
binding.setOutlet(outlet); 

은 내가 NPE Error와 NPE에 따라 얻을, 그것은 아니다. 마치 adapters이 초기화되지 않은 것과 같습니다. 나는 그것이 첫번째 항목이기 때문에 그것이 addressField을 가리키고 있다는 것을 안다. 주소는 adapter입니다. 그것은 추상적 인 클래스입니다. 하지가 initializede 왜, 내가 혼란 스러워요 :

다음
public TextWatcher onAddresChanged = new SimpleTextWatcher() { 
      @Override 
      public void onTextChanged(String newValue) { 
       Log.e(TAG+"address", newValue); 
       setAtomicAddress(newValue); 
      } 
     }; 

Log 내가 로그가 정확히 무엇을 디버그에 알고 추적 할 수 있습니다. 그러나, 그 자체가 Interface method에 붙어있는 뷰는 null입니다. 마치 Binding Layouts이 아직 초기화되지 않았습니다. 그래서 빈 데이터로 초기화 할 때 왜 작동합니까?

그리고 내 onCreate 코드

 @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //setContentView(R.layout.activity_create); 
     binding = DataBindingUtil.setContentView(this, R.layout.activity_create); 
     realm = RealmUtils.getRealmInstance(getApplicationContext()); 

     setSupportActionBar(binding.createToolbar); 
     action = getIntent().getStringExtra("action"); 

     if (getSupportActionBar() != null) { 
      getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
      initAutoCompletedTexts(); 
      if (action != null) { 
       if (action.equals("create")) { 
        getSupportActionBar().setTitle(R.string.create); 
        outlet = new Outlet(); 
        outlet.setShopkeeper(shopkeeper); 
        binding.setOutlet(outlet); 
       } else { 
        getSupportActionBar().setTitle(R.string.update); 
        binding.saveBtn.setText("UPDATE"); 
        initUpdateSpcific(); 

       } 
      } 
     } 

     //createBinding.setCustomer(outlet); 
     binding.saveBtn.setOnClickListener(view -> { 
      save(); 
     }); 
    } 
+1

'Outlet outlet = new Outlet();'은 초기화이며'Outlet outlet = gson.fromJson (realmOutlet.getPayload(), Outlet.class); '은 초기화하지 않고 값을 설정합니다. 'Log'가 붙어 있지 않습니다! – Smit

+0

예. 그러나 미리 채워진 데이터. 데이터 바인더에 연결합니다. 이것이 데이터 바인딩의 본질이 아닌가?뷰를 데이터로 자동 채우고 뷰에서 데이터를 수집합니까? @Smit –

+1

'Outlet outlet = new Outlet();'그런 다음 'Outlet outlet = gson.fromJson (realmOutlet.getPayload(), Outlet.class);'그런 다음'binding.setOutlet (outlet);'how를 시도하십시오. 이것에 관해서? 그리고 후속 업데이트는 단지 'outlet = gson.fromJson (realmOutlet.getPayload(), Outlet.class);' – Smit

답변

1

이 주를 가지고 할 몇 가지가 있습니다

Outlet outlet = new Outlet();

2)의 값을 할당 :

1) 초기화는 다음과 같은 방식으로 작동합니다 :

Outlet outlet = gson.fromJson(realmOutlet.getPayload(), Outlet.class);

데이터를 유지하려면 은 반드시으로 초기화하고 그에 따라 데이터를 업데이트해야합니다.

이 :

그래서 당신은 모두를해야하지만, 구조화 된 방법으로, 즉

Outlet outlet = new Outlet(); 
    Outlet outlet = gson.fromJson(realmOutlet.getPayload(), Outlet.class);  
    binding.setOutlet(outlet); 

그리고 이후의 업데이트 :

outlet = gson.fromJson(realmOutlet.getPayload(), Outlet.class); 
    binding.setOutlet(outlet); 

UPDATE을 값을 할당하고 setOutlet 다른 사람이 참조 할 수 있도록 질문에 대한 답과 의견에 대한 채팅의 후속 조치입니다.