如何使用ActionBar,ViewPager和Fragments并正确替换页面内的片段

时间:2014-03-29 21:32:10

标签: android-fragments android-actionbar android-viewpager fragmentpageradapter

我还是Android开发人员的新手,我尝试使用actionBar标签,滑动效果和片段开发应用。但是在过去的3天里,我没有解决在viewPager中替换片段的问题。我已经在几个网页上尝试了很多想法,但没有什么能帮助我解决这个问题。没有我的代码被浪费,因为如此多的替换,评论等等我已经删除它并开始一个新的。 但我想这次我需要了解片段的行为(State)PagerAdapter completly bevor我再次实现它。 所以我现在有几个问题。

1.是否可以使用actionbar和viewPager以及另外使用我可以在页面上替换另一个的片段?
2.是否可以保存这些替换的状态并切换到另一个寻呼机与之交互,更换相同的片段页面,然后返回上一页恢复页面?
3.我需要做些什么来实现这种行为?我真的需要覆盖哪些方法?我如何覆盖它们?
4.是否可以使用相同片段的所有页面实例?我需要一些东西来区分它们吗?那么我可以使用这个片段,从同一个类实例化,也是相同的xml布局文件? viewPager是否知道哪个页面iam当前要替换哪个页面的资源? 5.为什么只有教程只解释动作栏,或者只是用ViewPagerAdapter解释滑动,而是解释如何在viewpager和actionbar中替换片段。简单地结合这些教程?

所以我原谅我心情不好,但仍然被这个该死的问题所困扰。请原谅我的英语不好,我不是母语人士,只是使用我在学校的古老英语知识。 如果有人能帮助我,我会非常高兴,也许能给我一个例子。

请帮助,Justus

2014年3月30日编辑 以下是我目前正在使用的资料来源。

MainActivity.java:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
private ViewPager viewPager;
private ActionBar actionBar;
private Menue[] menuesDto;
private MyViewPagerAdapter myViewPagerAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle extras = getIntent().getExtras();
    String jsonString = extras.getString("jsonString");
    Gson g = new Gson();
    Type type = new TypeToken<Menue[]>() {
    }.getType();
    this.menuesDto = g.fromJson(jsonString, type);

    createTabBar();
}

@Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
    // Log.d("MyZooApp2", "onTabSelected at position " + tab.getPosition() +
    // " name " + tab.getTag());
    tab.setIcon(this.menuesDto[tab.getPosition()].getSelectedIcon());
    viewPager.setCurrentItem(tab.getPosition(), true);
}

@Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
    // Log.d("MyZooApp2", "onTabUnselected at position " + tab.getPosition()
    // + " name " + tab.getText());
    tab.setIcon(this.menuesDto[tab.getPosition()].getUnselectedIcon());
}

private void createTabBar() {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    setContentView(R.layout.activity_main);
    viewPager = (ViewPager) findViewById(R.id.pager);
    for (int i = 0; i < menuesDto.length; i++) {
        Menue menue = menuesDto[i];
        FragmentBuilder.setTabIconForChangeState(menue);
        String name = menue.getName();
        ActionBar.Tab tab = actionBar.newTab();
        tab.setText(name);
        tab.setIcon(menue.getUnselectedIcon());
        actionBar.addTab(tab);
    }

    myViewPagerAdapter = new MyViewPagerAdapter(getSupportFragmentManager(), this);
    viewPager.setAdapter(myViewPagerAdapter);
    viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int arg0) {
            // Log.d("MyZooApp2", "onPageSelected at position " + arg0);
            actionBar.setSelectedNavigationItem(arg0);
        }
    });
}

public MyViewPagerAdapter getMyViewPagerAdapter() {
    return myViewPagerAdapter;
}
}

MenueFragment.java:

public class MenueFragment extends Fragment implements ZooFragment, ResourceCaller {
private Menue menue;
private ListView listView;
private String[] navList;

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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.menue_fragment, container, false);
    init();
    if (menue.getNavs().size() > 0) {
        listView = (ListView) v.findViewById(R.id.list);
        new FileResourceLoader(menue, getActivity(), this).execute();
    } else {
        // createContentComponents();
    }
    return v;
}

public static MenueFragment newInstance() {
    MenueFragment f = new MenueFragment();
    return f;
}

@Override
public void init() {
    String jsonString = getArguments().getString("childNodes");
    Gson gson = new Gson();
    this.menue = gson.fromJson(jsonString, Menue.class);
    navList = new String[menue.getNavs().size()];
}

private void createNavigationComponents(List<Nav> navs) {
    listView.setAdapter(new ArrayAdapter<String>(getActivity(), R.layout.list_item, navList));
    listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            FragmentTransaction trans = getActivity().getSupportFragmentManager().beginTransaction();
            trans.replace(R.id.nav_here, new EmptyFragment());
            trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            trans.addToBackStack(null);
            trans.commit();
            ((MainActivity) getActivity()).getMyViewPagerAdapter().notifyDataSetChanged();
        }
    });
}
}

MyViewPAgerAdapter.java:

public class MyViewPagerAdapter extends FragmentStatePagerAdapter {

public static final int FRAGMENT1 = 0;
public static final int FRAGMENT2 = 1;
public static final int FRAGMENT3 = 2;
public static final int FRAGMENT4 = 3;
public static final int FRAGMENT5 = 4;

private final MainActivity mainActivity;
private ZooFragment[] fragments;

public MyViewPagerAdapter(FragmentManager fm, MainActivity mainActivity) {
    super(fm);
    this.mainActivity = mainActivity;
    fragments = new ZooFragment[mainActivity.getTabCount()];
}

@Override
public Fragment getItem(int position) {
    Menue menue = mainActivity.getMenuesDtoAtPos(position);
    switch (position) {
    case FRAGMENT1:
        if (fragments[FRAGMENT1] == null) {
            fragments[FRAGMENT1] = FragmentBuilder.getMenueFragment(mainActivity, menue);
        }
        break;
    case FRAGMENT2:
        if (fragments[FRAGMENT2] == null) {
            fragments[FRAGMENT2] = FragmentBuilder.getMenueFragment(mainActivity, menue);

        }
        break;
    case FRAGMENT3:
        if (fragments[FRAGMENT3] == null) {
            fragments[FRAGMENT3] = FragmentBuilder.getMenueFragment(mainActivity, menue);

        }
        break;
    case FRAGMENT4:
        if (fragments[FRAGMENT4] == null) {
            fragments[FRAGMENT4] = FragmentBuilder.getMenueFragment(mainActivity, menue);

        }
        break;
    case FRAGMENT5:
        if (fragments[FRAGMENT5] == null) {
            fragments[FRAGMENT5] = FragmentBuilder.getMenueFragment(mainActivity, menue);

        }
        break;
    }

    Log.d("MyZooApp2", "getItem: for Position: " + position + " added: " + menue.getName());

    return (Fragment) fragments[position];

}

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

两个layouts.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/nav_here"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:cacheColorHint="#DDEE22"
    android:divider="#55FFAA"
    android:scrollbarStyle="outsideOverlay" />

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#AA33EE"
android:orientation="vertical" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

我希望TisSarah的评论中会有人为我的问题提供另一种解决方案。

编辑31/03/2014: 如果像我们推荐的那样更改了Tab和viewpager监听器的Listener实现,并添加了一些LogCat输出。

VIA SWIPE:
03-31 19:10:05.914: D/MyZooApp2(5674): onTabUnselected at position 0 name Home
03-31 19:10:05.914: D/MyZooApp2(5674): onTabSelected at position 1 name null
03-31 19:10:05.924: D/MyZooApp2(5674): onPageSelected at position 1
03-31 19:10:06.895: D/MyZooApp2(5674): getItem: for Position: 2 added: Tiere
03-31 19:10:08.396: D/MyZooApp2(5674): onTabUnselected at position 1 name Zookarte
03-31 19:10:08.406: D/MyZooApp2(5674): onTabSelected at position 2 name null
03-31 19:10:08.406: D/MyZooApp2(5674): onPageSelected at position 2
03-31 19:10:09.187: D/MyZooApp2(5674): getItem: for Position: 3 added: Fütterung

VIA TAB SELECTION:
03-31 19:11:06.353: D/MyZooApp2(5674): onTabUnselected at position 2 name Tiere
03-31 19:11:06.353: D/MyZooApp2(5674): onTabSelected at position 0 name null
03-31 19:11:06.353: D/MyZooApp2(5674): getItem: for Position: 0 added: Home
03-31 19:11:06.984: D/MyZooApp2(5674): onTabReselected at position 0 name Home
03-31 19:11:06.984: D/MyZooApp2(5674): onPageSelected at position 0
03-31 19:11:11.488: D/MyZooApp2(5674): onTabUnselected at position 0 name Home
03-31 19:11:11.488: D/MyZooApp2(5674): onTabSelected at position 2 name null
03-31 19:11:11.498: D/MyZooApp2(5674): getItem: for Position: 2 added: Tiere
03-31 19:11:11.498: D/MyZooApp2(5674): getItem: for Position: 3 added: Fütterung

SWIPE + TAB SELECTION AND LISTITEM CLICKS:
03-31 19:18:27.123: D/MyZooApp2(9138): ListItem 0 on page Home clicked //After load item clicked -> Fragment replacement correct
03-31 19:18:38.094: D/MyZooApp2(9138): onTabUnselected at position 0 name Home
03-31 19:18:38.094: D/MyZooApp2(9138): onTabSelected at position 2 name null
03-31 19:18:38.134: D/MyZooApp2(9138): getItem: for Position: 2 added: Tiere //swiping to page 2 and click -> Fragment replacement incorrect. It´s replaced on page 1
03-31 19:18:38.154: D/MyZooApp2(9138): getItem: for Position: 3 added: Fütterung    //same page (2) and click -> Fragment replacement incorrect. It´s replaced on page 1
03-31 19:18:38.344: D/MyZooApp2(9138): onTabReselected at position 2 name Tiere
03-31 19:18:38.344: D/MyZooApp2(9138): onPageSelected at position 2
03-31 19:18:39.615: D/MyZooApp2(9138): ListItem 0 on page Tiere clicked  //swiping to page 0 and click -> Fragment replacement incorrect.It´s replaced on page 1
03-31 19:18:41.107: D/MyZooApp2(9138): onTabUnselected at position 2 name Tiere
03-31 19:18:41.107: D/MyZooApp2(9138): onTabSelected at position 1 name null
03-31 19:18:41.117: D/MyZooApp2(9138): onPageSelected at position 1
03-31 19:20:05.089: D/MyZooApp2(9138): onTabUnselected at position 1 name Zookarte
03-31 19:20:05.089: D/MyZooApp2(9138): onTabSelected at position 2 name null
03-31 19:20:05.089: D/MyZooApp2(9138): onPageSelected at position 2
03-31 19:20:06.550: D/MyZooApp2(9138): onTabUnselected at position 2 name Tiere
03-31 19:20:06.550: D/MyZooApp2(9138): onTabSelected at position 3 name null
03-31 19:20:06.560: D/MyZooApp2(9138): onPageSelected at position 3
03-31 19:20:07.020: D/MyZooApp2(9138): getItem: for Position: 4 added: Mehr
03-31 19:20:07.911: D/MyZooApp2(9138): onTabUnselected at position 3 name Fütterung
03-31 19:20:07.911: D/MyZooApp2(9138): onTabSelected at position 4 name null
03-31 19:20:07.921: D/MyZooApp2(9138): onPageSelected at position 4
03-31 19:20:09.763: D/MyZooApp2(9138): onTabUnselected at position 4 name Mehr
03-31 19:20:09.763: D/MyZooApp2(9138): onTabSelected at position 2 name null
03-31 19:20:09.853: D/MyZooApp2(9138): onTabReselected at position 2 name Tiere
03-31 19:20:09.853: D/MyZooApp2(9138): onPageSelected at position 2
03-31 19:20:11.074: D/MyZooApp2(9138): ListItem 0 on page Tiere clicked //a few swipes and tab selections done and back on page 0 and click -> Fragment replacement incorrect. It´s replaced on page 1
03-31 19:20:12.426: D/MyZooApp2(9138): onTabUnselected at position 2 name Tiere
03-31 19:20:12.436: D/MyZooApp2(9138): onTabSelected at position 1 name null
03-31 19:20:12.436: D/MyZooApp2(9138): onPageSelected at position 1
03-31 19:20:13.397: D/MyZooApp2(9138): onTabUnselected at position 1 name Zookarte
03-31 19:20:13.407: D/MyZooApp2(9138): onTabSelected at position 0 name null
03-31 19:20:13.407: D/MyZooApp2(9138): onPageSelected at position 0
03-31 19:20:14.878: D/MyZooApp2(9138): ListItem 0 on page Home clicked //only tab         selections back on page 0 and click -> Fragment replacement incorrect. It´s             replaced on page 1

Fragment setup:
page 0 -> Fragment1 (Home) layout: frag1.xml contains programmatically added listitems from a json response
page 1 -> Fragment1 (Zookarte) layout: frag1.xml contains only an imageview
page 2 -> Fragment1 (Tiere) layout: frag1.xml contains programmatically added listitems from a json response
page 3 -> Fragment1 (Fütterung) layout: frag1.xml contains only an imageview
page 4 -> Fragment1 (Mehr) layout: frag1.xml contains only an imageview

1 个答案:

答案 0 :(得分:1)

首先,我认为此链接可能对您非常有帮助:http://developer.android.com/training/implementing-navigation/lateral.html

  1. 是。 https://github.com/thecodepath/android_guides/wiki/ViewPager-with-FragmentPagerAdapter
  2. 是。您将像往常一样使用savedInstanceSTate
  3. 保存片段状态
  4. 查看以上链接,将其连接到操作栏标签栏 你需要创建一个TabListener
  5. 是的,只需让FragmentPagerAdapter创建相同片段的实例即可 如果你在你的身体膨胀,将膨胀相同的布局 onCreateView方法。视图寻呼机将处理跟踪 哪个实例在哪个页面上(你将在viewpager中)。
  6. 您需要在视图寻呼机中保留片段列表,以便这样做 你可以在getItem方法中返回适当的方法(我 通常使用switch语句和一些常量来跟踪 哪个片段返回哪个视图寻呼机位置。)
  7. 这有点令人沮丧,但你会得到它的支持!

    这是一个例子

    public class MyPagerAdapter extends FragmentPagerAdapter {
        public static final int FRAGMENT1 = 0;
        public static final int FRAGMENT2 = 1;
    
        private Fragment[] fragments;
    
        public MyPagerAdapter(Activity activity, FragmentManager fragmentManager) {
            super(fragmentManager);
           fragments = new Fragment[2];
        }
    
        @Override
        public Fragment getItem(int i) {
            switch(i){
                case FRAGMENT1:
                    if(fragment[FRAGMENT1] == null) {
                         fragment[FRAGMENT1] = new FragmentOne.createInstance();
                    }
                    break;
                case FRAGMENT2:
                    if(fragment[FRAGMENT2] == null) {
                         fragment[FRAGMENT2] = new FragmentTWO.createInstance();
                    }
                    break;
            }
            return fragments[i];
        }
    
        @Override
        public int getCount() {
            return fragments.length;
        }
    }
    

    您需要覆盖活动类中的侦听器:

    private ViewPager.OnPageChangeListener mPagerChangeListener
            = new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(0);
    
            ActionBar actionBar = getActionBar();
            actionBar.selectTab(actionBar.getTabAt(position));
        }
    };
    
    private ActionBar.TabListener mTabListener = new ActionBar.TabListener() {
        @Override
        public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
            mViewPager.setCurrentItem(tab.getPosition());
        }
    
        @Override
        public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
        }
    
        @Override
        public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
        }
    };