无法刷新ListFragment中的数据

时间:2012-02-14 17:55:52

标签: android android-fragments

我正在尝试使用包含数据源的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,因为它附加到数据源,它应该自动刷新。

3 个答案:

答案 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);
     }
}