2017-05-24 31 views
2

我正在關注此tutorial以瞭解ViewModel和LiveData。在我的情況下,而不是從網絡獲取數據,我只是簡單地生成隨機字符串按鈕單擊並嘗試更新textview。問題在於,當按鈕單擊更改數據時,textview不會更新,但只有在方向切換時纔會更新。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() 
    } 
}); 
    } 
} 

ViewModel類

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() 

更換

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

仍然得到同樣的行爲。 –

2

我在某種程度上能夠通過使用替代LiveData MutableLiveData解決這個問題。 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實例!你不應該那樣做。如果你這樣做,所有以前的觀察者都會被忽略。

在這種情況下,你可以在你的視圖模型取代你setUSer(LiveData<User>)方法setUser(User u)(以用戶而非LiveData),然後做user.setValue(u)裏面。

當然,必須初始化LiveData成員在你的ViewModel類,像這樣:

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 
    } 
} 

活動課

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() 
    } 
}); 
    } 
}