Vamsi Challa
Vamsi Challa

Reputation: 11109

ActionBar-PullToRefresh with ListView and Fragment

I am trying to implement ActionBar-PullToRefresh in my application. The activity has a fragment in it and the fragment has a listview in it. The implementation of listview is with custom adapter.

I tried to implement it with the QuickStart-ABS guide on github, but the pull doesn't work. I have a feeling that I am not initialising the PullToRefresh correctly. Please have a look at my code below...

fragment_news_list.xml

<?xml version="1.0" encoding="utf-8"?>
<uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ptr_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/listview_news_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout>

NewsListFragment.java

import java.util.ArrayList;
import java.util.List;

import uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout;
import uk.co.senab.actionbarpulltorefresh.library.ActionBarPullToRefresh;
import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockFragment;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;

public class NewsListFragment extends SherlockFragment implements
        OnRefreshListener {

    ProgressDialog pd;
    ImageLoader imageLoader;
    JsonArrayRequest jsArrayRequest;
    Database db;
    ListView listview;
    List<NewsItem> newsItems = new ArrayList<NewsItem>();
    NewsAdapter adapter;

    NewsDbAdapter mNewsDbAdapter;

    private PullToRefreshLayout mPullToRefreshLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        mNewsDbAdapter = DatabaseHelper.get(
                getActivity().getApplicationContext()).getNewsDbAdapter();

        // unrelated code removed

        View view = inflater.inflate(R.layout.fragment_news_list, container,
                false);

        pd = new ProgressDialog(getActivity());
        pd.setMessage("Loading...");
        pd.show();
        pd.setCancelable(true);

        newsItems = mNewsDbAdapter.getNewsTitles();
        adapter = new NewsAdapter(getActivity(), newsItems);
        listview = (ListView) view.findViewById(R.id.listview_news_list);
        listview.setAdapter(adapter);

        pd.dismiss();

        return view;
    }

    public class NewsAdapter extends ArrayAdapter<NewsItem> {
        // Adapter code goes in here... removed as not necessary
    }



    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ViewGroup viewGroup = (ViewGroup) view;

        // As we're using a ListFragment we create a PullToRefreshLayout manually
        mPullToRefreshLayout = new PullToRefreshLayout(viewGroup.getContext());

        // We can now setup the PullToRefreshLayout
        ActionBarPullToRefresh.from(getActivity())
                // We need to insert the PullToRefreshLayout into the Fragment's ViewGroup
                .insertLayoutInto(viewGroup)
                // Here we mark just the ListView and it's Empty View as pullable
                .theseChildrenArePullable(android.R.id.list, android.R.id.empty)
                .listener(this)
                .setup(mPullToRefreshLayout);

    }



    @Override
    public void onRefreshStarted(View view) {
        // Hide the list
        // setListShown(false);
        listview.setVisibility(View.INVISIBLE);

        /**
         * Simulate Refresh with 4 seconds sleep
         */
        new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);

                // Notify PullToRefreshLayout that the refresh has finished
                mPullToRefreshLayout.setRefreshComplete();

                if (getView() != null) {
                    // Show the list again
                    //setListShown(true);
                    listview.setVisibility(View.VISIBLE);
                }
            }
        }.execute();
    }

}

Where am I going wrong? If some one has an example with fragment with a listview, please share the link here..

Thanks!!!

[EDIT]

changed this

theseChildrenArePullable(android.R.id.list, android.R.id.empty)

to

theseChildrenArePullable(R.id.listview_news_list, android.R.id.empty)

and it worked...

Upvotes: 4

Views: 3081

Answers (2)

2Dee
2Dee

Reputation: 8629

I believe the problem is that you are not using the ListView in your Fragment layout, but a default one from the framework, try this :

// setup the PullToRefreshLayout
    ActionBarPullToRefresh.from(getActivity())
            // We need to insert the PullToRefreshLayout into the Fragment's ViewGroup
            .insertLayoutInto(viewGroup)
            // Here we mark just the ListView and it's Empty View as pullable
            .theseChildrenArePullable(R.id. listview_news_list, android.R.id.empty)
            .listener(this)
            .setup(mPullToRefreshLayout);

If it's not working, you could also try by doing the following in your onCreateView method :

mPullToRefreshLayout = ((PullToRefreshLayout) view.findViewById(R.id.ptr_layout));

and then setup it like this in onActivityCreated or onViewCreated :

ActionBarPullToRefresh
    .from(getActivity())
    .allChildrenArePullable()
    .listener(this)
    .setup(this.mPullToRefreshLayout);

For the record, I am using PullToRefreshLayout inside a Fragment in my app and it's working just fine. Let me know if it works.

Upvotes: 5

fifarunnerr
fifarunnerr

Reputation: 617

You have to initialize the ActionBarPullToRefresh in the onCreate method of your Activity, not in onViewCreated of your Fragment. Initialize the library in the Activity, and pass it to the Fragment.

Upvotes: -3

Related Questions