正确管理碎片

时间:2014-05-19 16:18:48

标签: android android-fragments

我在项目中正确使用和管理片段时遇到了一些困难。

我从this Android Developers project开始作为基础。

mainactivity扩展了SampleActivityBase并启动了一个简单的片段:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    SlidingTabsBasicFragment fragment = new SlidingTabsBasicFragment();
    transaction.replace(R.id.sample_content_fragment, fragment);
    transaction.commit();
}

SlidingTabsbasicFragment类扩展Fragment并在onCreateView上返回一个布局:

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

然后在另一个扩展PagerAdapter的类中,基于位置的视图内容被更改:

@Override
    public Object instantiateItem(ViewGroup container, int position) {
        // Inflate a new layout from our resources
        View view = getActivity().getLayoutInflater().inflate(R.layout.pager_item,
                container, false);
        // Add the newly created View to the ViewPager
        container.addView(view);

        // Retrieve a TextView from the inflated View, and update it's text
        TextView title = (TextView) view.findViewById(R.id.item_title);
        title.setText(String.valueOf(position + 1));

        Log.i(LOG_TAG, "instantiateItem() [position: " + position + "]");

        // Return the View
        return view;
    }

这为我提供了我正在寻找的基本选项卡功能。我甚至通过根据位置充气来改变布局。但现在我正在尝试实施名为Caldroid的自定义日历。

这里的主要类扩展了FragmentActivity。这允许它setContentView并使用FragmentTransaction和.replace将带有ID的布局更改为包含自定义日历的片段:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy");

    // Setup caldroid fragment
    // **** If you want normal CaldroidFragment, use below line ****
    caldroidFragment = new CaldroidFragment();

    // //////////////////////////////////////////////////////////////////////
    // **** This is to show customized fragment. If you want customized
    // version, uncomment below line ****

// caldroidFragment = new CaldroidSampleCustomFragment();

    // Setup arguments

    // If Activity is created after rotation
    if (savedInstanceState != null) {
        caldroidFragment.restoreStatesFromKey(savedInstanceState,
                "CALDROID_SAVED_STATE");
    }
    // If activity is created from fresh
    else {
        Bundle args = new Bundle();
        Calendar cal = Calendar.getInstance();
        args.putInt(CaldroidFragment.MONTH, cal.get(Calendar.MONTH) + 1);
        args.putInt(CaldroidFragment.YEAR, cal.get(Calendar.YEAR));
        args.putBoolean(CaldroidFragment.ENABLE_SWIPE, true);
        args.putBoolean(CaldroidFragment.SIX_WEEKS_IN_CALENDAR, true);

        // Uncomment this to customize startDayOfWeek
        // args.putInt(CaldroidFragment.START_DAY_OF_WEEK,
        // CaldroidFragment.TUESDAY); // Tuesday
        caldroidFragment.setArguments(args);
    }

    setCustomResourceForDates();

    // Attach to the activity
    FragmentTransaction t = getSupportFragmentManager().beginTransaction();
    t.replace(R.id.calendar1, caldroidFragment);
    t.commit();

我想要实现的是保留选项卡式布局,并仅在其中一个选项卡中生成自定义日历。我很感激任何方向/帮助/资源或其他建议。

我已经包含了一些代码片段,但这两个项目都存在(或多或少)作为原件:

SlidingTabsBasic Caldroid

感谢任何人提供的任何帮助。

*(1)根据要求添加了PagerAdapter :(据我所见,人们说不要乱用instantiateItem?)

class SamplePagerAdapter extends PagerAdapter {

@Override
public int getCount() {
    return 3;
}

@Override
public boolean isViewFromObject(View view, Object o) {
    return o == view;
}

@Override
public CharSequence getPageTitle(int position) {
    switch(position) {
        case 0:
            return "Item 1";
        case 1:
            return "Item 2";
        case 2:
            return "Item 3";
    }
    return "Item " + (position + 1);
}

@Override
public Object instantiateItem(ViewGroup container, int position) {

    // Inflate a new layout from our resources
    View view = null;
    if(position==2) {
        view = getActivity().getLayoutInflater().inflate(R.layout.item_1, container, false);
        container.addView(view);
    } else if(position==0) {
        view = getActivity().getLayoutInflater().inflate(R.layout.item_2, container, false);
        container.addView(view);
    } else {
        view = getActivity().getLayoutInflater().inflate(R.layout.item3, container, false);
        container.addView(view);
    }

    Log.i(LOG_TAG, "instantiateItem() [position: " + position + "]");

    // Return the View
    return view;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((View) object);
    Log.i(LOG_TAG, "destroyItem() [position: " + position + "]");
}

}

1 个答案:

答案 0 :(得分:1)

您需要做的是使用FragmentStatePagerAdapter代替PagerAdapter。您基本上只需要定义您拥有Tabs的{​​{1}}以及FragmentTab所属的private class ExampleAdapter extends FragmentStatePagerAdapter { public ExampleAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { // Return the correct Fragment for each Tab // The position corresponds to the position of the Tab // So the first Tab has a position of 0, the second Tab has a position of 1... switch (position) { case 0: return new Fragment1(); case 1: return new Fragment2(); case 2: return new Fragment3(); default: return null; } } @Override public int getCount() { return 3; // 3 Fragments in this example } }

FragmentStatePagerAdapter

所以这是getPageTitle()的最基本实现,只需要它就可以使它工作。我没有测试过,但如果有必要,你仍然可以像以前一样覆盖{{1}}。