标签: android-viewmodel

为什么在Android Studio中使用Hilt可以在ViewModel中引用Application?

我在 Android Studio 项目中使用 Hilt 作为 DI。我知道“ViewModel 绝不能引用视图、生命周期或任何可能保存对活动上下文的引用的类”。

所以可以发现A图中对于Code A有一条警告信息。

不过ViewModelComponentHilt的已经绑定了Application,你可以看看这篇文章

1: 我不知道为什么 private val appContext: Application在ViewModel中不显示警告信息,是否意味着我在使用Hilt时可以使用Applicationin ?ViewModel你可以告诉我吗?

2: BTW,private val appContext: Application显示以下信息,为什么?

构造函数参数从不用作属性

代码A

@HiltViewModel
class RecordSoundViewModel @Inject constructor(
    @ApplicationContext private val myContext: Context,    //Android Studio displays warning information
    private val appContext: Application,                   // Why doesn't it dsiplay warning information
    private val savedStateHandle: SavedStateHandle
): ViewModel()
{
     ...
}
Run Code Online (Sandbox Code Playgroud)

图片A 在此输入图像描述

android android-viewmodel dagger-hilt

5
推荐指数
1
解决办法
123
查看次数

发布或设置 MutableLiveData - 未调用观察者 onChanged

我发现了新的 android 架构组件,我想通过一个小的测试应用程序来测试这对 ViewModel / LiveData。后者有两个片段(在 a 中ViewPager),第一个创建/更新卡片列表(通过 an EditText),第二个显示所有卡片。

我的视图模型:


public class CardsScanListViewModel extends AndroidViewModel {

    private MutableLiveData> cardsLiveData = new MutableLiveData();
    private HashMap cardsMap = new HashMap();

    public CardsScanListViewModel(@NonNull Application application) {
        super(application);
    }

    public MutableLiveData> getCardsLiveData() {
        return this.cardsLiveData;
    }

    public void saveOrUpdateCard(String id) {
        if(!cardsMap.containsKey(id)) {
            cardsMap.put(id, new Card(id, new AtomicInteger(0)));
        }
        cardsMap.get(id).getCount().incrementAndGet();
        this.cardsLiveData.postValue(cardsMap);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的第二个片段:

public class CardsListFragment extends Fragment {

    CardsAdapter cardsAdapter;

    RecyclerView recyclerCardsList;

    public CardsListFragment() {}

    @Override
    public void …
Run Code Online (Sandbox Code Playgroud)

android android-fragments rx-android android-livedata android-viewmodel

4
推荐指数
1
解决办法
6275
查看次数

使用Dagger 2的ViewModelProviders,无法掌握概念

我有这样的改造服务

public interface BrandsService {
    @GET("listBrand")
    Call<List<Brand>> getBrands();
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个Repository来从这样的api获取数据

public class BrandsRepository {
    public static final String TAG = "BrandsRepository";
    MutableLiveData<List<Brand>> mutableLiveData;
    Retrofit retrofit;

    @Inject
    public BrandsRepository(Retrofit retrofit) {
        this.retrofit = retrofit;
    }

    public LiveData<List<Brand>> getListOfBrands() {
//       Retrofit retrofit = ApiManager.getAdapter();
        final BrandsService brandsService = retrofit.create(BrandsService.class);
        Log.d(TAG, "getListOfBrands: 00000000000 "+retrofit);

        mutableLiveData = new MutableLiveData<>();

        Call<List<Brand>> retrofitCall = brandsService.getBrands();
        retrofitCall.enqueue(new Callback<List<Brand>>() {
            @Override
            public void onResponse(Call<List<Brand>> call, Response<List<Brand>> response) {
                mutableLiveData.setValue(response.body());
            }

            @Override
            public void onFailure(Call<List<Brand>> call, Throwable t) …
Run Code Online (Sandbox Code Playgroud)

android retrofit dagger-2 android-viewmodel android-architecture-components

4
推荐指数
2
解决办法
3183
查看次数

从Room观察LiveData会导致PagedListAdapter刷新,ViewModel也会在方向更改时刷新数据

我正在构建一个使用ArticleBoundaryCallback初始化对API的调用并将响应存储在Room中的应用。我还使用LiveData收听该表,并在PagedListAdapter中显示项目。

问题在于,每次将新数据插入到Room(Article)表中时,整个列表都会刷新。

同样,在配置更改时,似乎再次获取了整个数据(ViewModel不保留它,RecyclerView被重新创建)。

每次插入时,RecyclerView都会跳转(如果插入的是新数据,则跳转几行;如果将新数据替换为旧数据,则跳转到开头)。

整个代码在此GitHub存储库中

我的课程是:

文章:

@Entity(tableName = "article",
    indices={@Index(value="id")})public class Article {
@PrimaryKey(autoGenerate = false)
@SerializedName("_id")
@Expose
@NonNull
private String id;
@SerializedName("web_url")
@Expose
private String webUrl;
@SerializedName("snippet")
@Expose
private String snippet;
@SerializedName("print_page")
@Expose
private String printPage;
@SerializedName("source")
@Expose
private String source;
@SerializedName("multimedia")
@Expose
@Ignore
private List<Multimedium> multimedia = null;
Run Code Online (Sandbox Code Playgroud)

第DAO条:

@Dao
public interface ArticleDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
long insert(Article article);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void update(Article... repos);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertArticles(List<Article> articles);


@Delete
void delete(Article... …
Run Code Online (Sandbox Code Playgroud)

android-livedata android-viewmodel android-paging mutablelivedata

4
推荐指数
1
解决办法
626
查看次数

没有ViewModelProviders类的情况下如何获取ViewModel?

有关过去的问题如何获取ViewModel?,以及我找到的示例,它不能解决我的情况。我没有在此发表评论的权限,因此我不得不再次询问。我没有要在所有示例和文档中使用的“ of”方法使用的ViewModelProviders类,例如

model = ViewModelProviders.of(this).get(Something.class);
Run Code Online (Sandbox Code Playgroud)

在Android Studio中,我找不到要添加为依赖项的“ android.arch.lifecycle:extensions”。当我搜索时,它说“没什么可显示”。我使用的是API27。因此,尝试使用不推荐使用的元素,我在Fragment中添加了它:

public class EventDetailsFragment extends Fragment
{
EventViewModel viewModel;

@Override
public void onActivityCreated (Bundle savedInstanceState)
{
    super.onActivityCreated(savedInstanceState);
    ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication());
    // HERE IS THE ISSUE: Seems not good practice to have to create a new ViewModelProvider every time this Fragment is created. 
    // Perhaps I should just create a singleton ViewModelProvider in the Activity or Application, 
    // so here could call getActivity().getViewModelProvider(this, factory).
    ViewModelProvider viewModelProvider = new ViewModelProvider(this, factory);
    viewModel …
Run Code Online (Sandbox Code Playgroud)

android android-viewmodel

4
推荐指数
1
解决办法
3128
查看次数

使用 ViewModel 的接口?

我目前正在根据官方文档和谷歌提供的示例应用程序(向日葵和 todo-app)将架构组件集成到我的应用程序中。我意识到这些都没有使用ViewModel接口(向日葵应用程序甚至不使用存储库接口)。

我的问题是:省略ViewModels的接口是否合理(包括优点和缺点)?

android design-patterns interface android-viewmodel android-architecture-components

4
推荐指数
1
解决办法
2440
查看次数

数据更改时LiveData不更新

我正在使用LiveData从服务器获取数据并进行观察。我的onChanged()方法只是在第一次调用,而在服务器中的数据更新时不会调用。

用户片段:

UserViewModel userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getUser().observe(this, new Observer<User>() {
    @Override
    public void onChanged(User user) {
        //Set UI
    }
});
Run Code Online (Sandbox Code Playgroud)

UserViewModel:

public class UserViewModel extends AndroidViewModel {
    private LiveData<User> user;

    public UserViewModel(Application application) {
        super(application);
        user = UserRepository.getInstance().fetchUser();
    }

    public LiveData<User> getUser() {
        return user;
    }    
}
Run Code Online (Sandbox Code Playgroud)

UserRepository:

public class UserRepository {    
    private ApiService apiService;
    private static UserRepository userRepository;

    private UserRepository() {
        apiService = RestClient.getClient().create(ApiService.class);
    }

    public synchronized static UserRepository getInstance() {
        if (userRepository == null) userRepository = …
Run Code Online (Sandbox Code Playgroud)

java android android-livedata android-viewmodel android-architecture-components

4
推荐指数
1
解决办法
2540
查看次数

从不同的 LiveData 源填充适配器

我正在使用 LiveData 并想了解它可以做什么。我想通过开关用来自不同来源的数据填充我的 RecyclerView(如果你愿意,可以使用过滤器)。

过滤适配器内的值不是一种选择。所以,我决定在我的视图模型中使用MediatorLiveData

道:

@Query("SELECT * FROM tasks WHERE completed = 0")
LiveData<List<Task>> getActiveTasksLiveData();

@Query("SELECT * FROM tasks")
LiveData<List<Task>> getAllTasksLiveData();

@Query("SELECT * FROM tasks WHERE completed = 1")
LiveData<List<Task>> getClosedTasksLiveData();
Run Code Online (Sandbox Code Playgroud)

回购:

    public LiveData<List<Task>> getActiveTasks() {
        return mTaskDao.getActiveTasksLiveData();
    }

    public LiveData<List<Task>> getAllTasks() {
        return mTaskDao.getAllTasksLiveData();
    }

    public LiveData<List<Task>> getClosedTasks() {
        return mTaskDao.getClosedTasksLiveData();
    }
Run Code Online (Sandbox Code Playgroud)

视图模型

public class MainViewModel extends AndroidViewModel {

    private final String TAG = "MainViewModel";

    private final AppDataRepository mData;

    private MediatorLiveData<List<Task>> mMediatorTasks;

    public MainViewModel(@NonNull Application application) …
Run Code Online (Sandbox Code Playgroud)

android android-recyclerview android-room android-livedata android-viewmodel

4
推荐指数
1
解决办法
1225
查看次数

当所有 EditText 完成时启用按钮

当表单中的所有字段都完成时,我想启用 AppCompatButton。

我正在使用 ViewModel 并希望使用数据绑定来启用它。

当视图上的文本更改以更新视图模型中的对象数据时,我有两种方法会触发。

我遇到的问题是当两个字段都完成时,我需要在布局上启用一个按钮以允许它们继续。

一个例子是登录,当用户名和密码字段填满时,登录按钮变为启用。

android android-databinding android-viewmodel

4
推荐指数
1
解决办法
3775
查看次数

已注册具有给定键的 SavedStateProvider

我目前正在尝试使用savedState 的新Jetpack ViewModel。

    implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-rc01'
Run Code Online (Sandbox Code Playgroud)

我正在使用 1 个活动并尝试与 2 个片段共享 1 个 ViewModel,但是当我尝试启动第二个片段时,我从标题中收到错误消息。

这就是我使用savedInstance调用ViewModel的方式:

    val repository = (activity?.application as App).getRepository()
    viewModel = activity?.run {
        ViewModelFactory(repository, this, savedInstanceState).create(MainViewModel::class.java)
    } ?: throw Exception("Invalid Activity")
Run Code Online (Sandbox Code Playgroud)

这是我的日志:

java.lang.IllegalArgumentException: SavedStateProvider with the given key is already registered
    at androidx.savedstate.SavedStateRegistry.registerSavedStateProvider(SavedStateRegistry.java:111)
    at androidx.lifecycle.SavedStateHandleController.attachToLifecycle(SavedStateHandleController.java:50)
    at androidx.lifecycle.SavedStateHandleController.create(SavedStateHandleController.java:70)
    at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:67)
    at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:84)
    at com.xxx.yyy.presentation.details.DetailsFragment.onCreate(DetailsFragment.kt:29)
    at androidx.fragment.app.Fragment.performCreate(Fragment.java:2586)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:838)
    at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1197)
    at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1080)
    at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:119)
    at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1866)
    at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
    at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
    at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
Run Code Online (Sandbox Code Playgroud)

看起来它正在尝试使用已经注册的 SavedState 并因此出现错误?我认为这就是图书馆的全部意义所在。任何人都可以帮助或指出如何使用此传递参数到 ViewModel 并使用 savedStateHandle?

android android-fragments android-viewmodel android-jetpack androidx

4
推荐指数
1
解决办法
3450
查看次数