如何解决使用 RxJava3
概述 我正在尽力遵循 MVVM 模式。在我的数据模型中,我有一个实体“语言”及其通过存储库访问的相应 DAO。反过来,这个存储库提供我的视图模型,并通过我的片段中的工厂进行实例化。或者,从另一个方面来说,我的片段 -> viewmodelFactory -> viewmodel -> Repository -> DAO -> Entity
我对 ArrayAdapter 在何处“适合”MVVM 模式感到有些困惑。该特定片段旨在显示一系列字段(姓名、语言等),用作应用内的“个人资料”创建页面。
问题: 我试图用语言列表填充微调器,这样当微调器中的一种语言被选择时,相应的值实际上会在软件中使用(想想:文本值对)。我真的不知道我在做什么,但我正在尽可能快地失败。目前,我在片段 onViewCreated 方法中遇到以下错误:
Android Studio 错误:“无法解析‘Observable’中的‘observe’方法”
语言实体
@Entity
public class languages {
@PrimaryKey(autoGenerate = true)
@NonNull
public Long langNo;
public String langDesc;
@ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
public Long langUpdatedDate;
@ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
public Long langCreatedDate;
}
DAO
@Dao
public interface languagesDAO {
@Update
Completable update(languages language);
@Insert
Completable insert(languages language);
@Delete
Completable delete(languages language);
//for array deletion
@Delete
Completable delete(languages... language);
//Queries
@Query("SELECT * FROM languages;")
Single<List<languages>> getLanguages();
}
存储库
public class newProfileRepository {
private final syllableDB m_db;
private static newProfileRepository s_Instance;
private usersDAO u_dao;
private languagesDAO l_dao;
private usersXlanguagesDAO uxl_dao;
public newProfileRepository(final syllableDB db){
m_db = db;
u_dao = m_db.usersDao();
l_dao = m_db.languagesDAO();
uxl_dao = m_db.usersXlanguagesDAO();
}
public static newProfileRepository getInstance(final syllableDB db) {
if (s_Instance == null) {
synchronized (newProfileRepository.class) {
if (s_Instance == null) {
s_Instance = new newProfileRepository(db);
}
}
}
return s_Instance;
}
public Single<List<languages>> getLanguages(){
return l_dao.getLanguages();
}
//...
}
SpinLangAdapter
public class SpinLangAdapter extends ArrayAdapter<language> {
private Context context;
private ArrayList<language> tvPairs = new ArrayList<>();
private List<languages> langs;
private newProfileRepository newP_repo;
private syllableDB db;
public SpinLangAdapter(Context context,int textViewResourceId,List<language> list){
super(context,textViewResourceId);
this.context = context;
this.tvPairs = new ArrayList<language>(list);
}
//This isn't used as I'm not even getting this far...
public void setLangs(List<languages> newLangs){
langs = newLangs;
notifyDataSetChanged();
}
/* @Override
public int getCount(){
return tvPairs.size();
}
@Override
public language getItem(int position){
return tvPairs.get(position);
}*/
@Override
public long getItemId(int position){
return position;
}
//SO Link: https://stackoverflow.com/questions/1625249/android-how-to-bind-spinner-to-custom-object-list
//again,not used (yet)
/*@Override
public View getView(int position,View convertView,ViewGroup parent) {
TextView label = (TextView) super.getView(position,convertView,parent);
label.setTextColor(Color.BLACK);
label.setText(tvPairs.get(position).getLangDesc());
return label;
}*/
}
视图模型
public class createNewProfileviewmodel extends Androidviewmodel {
private static final String QUERY_KEY = "QUERY";
private final newProfileRepository m_Repository;
private Single<List<languages>> m_Langs;
public createNewProfileviewmodel(Application application,newProfileRepository newProfileRepo) {
super(application);
m_Repository = newProfileRepo;
m_Langs = m_Repository.getLanguages();
}
public Observable<List<languages>> getLangListObservable(){
Single<List<languages>> items = m_Repository.getLanguages();
items.flattenAsObservable(new Function<List<languages>,Iterable<?>>() {
@Override
public Iterable<?> apply(List<languages> languages) throws Throwable {
return languages;
}
})
.toList();
return null;
}
}
片段
public class createNewProfileFragment extends Fragment implements View.OnTouchListener,View.OnClickListener {
private static final String LOG_TAG = com.electricbamboo.syllable.ui.createNewProfileFragment.class.getSimpleName();
private CreateNewProfileBinding mBinding;
private Context m_Context;
private profileService PCS;
private SpinLangAdapter nativeSLAdapter;
private SpinLangAdapter targetSLAdapter;
private List<language> spinnerListLangs;
private Float tmpFZero=null;
private Long tmpNativeLangNo = 0L;
private ArrayList<Long> tmpTargetLangNos = new ArrayList<>();
public createNewProfileFragment(){}
@Override
public void onAttach(Context context) {
super.onAttach(context);
m_Context = context;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
Log.d(LOG_TAG,"Starting New Profile Creation");
mBinding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.create_new_profile,container,false);
return mBinding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view,@Nullable Bundle savedInstanceState){
newProfileviewmodelFactory factory = new newProfileviewmodelFactory(requireActivity().getApplication());
final createNewProfileviewmodel model = new viewmodelProvider(this,factory).get(createNewProfileviewmodel.class);
mBinding.setLifecycleOwner(getViewLifecycleOwner());
nativeSLAdapter = new SpinLangAdapter(m_Context,android.R.layout.simple_spinner_dropdown_item,spinnerListLangs);
mBinding.spCreateNativeLang.setAdapter(nativeSLAdapter);
targetSLAdapter = new SpinLangAdapter(m_Context,spinnerListLangs);
mBinding.spCreateTargetLang.setAdapter(targetSLAdapter);
// Doesn't compile,error thrown here ("Cannot resolve method 'observe' in 'Observable'")
model.getLangListObservable().observe(this,new Observer<List<languages>>(){
@Override
public void onChanged(@Nullable final List<languages> langs){
for(languages l : langs){
language tmpLang = null;
tmpLang.setLangNo(l.langNo);
tmpLang.setLangDesc(l.langDesc);
spinnerListLangs.add(tmpLang);
}
targetSLAdapter.notifyDataSetChanged();
nativeSLAdapter.notifyDataSetChanged();
}
});
mBinding.spCreateNativeLang.setonItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView,View view,int position,long l) {
language language = nativeSLAdapter.getItem(position);
tmpNativeLangNo = language.getLangNo();
}
@Override
public void onnothingSelected(AdapterView<?> adapterView) {}
});
mBinding.spCreateTargetLang.setonItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView,long l) {
language language = targetSLAdapter.getItem(position);
tmpTargetLangNos.add(language.getLangNo());
}
@Override
public void onnothingSelected(AdapterView<?> adapterView) {}
});
subscribetoModel(model);
}
private void subscribetoModel(final createNewProfileviewmodel model){
//Fairly certain SOMETHING is supposed to go here,just unsure as to what
}
//...omitting onClick,onTouch,onStart,onPause,onResume,etc.
语言课 不要与语言混淆!
之所以存在,是因为我认为使用扩展 LiveData 而不是扩展的东西可能更容易
一个 RxJava Single。基于此处提供的答案:When to use RxJava in Android and when to use LiveData from Android Architectural Components?
(看看 kzotin 的回应)。这是我的尝试。
public class language extends LiveData {
private Long langNo;
private String langDesc;
//Getters
public Long getLangNo(){
return langNo;
}
public String getLangDesc(){
return langDesc;
}
//Setters
public void setLangNo(Long langNo){
this.langNo = langNo;
}
public void setLangDesc(String langDesc){
this.langDesc = langDesc;
}
}
我的尝试
我真的尝试引入这里介绍的文本值对功能: Populate Spinner from LiveData (Room Database) (这让我摸不着头脑,为什么“观察”会导致问题)。
使用此处介绍的 Observable 机制: Transform a Single<List<Item>> to an Observable<Item>?
...以及这里的 ID 内容(我已经评论了很多来自接下来两个链接的代码,因为我什至没有走那么远): Android: How to bind spinner to custom object list? 和 Android - configure Spinner to use array
通常困扰我的问题是我无法遍历带有 for-each 循环的 Single 对象,因为“foreach 未为 RxJava...Single 定义”(或类似的东西)当我将“语言”对象列表转换为“语言”对象列表。
我以为我可以将语言对象作为 Singles 检索,然后在 .map 或 .flatMap 函数中将它们添加到我的 onObservable 列表中,但这让我来到这里。
问题
-
对于 MVVM 模式,我选择在哪里访问我的存储库和处理 Spinner 的初始化是否合理?我想确保我正在使用该框架,而不是反对它,但我不知道我在做什么,并且使用 RxJava,感觉很好。我在想,如果我对如何更好地组织代码有一些指导,那么也许它可以阻止我尝试做一些愚蠢的事情。
-
我应该尝试让“中级”“language.java”类工作,还是完全放弃它?换句话说,我是否应该不担心将 RxJava 转换为 LiveData 可能有什么优势(或者我认为我理解的是什么)?好像我误解了一些东西,它混淆了我的代码,让我的生活变得更加艰难。
-
我应该怎样这样做?
-
我应该在我的 subscribetoModel 中做什么?我读过应该为服务保留业务逻辑。因此,到目前为止,在我看来,存储库应该负责传递计算内容,但我对如何对“填充”逻辑进行分类有点模糊,因此犹豫是否对片段进行任何类型的操作等级。然而,这让我想知道“好吧,那应该去那里做什么??”
非常感谢您提供的任何线索。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。