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();
});
}
'Outlet outlet = new Outlet();'은 초기화이며'Outlet outlet = gson.fromJson (realmOutlet.getPayload(), Outlet.class); '은 초기화하지 않고 값을 설정합니다. 'Log'가 붙어 있지 않습니다! – Smit
예. 그러나 미리 채워진 데이터. 데이터 바인더에 연결합니다. 이것이 데이터 바인딩의 본질이 아닌가?뷰를 데이터로 자동 채우고 뷰에서 데이터를 수집합니까? @Smit –
'Outlet outlet = new Outlet();'그런 다음 'Outlet outlet = gson.fromJson (realmOutlet.getPayload(), Outlet.class);'그런 다음'binding.setOutlet (outlet);'how를 시도하십시오. 이것에 관해서? 그리고 후속 업데이트는 단지 'outlet = gson.fromJson (realmOutlet.getPayload(), Outlet.class);' – Smit