簡體   English   中英

單擊按鈕時的Android ViewModel LiveData更新視圖

[英]Android ViewModel LiveData update view on button click

我正在學習本教程以學習ViewModel和LiveData。 在我的情況下,我只是在按鈕點擊時生成隨機字符串並嘗試更新文本視圖,而不是從網絡獲取數據。 問題是當按鈕單擊更改數據時,textview不會更新,但只有在切換方向時才會更新。

活動類(擴展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;
  }
}

您每次都在創建一個新的LiveData實例! 你不應該這樣做。 如果你這樣做,所有以前的觀察者將被忽略。

在這種情況下,您可以將ViewModel上的setUSer(LiveData<User>)方法替換為setUser(User u) (取用用戶而不是LiveData),然后在其中執行user.setValue(u)

當然,必須在ViewModel類中初始化LiveData成員,如下所示:

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

它會工作,因為它會通知現有的觀察員。

我能以某種方式通過使用MutableLiveData而不是LiveData來解決這個問題。 模型類

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

您替換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);

嘗試修改你提到的@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() 
  }
});
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM