2016-11-10 2 views
0

SOLVED! 최종 솔루션은 아래를 참조하십시오서비스로 모델을 업데이트 할 때 MVVM 데이터 바인딩

문제 : 내가 안드로이드 앱 데이터 바인딩 및 MVVM을 사용하려고하지만 문제의 MVVM 부분에서 분리 된 모델이 서비스에 의해 업데이트된다는 사실에있다 앱. viewmodel을 통해 모델을 업데이트해도 정상적으로 작동하지만 뷰 모델 및 뷰에 버블 링되도록 모델을 변경하는 올바른 방법을 찾지 못했습니다. 서비스.

앱 : 앱 블루투스를 통해 외부 장치에 연결하고, 센서 판독 및 설정이 실시간 부근에서 앱 디바이스로부터 연속 스트리밍 직렬 연결을 유지한다. 이 연결을 통해 장치에 명령을 보낼 수도 있습니다. 이 모델은 장치의 메모리 내 표시 역할을합니다. 앱의 여러 화면에서 모델의 다른 섹션이 사용자에게 노출되며 특정 값 (설정)을 조정할 수도 있고 허용하지 않을 수도 있습니다.

코드 :는 (I는 단순화 된 버전은 여기 내 정확한 코드를 보여줄 수는 없지만)

모델 :

public class DeviceModel extends BaseObservable { 

private int mode; 

@Bindable 
public int getMode(){ 
    return mode; 
} 

public void setMode(int mode) { 
    this.mode = mode; 
    notifyPropertyChanged(BR.mode); 
} 
} 

뷰 모델 :

public class BasicViewViewModel extends BaseObservable { 
private final Context mContext; 
private ObservableField<DeviceModel> modelFields; 

public BasicViewViewModel(Context context){ 
    mContext = context.getApplicationContext(); 
    ApplicationBase app = ApplicationBase.getInstance(); 
    modelFields = new ObservableField<>(app.dModel); 
} 

    @Bindable 
public String getMode(){ 
    return modelFields.get().Mode; 
} 
} 

조각 :

public class BasicViewFragment extends Fragment { 
private FragmentBasicViewBinding mBinding; 
private BasicViewViewModel mViewModel; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState){ 
    mViewModel = new BasicViewViewModel(getContext()); 
    mBinding = DataBindingUtil.inflate(
      inflater, R.layout.fragment_basic_view, container, false); 
    View view = mBinding.getRoot(); 
    mBinding.setDevice(mViewModel); 
    return view; 
} 
} 

레이아웃 :

<?xml version="1.0" encoding="utf-8"?> 
<layout xmlns:android="http://schemas.android.com/apk/res/android"> 
<data> 
    <variable name="device" type="com.example.android.bluetoothcomms.BasicViewViewModel"/> 
</data> 
<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

<TextView 
    android:text="@{device.mode}" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/tvModeVal" /> 

</RelativeLayout> 
</layout> 

사용자 정의 응용 프로그램 코드 : 결국

public class ApplicationBase extends Application { 

private static ApplicationBase instance; 
public BluetoothCommsService btComms; 
public DeviceModel dModel; 


@Override 
public void onCreate(){ 
    super.onCreate(); 
    instance = this; 
    dModel = new DeviceModel(); 
    btComms = new BluetoothCommsService(); 

} 

public static ApplicationBase getInstance(){ 
    return instance; 
} 
} 

솔루션 나는 @exkoria의 조언을 따라 사용자 정의 이벤트 작성하고 보낼 EventBus를 사용 :

public class DeviceModelUpdateEvent { 

public final String fieldName; 
public final String newValue; 

public DeviceModelUpdateEvent(String field, String value){ 
    fieldName = field; 
    newValue = value; 
} 
} 

뷰에서 데이터 바인딩 업데이트를 트리거하는 처리기를 내 viewmodel에 넣습니다. 변경 사항이있을 때의 ViewModel이보기 모델의 변화를 수신하고 업데이트 할 수 있도록

@Subscribe 
public void onMessageEvent(DeviceModelUpdateEvent event){ 
    switch(event.fieldName){ 
     case "yieldLevel": 
      notifyPropertyChanged(BR.yieldLevel); 
      break; 
     case "mode": 
      notifyPropertyChanged(BR.mode); 
      break; 
     case "deviceType": 
      notifyPropertyChanged(BR.deviceType); 
      break; 
     case "firmwareVersion": 
      notifyPropertyChanged(BR.firmwareVersion); 
    } 
} 

답변

0

당신은 당신의 모델에 리스너를 추가 할 수 있습니까? 아니면 다음과 같은 이벤트 버스를 사용하는 것이 좋습니다 : https://github.com/greenrobot/EventBus.

+0

고마워요! 나는 정직하기 위해 그 도서관에 관해 완전히 잊었다. 그리고 그것은 이상하게도 나의 어떤 Google 검색에서도 나오지 않았다. – Redberry