如何将页面添加到ViewPager的开头?

时间:2013-06-07 12:03:16

标签: android android-viewpager android-fragmentactivity

关于我的申请
我正在开发一个日历应用程序。想要用水平滑动导航显示月视图吗?这意味着无限滚动用户可以按月向右和向左滚动到任何年份的任何日期/月份。我发现ViewPager非常充分地用来实现这个目标。(我真的不知道其他什么是使用完整的方法)。通过点击日期单元格,用户可以看到添加到该日期的详细信息或事件(我不知道)我想链接设备日历)。

关于此问题
我可以将新页面添加到我的View寻呼机的末尾而没有任何问题。但是如果用户向左滑动,我需要在ViewPager的开头添加一个页面。 。当我向begning(索引位置为零)添加页面时,这将替换我在零位置的当前页面,并且只能添加一页(没有添加新页面,我不知道为什么)。在零位置上添加页面后,当用户向右滑动并访问最后一页强制关闭时,我无法将视图添加页面添加到视图寻呼机的末尾:

java.lang.IllegalStateException: Can't change tag of fragment MyFragment{40526bb8 #2  id=0x7f070000 android:switcher:2131165184:2}: was android:switcher:2131165184:2 now android:switcher:2131165184:3

简单的句子
我想知道在View分页器的开头和结尾添加页面的正确方法是什么?

代码

活动和适配器

    public class PageViewActivity extends FragmentActivity {

    ViewPager pager;
    MyPageAdapter pageAdapter;
    ArrayList<Fragment> fragments;

    int page_num = 0;
    int current_page = 1;
    int selected_page = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_page_view);

        pager = (ViewPager) findViewById(R.id.viewpager);

        fragments = getFragments();

        pageAdapter = new MyPageAdapter(getSupportFragmentManager(), pager,
                fragments);

        pager.setAdapter(pageAdapter);
        pager.setCurrentItem(2);
        pager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {

                // setting the selected page index
                selected_page = arg0;       
                //calling add page
                addPage();

            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub          

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub
            }
        });


    }

    public int addPage() {

        System.out.println("Add page called "+selected_page);
        // checking if selected page is second last and if tru adds new page 
        if (selected_page >= (pageAdapter.getCount() - 1)) {    

            System.out.println("on first condition");

            Fragment new_fragment = MyFragment.newInstance("Added to last  "+ (pageAdapter.getCount() + 1));
            //pageAdapter.fragments.add(pageAdapter.getCount(), new_fragment);
            System.out.println("pageAdapter.getCount()   :  "+pageAdapter.getCount());
            pageAdapter.add(pageAdapter.getCount(), new_fragment);
            current_page = selected_page;           
            pageAdapter.notifyDataSetChanged();
            System.out.println("New page added");
        }else if((selected_page-1)<=0){

            System.out.println("on second condition");

            Fragment new_fragment = MyFragment.newInstance("Added to begning  "+ (pageAdapter.getCount() + 1));         
            pageAdapter.add(0, new_fragment);
            current_page = selected_page;           
            //pageAdapter.notifyDataSetChanged();
        }

        return pageAdapter.getCount();


    }

    private ArrayList<Fragment> getFragments() {

        ArrayList<Fragment> fList = new ArrayList<Fragment>();

        fList.add(MyFragment.newInstance("Fragment 1"));
        fList.add(MyFragment.newInstance("Fragment 2"));
        fList.add(MyFragment.newInstance("Fragment 3"));
        fList.add(MyFragment.newInstance("Fragment 4"));
        fList.add(MyFragment.newInstance("Fragment 5"));

        return fList;
    }

    private class MyPageAdapter extends FragmentPagerAdapter {

        private ArrayList<Fragment> fragments;
        private ViewPager mPager;

        public MyPageAdapter(FragmentManager fm, ViewPager vp,
            ArrayList<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
            this.mPager = vp;


        }

        public void  add(int position,Fragment f){          
            fragments.add(position, f);
            this.notifyDataSetChanged();
        }


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

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


    }
}

My Fragment class

public class MyFragment extends Fragment {
public static final String EXTRA_MESSAGE = "EXTRA_MESSAGE";

public static final MyFragment newInstance(String message)
{
    MyFragment f = new MyFragment();
    Bundle bdl = new Bundle(1);
    bdl.putString(EXTRA_MESSAGE, message);
    f.setArguments(bdl);
    return f;
}

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

    String message = getArguments().getString(EXTRA_MESSAGE);
    View v = inflater.inflate(R.layout.myfragment_layout, container, false);
    TextView messageTextView = (TextView)v.findViewById(R.id.textView);
    messageTextView.setText(message);

    //return null;
    return v;
}


}

1 个答案:

答案 0 :(得分:3)

我将在这里解释我在我的情况下做的方式,我添加设置相同的东西,除了我需要在几天而不是几个月之间左右滑动:

  1. 我设置的最短日期和最长日期将成为导航日期的限制。在我的情况下,我提出了很大的限制,从1970年到2050年,以确保我处理足够的时间表。 如果我们用几个月更简单的例子,假设2012年到2014年,这意味着我们将有3年* 12个月=在寻呼机中提供36个不同的职位。

  2. 当应用程序启动时,默认情况下,我当前的片段显示当前日期,对您而言,显示当前月份。所以我在我的应用程序上创建了一个特定的函数来获取我的时间轴内的位置,以获得所选日期的位置。如果我们再次采用上面的例子,那么这个位置将是18。

  3. 为了给您一个想法,以下是我在Activity中获取当天职位的方式:

    //position in the timeline
    todayPosition = Days.daysBetween(new DateTime(MIN_DATE), new DateTime(getTodayDate())).getDays();
    

    daysBetween是Joda Time库中的一个函数,我使用它来获取最小日期和所选日期之间的天数(即时间轴中的位置)。

    然后在我的onCreate函数中,我在创建活动期间以这种方式初始化寻呼机:

    pager.setCurrentItem(mApplication.getTodayPosition());
    

    这是适配器,如果它激发你的灵感:

    public class MyFragmentPagerAdapter extends FragmentStatePagerAdapter{
    
    private final int todayPosition;
    private MyFragment currentFragment;
    private final Calendar todayDate;
    
    /** Constructor of the class */
    public MyFragmentPagerAdapter(FragmentManager fm, int today_position, Calendar today_date) {
        super(fm);
        todayPosition = today_position;
        todayDate = (Calendar) today_date.clone();
    }
    
    /** This method will be invoked when a page is requested to create */
    @Override
    public Fragment getItem(int arg0) {     
        currentFragment = new MyFragment();
        Bundle data = new Bundle();
    
        data.putInt("current_page", arg0);
        currentFragment.setArguments(data);
        return currentFragment;
    }
    
    /** Returns the number of pages */
    @Override
    public int getCount() {     
        return MyApplication.TOTAL_NUMBER_OF_DAYS;
    }
    
    @Override
    public CharSequence getPageTitle(int position) {
        Calendar newDate = (Calendar) todayDate.clone();
    
        int diffDays = position - todayPosition;
        newDate.add(Calendar.DATE, diffDays);
    
        return MyApplication.dateTitleFormat.format(newDate.getTime());
    }   
    }
    

    我不保证这是最好的解决方案,但至少它是有效的。