Android CursorLoader以特定/特定顺序动态添加视图
这可能很奇怪,但我在Android中使用多个游标加载程序来执行多个查询,在onLoadFinished()中,我根据游标结果(如游标不为null)动态向布局中添加TextView和ListView等视图。我确实得到了准确的结果,但是因为我使用的是AsyncTaskLoader(CursorLoader),所以光标结果不会同时出现,并且结果不会以正确的顺序添加。我以前使用了静态布局,在索引处添加了视图,并根据结果查看了view.setVisibility(view.go),但它太多太混乱了,因为我有32个视图。另外,这看起来很奇怪,因为我认为用户不希望看到所有这些视图都消失,并根据AsyncTaskLoader结果上下移动。 我怎样才能在没有一堆布尔变量的情况下以我想要的正确顺序获取视图?我调查了LayoutFlater,但这也需要索引,但我不确定这是否会对我有所帮助。对于我来说,索引的问题在于,在cursorloader ID 1中:Android CursorLoader以特定/特定顺序动态添加视图,android,android-asynctask,android-view,android-cursorloader,Android,Android Asynctask,Android View,Android Cursorloader,这可能很奇怪,但我在Android中使用多个游标加载程序来执行多个查询,在onLoadFinished()中,我根据游标结果(如游标不为null)动态向布局中添加TextView和ListView等视图。我确实得到了准确的结果,但是因为我使用的是AsyncTaskLoader(CursorLoader),所以光标结果不会同时出现,并且结果不会以正确的顺序添加。我以前使用了静态布局,在索引处添加了视图,并根据结果查看了view.setVisibility(view.go),但它太多太混乱了,因为我
view.addView(v, 1);
view.addView(v, 2);
在ID为2的游标加载程序完成以下操作之前,可能无法执行:
view.addView(v, 3);
view.addView(v, 4);
如果游标加载程序ID1没有执行,ID2没有执行,那么就缺少空间,如果我使用静态XML视图而不动态添加它们,我必须执行大量的view.setVisibility(view.GONE)
在代码中,我目前正在做类似的事情:
@Override
public void onLoadFinished(android.support.v4.content.Loader<Cursor> cursorLoader, Cursor cursor) {
switch (cursorLoader.getId())
{
case 0:
if (cursor != null && cursor.moveToFirst()) {
..
title = new TextView(this);
...
mainLinearLayout.addView(title, 1);
}
break;
case 1:
if (cursor != null && cursor.moveToFirst()) {
..
title2 = new TextView(this);
mainLinearLayout.addView(title2, 2);
break;
default:
...
}
@覆盖
public void onLoadFinished(android.support.v4.content.Loader cursorLoader,Cursor Cursor){
开关(cursorLoader.getId())
{
案例0:
if(cursor!=null&&cursor.moveToFirst()){
..
title=新文本视图(此);
...
mainLinearLayout.addView(标题1);
}
打破
案例1:
if(cursor!=null&&cursor.moveToFirst()){
..
title2=新文本视图(本);
mainLinearLayout.addView(标题2,2);
打破
违约:
...
}
}
我还在网上的某个地方读到,如果你想在后台线程上执行查询并让它们按一定顺序完成,最好使用服务而不是游标加载程序,但我在其他任何地方都没有听到这个建议,也没有看到任何在服务中执行查询的示例。它们都使用游标加载程序。这个建议一定是真的吗我并不粗略
顺便说一句,我使用的是CursorLoader实现,没有提供任何内容提供者
我怎样才能以正确的顺序获取视图?我希望它们在没有
有一堆布尔变量
您确实需要某种状态控件才能使视图按顺序显示。我会将视图构造/添加委托给一个控件类,该控件类将包含生成正确视图所需的所有信息,并且无论装载机如何完成其工作,都能按正确的顺序显示
public class ViewDispatcher {
public SparseArray<Status> mLoadStatuses = new SparseArray<Status>();
public SparseArray<Cursor> mDataCursors = new SparseArray<Cursor>();
// you'll call this method for each of the loaders, in the order they should be. The ids should be incremental
public void registerLoader(int loaderId) {
mLoadStatuses.put(loaderId, Status.INITIAL);
}
// called when one of the loaders finishes its job
public void onLoadComplete(int loaderId, Cursor data) {
mDataCursors.put(loaderId, data);
boolean current = true;
mLoadStatuses.put(loaderId, Status.LOADED);
if (loaderId == firstLoaderId) {
// the first loader it's done and we should start the view creation right away
buildView(loaderId, mainLayout, true);
mLoadStatuses.put(loaderId, data, Status.FULLY_BUILT);
} else {
// implement a priority system, a view construction will be triggered ONLY
// if the previous loader has finished loading data and its view is in place
// I'm assuming that the Loaders have consecutive ids
if (mLoadStatuses.get(loaderId - 1) != null && mLoadStatuses.get(loaderId - 1) == Status.FULLY_BUILT) {
buildView(loaderId, data, mainLayout, true);
mLoadStatuses.put(loaderId, Status.FULLY_BUILT);
} else {
current = false;
}
}
// we'll also need to implement a buddy system. When a loader is done loading and its view
// is created we must check to see if we don't have other loaders after this current one that have finished loading
// but couldn't construct their view because this current loader didn't finished at that moment
// get the next loader
int next = loaderId + 1;
while(current && next < totalNumberOfLoaders && mLoadStatuses.get(next) == Status.LOADED) {
// continue to build views
buildView(next, mDataCursors.get(loaderId), mainLayout, true);
mLoadStatuses.put(next, Status.FULLY_BUILT);
next++;
}
}
// this will build the appropriate view, and optionally attach it
public void buildView(int loaderId, Cursor data, view mainLayout, boolean attach) {
// build the view for this specific Loader
}
}
public enum Status {
INITIAL, LOADED, FULLY_BUILT
}
公共类ViewDispatcher{
public SparseArray mloadstatus=新SparseArray();
public SparseArray mDataCursors=新SparseArray();
//您将按照加载程序的顺序为每个加载程序调用此方法
公共无效注册表加载程序(int-loaderId){
mLoadStatuses.put(loaderId,Status.INITIAL);
}
//当其中一个装载机完成其工作时调用
public void onLoadComplete(int-loaderId,游标数据){
mDataCursors.put(loaderId,数据);
布尔电流=真;
mLoadStatuses.put(loaderId,Status.LOADED);
if(loaderId==firstLoaderId){
//第一个加载程序已经完成,我们应该立即开始视图创建
构建视图(loaderId,Main Layout,true);
mLoadStatuses.put(loaderId、数据、状态。完全构建);
}否则{
//实施优先级系统时,仅会触发视图构造
//如果上一个加载程序已完成加载数据,并且其视图已就位
//我假设装载机有连续的ID
if(mLoadStatuses.get(loaderId-1)!=null&&mLoadStatuses.get(loaderId-1)==Status.FULLY_-builded){
buildView(loaderId、数据、主布局、true);
mLoadStatuses.put(loaderId,Status.FULLY_builded);
}否则{
电流=假;
}
}
//我们还需要实现一个伙伴系统
//我们必须检查在当前加载程序完成加载后是否没有其他加载程序
//但是无法构建他们的视图,因为当前加载程序当时没有完成
//获取下一个加载器
int next=loaderId+1;
while(current&&next
我希望我没有遗漏一些明显的东西,因为我在没有任何测试的情况下编写了它。要使用它,首先要按照需要的顺序为所有加载程序调用registerLoader()
方法,并在LoaderCallbacks
调用viewspatcher.onLoadComplete()
的call中调用viewspatcher.onLoadComplete()
我还在网上的某个地方读到,使用服务更好
而不是诅咒