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

Ren*_*K N 11 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
Run Code Online (Sandbox Code Playgroud)

在简单的句子中,
我想知道将页面添加到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();
        }


    }
}
Run Code Online (Sandbox Code Playgroud)

我的片段课

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


}
Run Code Online (Sandbox Code Playgroud)

Yoa*_*uet 3

我将在这里解释我在我的案例中的做法,我添加了相同的设置,除了我需要在几天而不是几个月之间左右滑动:

  1. 我设置了一个最小日期和一个最大日期,这将成为导航日期的限制。就我而言,我设定了很大的限制,从 1970 年到 2050 年,以确保我处理足够的时间表。如果我们以月份为例,比如 2012 年到 2014 年,这意味着寻呼机中将有 3 年 * 12 个月 = 36 个不同的位置可用。

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

为了给您一个想法,以下是我在我的 中获取当前位置的方法Activity

//position in the timeline
todayPosition = Days.daysBetween(new DateTime(MIN_DATE), new DateTime(getTodayDate())).getDays();
Run Code Online (Sandbox Code Playgroud)

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

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

pager.setCurrentItem(mApplication.getTodayPosition());
Run Code Online (Sandbox Code Playgroud)

这是适配器,以防它对您有所启发:

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());
}   
}
Run Code Online (Sandbox Code Playgroud)

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