使用ViewPager时在片段之间导航

时间:2013-11-01 21:58:15

标签: android android-layout android-fragments

我在这里看了很多问题,我甚至都不知道我在找什么。

我有一个使用ViewPager的简单应用。它有3个选项卡,每个选项卡都有一个片段。第一个片段包含ListView。我希望能够单击ListView中的一个元素,并将其带到另一个片段。

所以基本上我想在单击一个元素后删除包含ListView的片段并添加一个新片段。我试图以几种不同的方式做到这一点,没有工作。

我尝试的最后一件事是在点击一个元素后编辑TabsPageAdapter,除非按下后退按钮退出应用程序,否则几乎可以工作。此外,它似乎不是最干净的方式。

TabsPagerAdapter

public class TabsPagerAdapter extends FragmentStatePagerAdapter {

SherlockFragment mf;
TalkingPointsFragment tpf;
ContactFragment gf;
int mode = 0; 

public TabsPagerAdapter(FragmentManager fm) {
    super(fm);
    mf = new CanvassFragment();
    tpf = new TalkingPointsFragment();
    gf = new ContactFragment();
}

public TabsPagerAdapter(FragmentManager fm, int mode)
{
    super(fm);
    if(mode == 0)
    {
    mf = new CanvassFragment();
    tpf = new TalkingPointsFragment();
    gf = new ContactFragment();
    }
    else if(mode == 1)
    {
        mf = new ContactFragment();
        tpf = new TalkingPointsFragment();
        gf = new ContactFragment();
    }
}

@Override
public SherlockFragment getItem(int index) {

    switch (index) {
    case 0:
        return mf;
    case 1:
        return tpf;
    case 2:
        return gf;
    }

    return null;
}

@Override
public int getCount() {
    // get item count - equal to number of tabs
    return 3;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object)
{

}
}

onclick代码:

ViewPager viewp = (ViewPager) getActivity().findViewById(R.id.pager);
TabsPagerAdapter mAdapter = new TabsPagerAdapter(getActivity().getSupportFragmentManager(),1);

viewp.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();

layout_main.xml

<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:actionBarTabStyle="@drawable/actionbar_tab_indicator">

2 个答案:

答案 0 :(得分:0)

我也是FragmentStatePagerAdapter,当用户从ActionBar中选择地图时,我在FragmentStatePagerAdapter上添加了GoogleMapsFragment:

        // create a new map
        mapsFragment = GoogleMapFragment.newInstance();
        // Then we add it using a FragmentTransaction.
        FragmentTransaction fragmentTransaction = getSupportFragmentManager()
                .beginTransaction();
        fragmentTransaction.add(android.R.id.content, mapsFragment,
                FRAGMENT_MAP_TAG);
        fragmentTransaction.commit();

对于你的情况,你可能也需要将它添加到backstack,我没有,因为在我的应用程序中,用户必须使用ActionBar导航回来。

当用户从列表中选择一个项目时,也认为这种方法也适用于您。

当然,这样做的缺点是在用户导航回来之前无法使用FragmentStatePagerAdapter。因此,我不确定您的应用程序是否可接受。

答案 1 :(得分:0)

好的,所以这需要我想象的更多代码。希望你明白这个想法:

public class MainClass extends FragmentActivity implements CanvassCallback {

// save a single reference to ViewPager and TabsPagerAdapter
private ViewPager mViewPager;
private TabsPagerAdapter mAdapter;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.mViewPager = (ViewPager) findViewById(R.id.pager);
    this.mAdapter = new TabsPagerAdapter(getSupportFragmentManager(), this);
    mViewPager.setAdapter(mAdapter);

    ...
}

// from the CanvassCallback interface
public void itemSelected() {
    mAdapter.canvassSelected();
    mAdapter.notifyDataSetChanged();
}

    @Override
public void onBackPressed() {
    if (mViewPager.getCurrentItem() == 0 && mAdapter.isCanvassSelected() {
        mAdapter.canvassSelected();
        mAdapter.notifyDataSetChanged();
            }
            else {
                super.onBackPressed();
            }
}

}

显示回调的CanvassFragment样机

public class CanvassFragment extends SherlockFragment {

public interface CanvassCallback {
    public void itemSelected();
}

private CanvassCallback canvassCallback;

public void setCanvassCallback(CanvassCallback canvassCallback) {
    this.canvassCallback = canvassCallback;
}

...

// The onClick of your item
private void onClick() {
    // notify your activity that an item was selected
    canvassCallback.itemSelected();
}
}

注册片段不是严格需要的,但我认为如果您需要从活动中调用片段中的物品,它会提供一些价值。

public class TabsPagerAdapter extends FragmentStatePagerAdapter {

// see upvoted answer from http://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

private boolean canvassSelected = false; 

private CanvassCallback canvassCallback;

public TabsPagerAdapter(FragmentManager fm, CanvassCallback canvassCallback) {
    super(fm);
    this.canvassCallback = canvassCallback;
}

public void canvassSelected() {
    canvassSelected = !canvassSelected;
}

    public boolean isCanvassSelected() {
            return canvassSelected;
    }

@Override
public SherlockFragment getItem(int index) {

    switch (index) {
    case 0:
        if (canvassSelected) 
            return new ContactFragment();

        CanvassFragment canvassFragment = new CanvassFragment();
        // this ensures that your Activity gets notified when an item is clicked
        canvassFragment.setCanvassCallback(canvassCallback);
        return canvassFragment;
    case 1:
        return new TalkingPointsFragment();
    case 2:
        return new ContactFragment();
    }

    return null;
}

@Override
public int getCount() {
    // get item count - equal to number of tabs
    return 3;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    Log.d(TAG, "instantiateItem " + position);
    Fragment fragment = (Fragment) super.instantiateItem(container, position);
    registeredFragments.put(position, fragment);
    return fragment;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    Log.d(TAG, "destroyItem " + position);
    registeredFragments.remove(position);
    super.destroyItem(container, position, object);
}

}