나는 this 블로그 게시물을 따라 사용자 지정 구성 요소 (EditText가 포함 된 제약보기)에서 작동하도록 양방향 데이터 바인딩을 시도하려고합니다.맞춤 구성 요소에 대한 Android 양방향 데이터 바인딩?
두 가지 표준 EditText 구성 요소를 내 모델과 동기화 (두 가지 방법 모두) 할 수 있지만 사용자 정의 구성 요소의 변경 사항을 내 모델로 전달하는 데 문제가 있습니다 (단방향 데이터 바인딩 공장).
내 모델 :
public class Model extends BaseObservable {
private String value;
@Bindable
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
notifyPropertyChanged(company.com.databinding.BR.value);
}
public Model() {
value = "Value";
}
}
활동 :
@InverseBindingMethods({
@InverseBindingMethod(
type = CustomComponent.class,
attribute = "value",
method = "getValue")
})
public class MainActivity extends AppCompatActivity {
@BindingAdapter("value")
public static void setColor(CustomComponent view, String value) {
if (!value.equals(view.getValue())) {
view.setValue(value);
}
}
@BindingAdapter(
value = {"onValueChange", "valueAttrChanged"},
requireAll = false
)
public static void setListeners(CustomComponent view,
final ValueChangeListener onValueChangeListener,
final InverseBindingListener inverseBindingListener) {
ValueChangeListener newListener;
if (inverseBindingListener == null) {
newListener = onValueChangeListener;
} else {
newListener = new ValueChangeListener() {
@Override
public void onValueChange(CustomComponent view,
String value) {
if (onValueChangeListener != null) {
onValueChangeListener.onValueChange(view,
value);
}
inverseBindingListener.onChange();
}
};
}
ValueChangeListener oldListener =
ListenerUtil.trackListener(view, newListener,
R.id.textWatcher);
if (oldListener != null) {
view.removeListener(oldListener);
}
if (newListener != null) {
view.addListener(newListener);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setModel(new Model());
}
}
사용자 정의 구성 요소 :
public class CustomComponent extends ConstraintLayout {
private String value;
private EditText txt;
private TextWatcher textWatcher;
ValueChangeListener listener;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
if (txt != null) {
txt.setText(value);
}
}
public CustomComponent(Context context) {
super(context);
init(context);
}
public CustomComponent(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CustomComponent(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context) {
}
private void init(Context context, AttributeSet attrs) {
View.inflate(context, R.layout.custom_component, this);
txt = findViewById(R.id.txt_box);
final CustomComponent self = this;
textWatcher = 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 (listener != null) {
listener.onValueChange(self, editable.toString());
}
}
};
txt.addTextChangedListener(textWatcher);
}
public void addListener(ValueChangeListener listener) {
this.listener = listener;
}
public void removeListener(ValueChangeListener listener) {
this.listener = null;
}
}
public interface ValueChangeListener {
public void onValueChange(CustomComponent view, String value);
}
그 게시물에 "이벤트를 후킹"섹션을 통해 완전히 사라 졌 생각 내 머리; 난 정말 구성 요소에 대한 간단한 setter 및 getter가 필요하므로 BindingAdapter에서 수행 된 작업을 이해할 수 없습니다.
ValueChangeListener oldListener =
ListenerUtil.trackListener(view, newListener,
R.id.textWatcher);
데모에서 : https://github.com/indgov/data_binding