web-dev-qa-db-fra.com

Liaison de données Android: la vue ne se met pas à jour lorsque la propriété est modifiée

permettez-moi de commencer par montrer le code: 

build.gradle (module):

Android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
dataBinding {
    enabled = true
}
defaultConfig {
    applicationId "com.example.oryaa.basecalculator"
    minSdkVersion 15
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
    }
}


dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.Android.support:appcompat-v7:24.2.1'
compile 'com.google.Android.gms:play-services-appindexing:8.1.0'

activity_main.xml:

<data>
    <import type="Android.view.View" />
    <variable
        name="baseCalcModel"
        type="com.example.oryaa.basecalculator.BaseCalcModel">
    </variable>
</data>  <TextView
        Android:id="@+id/resultOutput"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_below="@id/resultTextView"
        Android:textColor="@color/DarkBlue"
        Android:text="@{baseCalcModel.calcResult}"
        Android:textSize="32dp" />

MainActicity.Java:

public class MainActivity extends AppCompatActivity {

EditText userInput = null;
TextView resultTV = null;
Spinner fromBaseSpinner = null;
Spinner toBaseSpinner = null;
ArrayList<String> spinnerArray = new ArrayList<>();
String _allowedChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String _onlyOnceChar = "-+*/";
BaseCalcModel baseCalcModel = new BaseCalcModel();

/**
 * ATTENTION: This was auto-generated to implement the App Indexing API.
 * See https://g.co/AppIndexing/AndroidStudio for more information.
 */
private GoogleApiClient client;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.setBaseCalcModel(this.baseCalcModel);
    this.resultTV = (TextView) this.findViewById(R.id.resultOutput);
    this.fromBaseSpinner = (Spinner) findViewById(R.id.fromBaseSpinner);
    this.toBaseSpinner = (Spinner) findViewById(R.id.toBaseSpinner);
    this.userInput = (EditText) findViewById(R.id.userInput);
    SetupUI();
    baseCalcModel.setCalcResult("test");

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}

BaseCalcModel.Java:

ublic class BaseCalcModel extends BaseObservable {


public String calcResult;
public BaseView firstNumView;
public BaseView secondNumView;
public BaseView resultNumView;
public int firstNumBase;
public int secondNumBase;
public int resultNumBase;
public String error;


@Bindable
String getCalcResult() {
    return calcResult;
}

@Bindable
public BaseView getFirstNumView() {
    return firstNumView;
}

@Bindable
public BaseView getSecondNumView() {
    return secondNumView;
}

@Bindable
public BaseView getResultNumView() {
    return this.resultNumView;
}

@Bindable
public int getFirstNumBase() {
    return this.firstNumBase;
}

@Bindable
public int getSecondNumBase() {
    return this.secondNumBase;
}

@Bindable
public int getResultNumBase() {
    return this.resultNumBase;
}

@Bindable
public String getError() {
    return this.error;
}

public void setCalcResult(String calcResult) {
    this.calcResult = calcResult;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.calcResult);
}

public void setFirstNumView(BaseView firstNumView) {
    this.firstNumView = firstNumView;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.firstNumView);
}

public void setSecondNumView(BaseView secondNumView) {
    this.secondNumView = secondNumView;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.secondNumView);
}

public void setResultNumView(BaseView resultNumView) {
    this.resultNumView = resultNumView;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.resultNumView);
}

public void setFirstNumBase(int firstNumBase) {
    this.firstNumBase = firstNumBase;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.firstNumBase);
}

public void setSecondNumBase(int secondNumBase) {
    this.secondNumBase = secondNumBase;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.secondNumBase);
}

public void setResultNumBase(int resultNumBase) {
    this.resultNumBase = resultNumBase;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.resultNumBase);
}

public void setError(String error) {
    this.error = error;
    notifyPropertyChanged(com.example.oryaa.basecalculator.BR.error);
}


public BaseCalcModel() {
    firstNumView = new BaseView();
    secondNumView = new BaseView();
    resultNumView = new BaseView();
    firstNumBase = 0;
    secondNumBase = 0;
    resultNumBase = 0;
    calcResult = "";
    error = "";
}

public BaseCalcModel(BaseView firstNumView, BaseView secondNumView, BaseView resultNumView,
                     int firstNumBase, int secondNumBase, int resultNumBase, String clcResult,
                     String error) {
    this.firstNumView = firstNumView;
    this.secondNumView = secondNumView;
    this.resultNumView = resultNumView;
    this.firstNumBase = firstNumBase;
    this.secondNumBase = secondNumBase;
    this.resultNumBase = resultNumBase;
    this.calcResult = clcResult;
    this.error = error;
}

 enter image description here

J'essaie de faire une simple liaison de données, mais mon point de vue ne se met pas à jour une fois la propriété changée. comme vous pouvez le voir sur l'image, mon code arrive à:

            notifyPropertyChanged(com.example.oryaa.basecalculator.BR.calcResult);

mais la vue est mise à jour uniquement au démarrage de l'application ou lorsque je fais pivoter mon téléphone verticalement ou horizontalement, ou inversement.

Où est mon problème? 

Merci beaucoup, .__ Ou Yaacov

8
user5190190

Vous devez appeler executePendingBindings() pour mettre à jour immédiatement la valeur de liaison dans la vue:

Quand une variable ou un observable change, la liaison sera programmée pour changer avant la prochaine image. Cependant, il y a des moments où la liaison doit être exécutée immédiatement. Pour forcer l'exécution, utilisez la méthode executePendingBindings ().

Regardez Advanced Binding chapitre pour plus d'informations

3
XIII-th

J'ai eu un problème similaire lorsque j'ai eu besoin d'actualiser les vues après un événement, avec mes objets variables non observables.

binding?.invalidateAll()

J'espère que ça aide.

3
uan
  • Rendez vos champs de classe de modèle privés.
  • Changer getCalcResult() devrait être public.
  • BaseView devrait être extensible BaseObservable
  • Si vous ne modifiez pas la valeur du modèle de manière dynamique. Dans ce cas, vous n'avez pas besoin de rendre chaque accesseur @Bindable. Vous pouvez enlever ça. Et aussi supprimer notifyPropertyChanged(). Si vous devez modifier les valeurs du modèle de manière dynamique, utilisez l'attribut @Bindable.

Tu es prêt.

public class BaseCalcModel extends BaseObservable {
private String calcResult;
private BaseView firstNumView;
private BaseView secondNumView;
private BaseView resultNumView;
private int firstNumBase;
private int secondNumBase;
private int resultNumBase;
private String error;

public String getCalcResult() {
    return calcResult;
}

public void setCalcResult(String calcResult) {
    this.calcResult = calcResult;
}

public BaseView getFirstNumView() {
    return firstNumView;
}

public void setFirstNumView(BaseView firstNumView) {
    this.firstNumView = firstNumView;
}

public BaseView getSecondNumView() {
    return secondNumView;
}

public void setSecondNumView(BaseView secondNumView) {
    this.secondNumView = secondNumView;
}

public BaseView getResultNumView() {
    return resultNumView;
}

public void setResultNumView(BaseView resultNumView) {
    this.resultNumView = resultNumView;
}

public int getFirstNumBase() {
    return firstNumBase;
}

public void setFirstNumBase(int firstNumBase) {
    this.firstNumBase = firstNumBase;
}

public int getSecondNumBase() {
    return secondNumBase;
}

public void setSecondNumBase(int secondNumBase) {
    this.secondNumBase = secondNumBase;
}

public int getResultNumBase() {
    return resultNumBase;
}

public void setResultNumBase(int resultNumBase) {
    this.resultNumBase = resultNumBase;
}

public String getError() {
    return error;
}

public void setError(String error) {
    this.error = error;
}

}

0
Khemraj

Si vous rencontrez ce problème avec LiveData, vous avez peut-être oublié d’ajouter binding.setLifecycleOwner(lifecycleOwner).

0
dgngulcan