分页片段中的PullToRefresh列表

时间:2013-05-11 02:42:04

标签: android actionbarsherlock android-viewpager fragment pull-to-refresh

我想用pager创建PullToRefresh列表片段。 我正在使用ActionBarSherlock和列表的this implementation。没有片段我没有问题,但我需要支持双窗格布局。

布局文件

activity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin" >

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".SubcatNavActivity" />

</LinearLayout>

fragment
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/subcat_list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </ListView>
</LinearLayout>

活动很简单

public class SubcatNavActivity extends SherlockFragmentActivity
{
    private SubcatNavPager mPager;


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

        setContentView(R.layout.activity_subcat_nav);

        mPager = new SubcatNavPager(this);
        mPager.initialisePaging();

        setProgressBarIndeterminateVisibility(true);
    }
}

我创建了一个pager类,以便稍后在主窗格模式中使用它。

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;


public class SubcatNavPager implements ActionBar.TabListener
{   
    public SectionsPagerAdapter mSectionsPagerAdapter;
    public ViewPager mViewPager;
    private SherlockFragmentActivity mFragmentActivity;

    public SubcatNavPager(SherlockFragmentActivity fa) {
        mFragmentActivity = fa;
    }

    public void initialisePaging() {
        mFragmentActivity.setTitle(mFragmentActivity.getResources().getString(SiteContent.curr_cat.nameID));

        try {
            List<Fragment> fragments = new Vector<Fragment>();
            mSectionsPagerAdapter = new SectionsPagerAdapter(mFragmentActivity.getSupportFragmentManager(), fragments);

            for (int i = 0; i < SiteContent.curr_cat.content.size(); ++i) {
                Fragment tmp = SiteContent.curr_cat.fragment.newInstance();

                if (!(tmp instanceof ContentDownloader)) {
                    throw new IllegalStateException(
                            "Fragment must implement content downloader interface.");
                }

                Bundle args = new Bundle();
                args.putInt(SubcatListFragment.SUBCAT_IDX, i);
                tmp.setArguments(args);
                fragments.add((Fragment)tmp);
            }

            mViewPager = (ViewPager)mFragmentActivity.findViewById(R.id.pager);
            mViewPager.setAdapter(mSectionsPagerAdapter);

            final ActionBar actionBar = mFragmentActivity.getSupportActionBar();
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

            mViewPager
                    .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                        @Override
                        public void onPageSelected(int position) {
                            actionBar.setSelectedNavigationItem(position);
                        }
                    });

            for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
                actionBar.addTab(actionBar.newTab()
                        .setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
            }

            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        catch (Exception e) {}
    }

    @Override   
    public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
        int pos = tab.getPosition();
        SiteContent.setCurrSubCat(pos);
        mViewPager.setCurrentItem(pos);
        ((ContentDownloader)mSectionsPagerAdapter.getItem(pos)).downloadContent(false);
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {}

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {}


    public class SectionsPagerAdapter extends FragmentPagerAdapter
    {
        private List<Fragment> fragments;

        public SectionsPagerAdapter(FragmentManager fm, List<Fragment> fList) {
            super(fm);
            fragments = fList;
        }

        @Override
        public Fragment getItem(int position) {
            Fragment tmp = fragments.get(position);
            return tmp;
        }

        @Override
        public int getCount() { return fragments.size(); }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentActivity.getResources().getString(SiteContent.curr_cat.content.get(position).nameID);
        }
    }
}

最后,片段本身

import com.actionbarsherlock.app.SherlockListFragment;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

public class SubcatListFragment extends SherlockListFragment implements ContentDownloader
{
    public static final String SUBCAT_IDX = "subcat_idx";
    protected ArrayAdapter<SiteItem> adapter;
    protected DownloadSubcatTask loadTask;
    protected SiteSubcat subcat;
    private PullToRefreshListView mPullToRefreshListView;
    private boolean loadRequested;

    public SubcatListFragment() {           
        adapter = null;
        loadRequested = false;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle args = getArguments();           
        subcat = SiteContent.curr_cat.content.get(args.getInt(SUBCAT_IDX));
        adapter = new ArrayAdapter<SiteItem>(getActivity(), android.R.layout.simple_list_item_1, subcat.items);
        this.setListAdapter(adapter);

        if (loadRequested == true)
            downloadContent(false);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View layout = inflater.inflate(R.layout.fragment_subcat_nav, container, false);

        ListView lv = (ListView) layout.findViewById(R.id.subcat_list);
        ViewGroup parent = (ViewGroup) lv.getParent();

        int lvIndex = parent.indexOfChild(lv);
        parent.removeViewAt(lvIndex);
        mPullToRefreshListView = new PullToRefreshListView(layout.getContext());
        mPullToRefreshListView.setMode(Mode.BOTH);
        mPullToRefreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>()
                                {
                                    @Override
                                    public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                                        downloadContent(true);
                                    }
                                });

        parent.addView(mPullToRefreshListView, lvIndex, lv.getLayoutParams());        
        return layout;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Intent subcatIntent = new Intent(getActivity(), NewsActivity.class);
        SiteContent.setCurrItem((int)id);
        startActivity(subcatIntent);
    }

    @Override
    public void downloadContent(boolean bRefresh) {
        // on first call to onTabSelected this fragment is not created, yet
        if (subcat == null)
            loadRequested = true;
        else
        {
            loadRequested = false;
            if (loadTask == null && (adapter.isEmpty() == true || bRefresh == true))
                (loadTask = new DownloadSubcatTask()).execute(subcat.getUrl());
        }
    }   

    protected void showProgress(boolean bShow) {
        getActivity().setProgressBarIndeterminateVisibility(bShow);
    }

    private class DownloadSubcatTask extends DownloadTask {
        public DownloadSubcatTask() {}      

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showProgress(true);
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            adapter.clear();
            loadTask = null;

            try {
                SiteContent.curr_cat.parser.newInstance().parse(result, adapter);
            }
            catch (Exception e) {}

            mPullToRefreshListView.onRefreshComplete();
            adapter.notifyDataSetChanged();
            showProgress(false);
        }
    }
}

正如您所看到的,一切都包含来自示例的内容。但问题是,当我启动应用程序时,列表不会显示。我可以看到标签,加载指示器消失了(我知道适配器有数据)但列表区域是清晰的白色。我不能拉清单来刷新它。但是,如果我尝试交换页面,突然数据出现在上一页(实际上不是之前的,但之前的那个)。它似乎与适配器加载前两个片段有关,但我可以弄清楚出了什么问题。

加载后如何制作列表? 更普遍的问题是,这是正确的架构吗?

修改
如果我删除所有这样的pull-to-refresh代码 public View onCreateView(LayoutInflater inflater,ViewGroup容器,Bundle savedInstanceState) {     View layout = inflater.inflate(R.layout.fragment_subcat_nav,container,false);         返回布局; }

并在片段布局中设置默认列表ID android:id="@android:id/list"列表视图将按原样显示。无法弄清楚为什么拉动刷新会导致问题。

1 个答案:

答案 0 :(得分:2)

这就是我如何修复问题(列表片段需要返回列表视图)

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View layout = inflater.inflate(R.layout.fragment_subcat_nav, container, false);
        ListView lv = (ListView) layout.findViewById(android.R.id.list);

        mPullToRefreshListView = new PullToRefreshListView(getActivity());
        mPullToRefreshListView.setLayoutParams(lv.getLayoutParams());

        mPullToRefreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>()
                                {
                                    @Override
                                    public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                                        downloadContent(true);
                                    }
                                });

        return mPullToRefreshListView;
    }