Bối cảnh:Đang cập nhật giao diện người dùng sử dụng dữ liệu ràng buộc thư viện
Tôi đang sử dụng v1.0-rc1 của new data binding library.
tôi có mô hình quan điểm sau đây:
public class DrawerPageHeaderViewModelImpl extends BaseObservable implements DrawerPageHeaderViewModel {
@Nullable
private Location currentLocation;
public DrawerPageHeaderViewModelImpl(@Nullable final Location currentLocation) {
this.currentLocation = currentLocation;
}
@Bindable
@Nullable
@Override
public String getDistanceDisplayString() {
if (currentLocation == null) {
return null;
}
float[] results = new float[1];
Location.distanceBetween(landmark.getLatitude(), landmark.getLongitude(), currentLocation.getLatitude(), currentLocation.getLongitude(), results);
final float metersToTargetLocation = results[0];
final float feetToTargetLocation = DistanceUtil.convertMetersToFeet(metersToTargetLocation);
return DistanceUtil.convertFeetToFeetOrMilesString(feetToTargetLocation);
}
@Override
public void setCurrentLocation(@Nullable final Location currentLocation) {
this.currentLocation = currentLocation;
notifyPropertyChanged(BR.distanceDisplayString);
}
}
mô hình Quan điểm này được chuyển cho một Fragment
và lưu trữ trong một biến ví dụ. Mô hình điểm sau đó được ràng buộc với một bố trí trong onCreateView
callback của Fragment (ở đây headerView
là một sản phẩm nào FrameLayout
):
@Nullable
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_drawer_page, container, false);
headerView = (ViewGroup) v.findViewById(R.id.headerView);
final ViewDrawerPageHeaderBinding binding = DataBindingUtil.inflate(inflater, R.layout.view_drawer_page_header, headerView, true);
binding.setViewModel(viewModel);
return v;
}
Định kỳ, viewModel.setCurrentLocation
được gọi và thông qua hiện tại vị trí của người dùng:
@Override
public void update(final Observable observable, Object data) {
new Handler(Looper.getMainLooper()).post(() -> {
if (isAdded()) {
viewModel.setCurrentLocation(locationController.getCachedUserLocation());
}
});
}
Hành vi hiện tại:
Giao diện người dùng hiển thị chính xác khoảng cách String
khi mỗi Fragment
được tạo đầu tiên. Giao diện người dùng hiển thị một cách chính xác khoảng cách String
mỗi lần Fragment
được tái tạo (những mảnh vỡ đang sống trong một ViewPager
UI KHÔNG cập nhật khi viewModel.setCurrentLocation
được gọi với một vị trí mới
hành vi mong muốn:..
Giao diện cập nhật mỗi lần viewModel.setCurrentLocation
được gọi với một vị trí mới
Nội dung tôi đã nhìn/suy nghĩ về cho đến nay:.
Theo như tôi có thể biết, có mô hình xem thực hiện Observable
(trong trường hợp này, thông qua mở rộng BaseObservable
) được yêu cầu tự động cập nhật giao diện người dùng khi gọi notifyPropertyChanged
. Ít nhất, khi tôi nhìn vào the Android documentation for data binding, đó là thông điệp tôi lấy đi.
Lớp BaseObservable
duy trì danh sách riêng là OnPropertyChangedCallback
s. Nếu tôi đặt một breakpoint debug vào phương pháp BaseObservable.notifyPropertyChanged
:
public void notifyPropertyChanged(int fieldId) {
if(this.mCallbacks != null) {
this.mCallbacks.notifyCallbacks(this, fieldId, (Object)null);
}
}
Tôi thấy rằng mCallbacks
luôn null
là khi chạy. Vì vậy, có lẽ, các công cụ ràng buộc dữ liệu được tạo ra không gọi BaseObservable.addOnPropertyChangedCallback
để cung cấp một OnPropertyChangedCallback
tự động kết nối các thành phần. Điều đó có nghĩa là tôi cần phải làm điều đó bằng tay? Điều đó dường như sẽ đánh bại rất nhiều điểm của thư viện ràng buộc dữ liệu.
Một sự khác biệt giữa những gì bạn có và những gì họ có là họ có song song trong tên phương pháp. Chúng có các getters với '@ Bindable' và các bộ giải mã tương ứng với các lời gọi' notifyPropertyChanged() 'và chúng cũng khớp với trường' BR' tương ứng. Tên phương thức của bạn không có chung cơ sở. Bạn có thể tạm thời đổi tên chúng để có nhiều getter/setter-like và xem nếu điều đó ảnh hưởng đến hành vi. Nếu có, bạn có thể sẽ phải đi với những tên đó, ngay cả khi bạn muốn gọi chúng bằng tên mà bạn đang sử dụng. Tôi sẽ ngạc nhiên nếu điều này đã giúp, nhưng đó là một thử nghiệm dễ dàng. – CommonsWare
@CommonsWare cảm ơn đề xuất; sẽ dùng thử và báo cáo lại. – stkent
@CommonsWare thật đáng buồn, không thay đổi hành vi sau khi thực hiện các sửa đổi bạn đề xuất. FWIW, tôi đã sử dụng 'getCurrentLocation' /' setCurrentLocation'/'currentLocation' làm triple của tôi. – stkent