Не могу обновить данные в ListFragment - PullRequest
3 голосов
/ 14 февраля 2012

Я пытаюсь реализовать ListFragment с AsynchTaskLoader, который содержит источник данных, но у меня проблемы с обновлением listFragment, так как он не обновляется при изменении данных из фона в BaseAsyncTaskLoader

Код прилагается:

Операция, которая загружает фрагмент списка

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 Class

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 ]

5 голосов
/ 24 февраля 2012

Просто вызовите перезапустить загрузчик вместо этого в loadMOre, а лучше вызвать его из 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);
     }
}

Можно найти лучший примерна здесь

5 голосов
/ 22 мая 2013

Звоните invalidateViews(), чтобы обновить ListFragment

listFragment.getListView().invalidateViews();
1 голос
/ 14 февраля 2012

Не забудьте позвонить:

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);
     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...