在我旋转屏幕之前,LiveData 不会加载到片段中
Posted
技术标签:
【中文标题】在我旋转屏幕之前,LiveData 不会加载到片段中【英文标题】:LiveData doesn't load in fragmet until I rotate the screen 【发布时间】:2021-10-01 10:13:22 【问题描述】:我有一个片段来展示我已经从实时数据库 (firebase) 中检索到的新闻。
我使用了liveData
和viewModel
,我试图观察片段中的数据,但数据不会加载到recyclerView
,直到我旋转屏幕,然后它呈现在片段上。
我不知道我可以做些什么来让它在我打开片段时可见?
Fragment.java
public class GeneralFragment extends Fragment implements DataLoadListener
public NewsAdapter adapter;
private FragmentGeneralBinding binding;
public NewsViewModel newsViewModel;
Context mContext;
@Override
public void onAttach(Context context)
super.onAttach(context);
mContext = context;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_general, container, false);
View view = binding.getRoot();
return view;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
newsViewModel = ViewModelProviders.of(getActivity()).get(NewsViewModel.class);
newsViewModel.init(mContext);
adapter = new NewsAdapter(mContext, newsViewModel.getData().getValue());
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getContext(), 1);
binding.recyclerView.setLayoutManager(layoutManager);
binding.recyclerView.addItemDecoration(new GridSpacingItemDecoration(1, dpToPx(10), true));
binding.recyclerView.setItemAnimator(new DefaultItemAnimator());
Log.d("ADAPTER", "item count: "+adapter.getItemCount());
adapter.notifyDataSetChanged();
Log.d("ADAPTER", "item count: "+adapter.getItemCount());
binding.recyclerView.setAdapter(adapter);
private int dpToPx(int dp)
Resources r = getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
@Override
public void onNewsLoad()
newsViewModel.getData().observe(getViewLifecycleOwner(), new Observer<ArrayList<NewsModel>>()
@Override
public void onChanged(ArrayList<NewsModel> newsModels)
adapter.notifyDataSetChanged();
);
NewsViewModel.java
public class NewsViewModel extends ViewModel
MutableLiveData<ArrayList<NewsModel>> news;
public void init(Context context)
if(news != null)
return;
news = Repo.getInstance(context).getData();
public LiveData<ArrayList<NewsModel>> getData()
return news;
Repo.java
public class Repo
private static final String TAG = "Tracing Data";
static Repo instance;
private ArrayList<NewsModel> newsModels;
static Context mContext;
static DataLoadListener dataLoadListener;
public static Repo getInstance(Context context)
if (instance == null)
instance = new Repo();
mContext = context;
dataLoadListener = (DataLoadListener) mContext;
return instance;
public MutableLiveData<ArrayList<NewsModel>> getData()
newsModels = new ArrayList<>();
RetrieveAllData();
MutableLiveData<ArrayList<NewsModel>> newsModel = new MutableLiveData<>();
newsModel.setValue(newsModels);
return newsModel;
private void RetrieveAllData()
Log.d(TAG, "before RetrieveAllData: "+newsModels.size());
FirebaseDatabase database = FirebaseDatabase.getInstance();
database.getReference("news").orderByChild("date").addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
if (snapshot.exists())
newsModels.clear();
for (DataSnapshot postSnapshot : snapshot.getChildren())
newsModels.add(0, postSnapshot.getValue(NewsModel.class));
dataLoadListener.onNewsLoad();
Log.d(TAG, "after RetrieveAllData: "+newsModels.size());
@Override
public void onCancelled(@NonNull DatabaseError error)
);
DataLoadListener.java
public interface DataLoadListener
void onNewsLoad();
【问题讨论】:
【参考方案1】:我正在尝试观察片段中的数据,但在我旋转屏幕之前,数据不会加载到 recyclView 中
因为onViewCreated()
再次被调用,并且适配器数据设置为adapter = new NewsAdapter(mContext, newsViewModel.getData().getValue())
中的 ViewModel 的持久数据(不受配置更改/旋转的影响)
数据不会在初始启动时加载,因为片段的回调 onNewsLoad()
没有被触发,因为您传递给 ViewModel
的上下文与实现 @987654325 的当前片段不同@。
因此,要解决此问题,您需要替换:
newsViewModel.init(mContext); // mContex isn't considered as a `DataLoadListener`
与:
newsViewModel.init(this); // this here refers to the `GeneralFragment` as a `DataLoadListener`
【讨论】:
以上是关于在我旋转屏幕之前,LiveData 不会加载到片段中的主要内容,如果未能解决你的问题,请参考以下文章