2017-05-24 12 views
2

ViewModelとLiveDataを学ぶために私はtutorialに従っています。私の場合は、ネットワークからデータを取得するのではなく、単にボタンをクリックしてランダムな文字列を生成し、テキストビューを更新しようとしています。問題は、ボタンクリックでデータが変更されたときにテキストビューが更新されず、方向が切り替わったときにのみ更新される点です。ボタンをクリックするとAndroid ViewModel LiveDataアップデートビュー

アクティビティクラス(延びLifecycleActivity)

public class PScreen extends BaseActivity { 
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) { 

super.onCreate(savedInstanceState); 
setContentView(R.layout.places_screen); 

final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class); 
viewModel.init(); 

viewModel.getUser().observe(this, new Observer<User>() { 
    @Override public void onChanged(@Nullable User user) { 
    ((TextView) findViewById(R.id.name)).setText(user.getName()); 
    } 
}); 

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { 
    @Override public void onClick(View v) { 
    final MutableLiveData<User> data = new MutableLiveData<>(); 
    User user = new User(); 
    user.setName(String.valueOf(Math.random() * 1000)); 
    data.postValue(user); 
    viewModel.setUser(data); // Why it does not call observe() 
    } 
}); 
    } 
} 

ビューモデルクラス

package timsina.prabin.tripoptimizer.model; 

import android.arch.lifecycle.LiveData; 
import android.arch.lifecycle.ViewModel; 

public class UserModel extends ViewModel { 
    private LiveData<User> user; 

    public void init() { 
    if (this.getUser() != null) { 
     return; 
    } 
    this.user = new LiveData<User>() { 
     @Override protected void setValue(User value) { 
     value.setName("Fresh New Name"); 
     super.setValue(value); 
     } 
    }; 
    } 

    public LiveData<User> getUser() { 
    return user; 
    } 

    public void setUser(LiveData<User> user) { 
    this.user = user; 
    } 
} 

答えて

0

、コードの行を交換しようとあなたがUserModel内部のオブジェクトへの参照を置き換える

data.postValue(user); 
viewModel.setUser(data); // Why it does not call observe() 

は私が何とかMutableLiveData代わりのLiveDataを使用することによってこの問題を解決することができた

viewModel.setUser(data); // Why it does not call observe() 
data.postValue(user); 
+0

はまだ同じ動作を得ます。 –

2

に交換してください。 Modelクラス

private MutableLiveData<User> user2; 
    public void init() { 
    if (user2 == null) { 
     user2 = new MutableLiveData<>(); 
    } 
} 

    public MutableLiveData<User> getUser2() { 
    return user2; 
    } 

    public void setUser2(final User user) { 
    user2.postValue(user); 
    } 

活動

viewModel.getUser2().observe(this, new Observer<User>() { 
     @Override public void onChanged(@Nullable User user) { 
     ((TextView) findViewById(R.id.name)).setText(user.getName()); 
     } 
    }); 

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { 
     @Override public void onClick(View v) { 
     User user = new User(); 
     viewModel.getUser().postValue(user); 
     } 
    }); 
3
あなたは新しいLiveDataインスタンスごとに作成している

!あなたはそれをするべきではありません。そうすれば、以前のオブザーバーはすべて無視されます。あなたが(代わりにLiveDataのユーザーを取る)setUser(User u)にあなたのViewModelにごsetUSer(LiveData<User>)方法を交換して、その中user.setValue(u)を行うことができます。この場合

。もちろん

、このように、あなたのViewModelクラスでLiveDataメンバーを初期化する必要があります:それは、既存のオブザーバーに通知しますので、

final private LiveData<User> user = new MutableLiveData<>(); 

それは、その後動作します。

0

上記の@niquecoのようにコードを変更して、setUser()メソッド内に更新されたメソッドを設定し、アクティビティのonclick()リスナを変更して新しいユーザーデータ情報のみを送信してください。他の作品は、LiveDataが役立ちます。

public class UserModel extends ViewModel { 
    private LiveData<User> user; 

    public void init() { 
    if (this.getUser() != null) { 
     return; 
    } 
    this.user = new LiveData<User>() { 
     @Override protected void setValue(User value) { 
     value.setName("Fresh New Name"); 
     super.setValue(value); 
     } 
    }; 
    } 

    public LiveData<User> getUser() { 
    return user; 
    } 

    public void setUser(LiveData<User> user) { 
    this.user.setValue(user); //the live data will help u push data 
    } 
} 

Activityクラス

public class PScreen extends BaseActivity { 
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) { 

super.onCreate(savedInstanceState); 
setContentView(R.layout.places_screen); 

final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class); 
viewModel.init(); 

viewModel.getUser().observe(this, new Observer<User>() { 
    @Override public void onChanged(@Nullable User user) { 
    ((TextView) findViewById(R.id.name)).setText(user.getName()); 
    } 
}); 

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { 
    @Override public void onClick(View v) { 
    //final MutableLiveData<User> data = new MutableLiveData<>(); 
    User user = new User(); 
    user.setName(String.valueOf(Math.random() * 1000)); 
    //data.postValue(user); 
    viewModel.setUser(user); // Why it does not call observe() 
    } 
}); 
    } 
} 
関連する問題