我正在尝试使用包含数据源的AsynchTaskLoader实现ListFragment但是我在刷新listFragment时遇到了麻烦,因为当我从BaseAsyncTaskLoader中的后台更改数据时它没有刷新
附上代码:
加载listfragment的活动
public class BaseFragmentManager extends FragmentActivity implements ListItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_stack);
Button btnLoadMore = (Button) findViewById(R.id.new_fragment);
btnLoadMore.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent();
i.setAction("com.test.gcc.myintent.loader.BaseAsyncTaskLoader");
i.putExtra("action", "loadmore");
sendBroadcast(i);
}
});
BaseListFragmentActivity fragment = new BaseListFragmentActivity();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
@Override
public void onListItemSelected(int index) {
Log.i("Error", "itemSelected-"+index);
}
}
我没有刷新的LISTFragment类
public class BaseListFragmentActivity extends ListFragment implements LoaderManager.LoaderCallbacks<ArrayList<MyData>> {
private ListItemSelectedListener selectedListener;
private int index = 0;
private ArrayList<MyData> data;
private BaseAsyncTaskLoader astask;
private CustomListAdapter adapter;
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
this.data = MyDataBroker.getDefaultBroker().getData();
this.adapter = new CustomListAdapter(this.getActivity(), data);
setListAdapter(this.adapter);
setListShown(false);
getLoaderManager().initLoader(0, null, this);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override public Loader<ArrayList<MyData>> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader with no arguments, so it is simple.
astask = new BaseAsyncTaskLoader(this.getActivity());//new AppListLoader(getActivity());
return astask;
}
@Override
public void onLoadFinished(Loader<ArrayList<MyData>> Loader, ArrayList<MyData> data) {
this.adapter.setData(data);
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
index = position;
selectedListener.onListItemSelected(position);
}
@Override
public void onLoaderReset(Loader<ArrayList<MyData>> data) {
adapter.setData(null);
}
public interface ListItemSelectedListener {
public void onListItemSelected(int index);
}
}
AsynchTaskLoader类
public class BaseAsyncTaskLoader extends AsyncTaskLoader<ArrayList<MyData>> {
private ArrayList<MyData> data;
private int pageNumber;
private boolean listenerIsRegistered = false;
private com.test.gcc.myintent.test.BaseAsyncTaskLoader.CustomBroadCastListener listener;
public BaseAsyncTaskLoader(Context context) {
super(context);
pageNumber = 1;
listener = new CustomBroadCastListener();
if (!listenerIsRegistered) {
context.registerReceiver(listener, new IntentFilter("com.test.gcc.myintent.loader.BaseAsyncTaskLoader"));
listenerIsRegistered = true;
}
}
/**
* This is where the bulk of our work is done. This function is called in a
* background thread and should generate a new set of data to be published
* by the loader.
*/
@Override
public ArrayList<MyData> loadInBackground() {
final Context context = getContext();
return this.loadInBackgroud();
}
private ArrayList<MyData> loadInBackgroud() {
return MyDataBroker.getDefaultBroker().getData(); //returns some data of custom type.
}
/**
* Called when there is new data to deliver to the client. The super class
* will take care of delivering it; the implementation here just adds a
* little more logic.
*/
@Override
public void deliverResult(ArrayList<MyData> data) {
if (isReset()) {
if (data != null) {
onReleaseResources(data);
}
}
if (isStarted()) {
super.deliverResult(data);
}
}
/**
* Handles a request to start the Loader.
*/
@Override
protected void onStartLoading() {
if (this.data != null) {
deliverResult(this.data);
}
if (takeContentChanged() || this.data == null) {
forceLoad();
}
}
/**
* Handles a request to stop the Loader.
*/
@Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Handles a request to cancel a load.
*/
@Override
public void onCanceled(ArrayList<MyData> data) {
super.onCanceled(data);
onReleaseResources(data);
}
/**
* Handles a request to completely reset the Loader.
*/
@Override
protected void onReset() {
super.onReset();
onStopLoading();
this.data = null;
}
public void onLoadMore(){
this.loadInBackground();
}
protected class CustomBroadCastListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.test.gcc.myintent.loader.BaseAsyncTaskLoader")) {
if(intent.getStringExtra("action") != null &&
intent.getStringExtra("action").equals("loadmore")){
loadInBackground();
}
}
}
}
/**
* Helper function to take care of releasing resources associated with an
* actively loaded data set.
*/
protected void onReleaseResources(List<MyData> apps) {
//NOTUSED
}
}
从调试我可以看到正在加载数据但是listFragment没有刷新,据我所知,我们不必手动刷新listFragment,因为它附加到数据源,它应该自动刷新。
答案 0 :(得分:5)
只需在loadMOre中调用restart loader,最好从ListFragment
调用它public void onLoadMore(){
loader.restartLoader(0, null, this);
}
并将onFinished更改为@doorstuck
所述@Override
public void onLoadFinished(Loader<ArrayList<MyData>> Loader, ArrayList<MyData> data) {
this.adapter.setData(data);
this.adapter.notifyDataSetChanged();
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
可以在here
找到更好的示例答案 1 :(得分:5)
致电invalidateViews()
以刷新ListFragment
listFragment.getListView().invalidateViews();
答案 2 :(得分:1)
请记得致电:
notifyDataSetChanged()
当您希望更新绑定到适配器的视图时,在列表适配器中。请将代码发布到列表适配器。
你可以把它放在这里:
@Override
public void onLoadFinished(Loader<ArrayList<MyData>> Loader, ArrayList<MyData> data) {
this.adapter.setData(data);
this.adapter.notifyDataSetChanged();
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}