我在下面的代码中编写了简单的Loader
,我希望将数据添加到List
,并且我的RecyclerView适配器知道通过使用notifyDataSetChanged()
刷新列表
我的装载机课程:
public class StringLoader extends AsyncTaskLoader<List<RobotViewModel>> {
private List<RobotViewModel> cache;
private static List<RobotViewModel> model;
public StringLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
if (cache == null) {
forceLoad();
} else {
super.deliverResult(cache);
}
}
@Override
public List<RobotViewModel> loadInBackground() {
Log.e("LOAD......... ", "new");
model = new ArrayList<>();
return model;
}
public void addCommand() {
RobotViewModel temp = new RobotViewModel();
temp.setMessage("hello");
temp.setMessageType(SV.RobotMessageType.SENT_BY_ROBOT.ordinal());
model.add(temp);
forceLoad();
}
@Override
public void deliverResult(List<RobotViewModel> data) {
cache = data;
super.deliverResult(data);
}
}
我使用活动中的addCommand()
方法:
public void clickOnSendCommand() {
loader.addCommand();
adapter.notifyDataSetChanged();
}
我的活动和实现适配器和加载器:
public class ActivityRegister extends BaseActivities {
private RobotMessagesAdapter adapter;
private StringLoader loader;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
ActivityRegisterPresenter presenter = new ActivityRegisterPresenter(this);
ActivityRegisterViewModel viewModel = new ActivityRegisterViewModel();
binding.setViewModel(viewModel);
binding.setPresenter(presenter);
List<RobotViewModel> model = new ArrayList<>();
adapter = new RobotMessagesAdapter(this, model);
binding.registerRobot.setAdapter(adapter);
loader = (StringLoader) getSupportLoaderManager().initLoader(R.id.string_loader_id, null, loaderCallbacks);
}
private LoaderManager.LoaderCallbacks<List<RobotViewModel>> loaderCallbacks = new LoaderManager.LoaderCallbacks<List<RobotViewModel>>() {
@Override
public Loader<List<RobotViewModel>> onCreateLoader(int id, Bundle args) {
return new StringLoader(getApplicationContext());
}
@Override
public void onLoadFinished(Loader<List<RobotViewModel>> loader, List<RobotViewModel> data) {
adapter.setData(data);
}
@Override
public void onLoaderReset(Loader<List<RobotViewModel>> loader) {
adapter.setData(Collections.<RobotViewModel>emptyList());
}
};
适配器上的 setData()
方法:
public void setData(List<RobotViewModel> data) {
list.clear();
list.addAll(data);
notifyDataSetChanged();
}
添加项目到列表通常没有任何问题,并且工作正常,但我想添加项目并刷新适配器
答案 0 :(得分:0)
对于自定义加载器,您必须创建自己的观察者,每当表中发生更改时,您将继续观察表的URI,然后您将在观察者或加载器上获得回调,并且可以更新视图。
您可以使用除光标之外的其他一些对象来指向加载的数据(如列表等)。在这里,我们没有权限通过游标通知ContentResolver。应用程序也可能没有内容提供程序来跟踪URI更改。在这种情况下,我们使用BroadcastReceiver或显式ContentObserver来实现自动视图更新。具体如下:
我们需要定义我们的自定义加载器,它扩展了AsyncTaskLoader并实现了它的所有抽象方法。与CursorLoader不同,我们的自定义加载器可能会也可能不会使用内容提供程序,并且当此加载器被实例化时,它的构造函数可能不会调用ContentResolver.query()。所以我们使用广播接收器来达到目的。 我们需要在抽象AsyncTaskLoader类的OnStartLoading()方法中实例化BroadCastReceiver或ContentObserver。 应该定义此BroadCast接收器以从内容提供者或任何系统事件(如新安装的应用程序)接收数据更改广播,并且必须调用loader的onContentChanged()方法,以通知加载器有关数据更改的信息。 Loader会自动完成其余工作以加载更新的数据并调用onLoadFinished()来更新视图。
有关详细信息,请参阅:http://developer.android.com/reference/android/content/AsyncTaskLoader.html http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html
示例代码
在您的活动中添加此代码
private final ContentObserver mObserver = new ThrottledContentObserver(
new ThrottledContentObserver.Callbacks() {
@Override
public void onThrottledContentObserverFired() {
getSupportLoaderManager().restartLoader(LOADER_ID, null, MainActivity.this);
}
});
使用
在 onResume()上注册以下变量
getContentResolver()。registerContentObserver(CONTENT_URI,true,mObserver);
使用getContentResolver().unregisterContentObserver(mObserver);