【问题标题】:ActionBar-PullToRefresh with ListView and Fragment带有 ListView 和 Fragment 的 ActionBar-PullToRefresh
【发布时间】:2026-01-30 05:35:01
【问题描述】:

我正在尝试在我的应用程序中实现 ActionBar-PullToRefresh。活动中有一个片段,片段中有一个列表视图。 listview 的实现是通过自定义适配器实现的。

我尝试使用 github 上的 QuickStart-ABS 指南来实现它,但是 pull 不起作用。我有一种感觉,我没有正确初始化 PullToRefresh。请看下面我的代码...

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();
    }

}

我哪里出错了?如果有人有一个带有列表视图的片段示例,请在此处分享链接..

谢谢!!!

[编辑]

改变了这个

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

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

它成功了……

【问题讨论】:

    标签: android android-listview android-fragments


    【解决方案1】:

    我认为问题在于您没有在 Fragment 布局中使用 ListView,而是框架中的默认布局,试试这个:

    // 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);
    

    如果它不起作用,您也可以尝试在 onCreateView 方法中执行以下操作:

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

    然后在 onActivityCreated 或 onViewCreated 中像这样设置它:

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

    为了记录,我在我的应用程序的片段中使用PullToRefreshLayout,它工作得很好。让我知道它是否有效。

    【讨论】:

    • 我怎么错过了!!!感谢您的帮助.. 问题是我使用的是默认框架的列表视图,而不是我的列表视图。将 android.R.id.list 更改为 R.id.listview_news_list,让它工作。再次感谢...
    • 很高兴我能帮上忙 ;) 编码愉快!
    • 在我的例子中,我在没有附加监听器的情况下测试它。您必须附加监听器,否则它将无法工作。
    【解决方案2】:

    您必须在 Activity 的 onCreate 方法中初始化 ActionBarPullToRefresh,而不是在 Fragment 的 onViewCreated 中。在Activity中初始化库,并传递给Fragment。

    【讨论】:

      最近更新 更多