滑块菜单片段中的Swapable选项卡

我已经实现了导航抽屉通过参考本教程 ,现在我想要做的是在片段内显示滑动标签。 (也就是说: – A,B,C,D,E, F),我的A片段需要3个swapable选项卡。)

如果item1是事件,当我点击它,那么它应该显示滑动选项卡。

但我面临以下问题:

  1. 我怎样才能实现查看页面里面的片段?

  2. 片段可能会扩展片段。

  3. 当一个片段扩展了FragmentActivity,那么在我的主要活动中,代码显示一个错误,说“types不匹配”,不能从A片段转换成片段。

这是我的Deep.java文件

package com.amar.demo; import info.androidhive.slidingmenu.adapter.NavDrawerListAdapter; import info.androidhive.slidingmenu.model.NavDrawerItem; import java.util.ArrayList; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; public class Deep extends Activity { private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; // nav drawer title private CharSequence mDrawerTitle; // used to store app title private CharSequence mTitle; // slide menu items private String[] navMenuTitles; private TypedArray navMenuIcons; private ArrayList<NavDrawerItem> navDrawerItems; private NavDrawerListAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.deep); mTitle = mDrawerTitle = getTitle(); // load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items); // nav drawer icons from resources navMenuIcons = getResources() .obtainTypedArray(R.array.nav_drawer_icons); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.list_slidermenu); navDrawerItems = new ArrayList<NavDrawerItem>(); // adding nav drawer items to array // Home navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons .getResourceId(0, -1))); // Find People navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons .getResourceId(1, -1))); // Photos navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons .getResourceId(2, -1))); // Communities, Will add a counter here navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons .getResourceId(3, -1), true, "22")); // Pages navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons .getResourceId(4, -1))); // What's hot, We will add a counter here navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons .getResourceId(5, -1), true, "50+")); // Recycle the typed array navMenuIcons.recycle(); mDrawerList.setOnItemClickListener(new SlideMenuClickListener()); // setting the nav drawer list adapter adapter = new NavDrawerListAdapter(getApplicationContext(), navDrawerItems); mDrawerList.setAdapter(adapter); // enabling action bar app icon and behaving it as toggle button getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, // nav menu toggle icon R.string.app_name, // nav drawer open - description for // accessibility R.string.app_name // nav drawer close - description for // accessibility ) { public void onDrawerClosed(View view) { getActionBar().setTitle(mTitle); // calling onPrepareOptionsMenu() to show action bar icons invalidateOptionsMenu(); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle(mDrawerTitle); // calling onPrepareOptionsMenu() to hide action bar icons invalidateOptionsMenu(); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); if (savedInstanceState == null) { // on first time display view for first nav item displayView(0); } } /** * Slide menu item click listener * */ private class SlideMenuClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // display view for selected nav drawer item displayView(position); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.testmenu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // toggle nav drawer on selecting action bar app icon/title if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } // Handle action bar actions click switch (item.getItemId()) { case R.id.a_More: return true; default: return super.onOptionsItemSelected(item); } } /* * * Called when invalidateOptionsMenu() is triggered */ @Override public boolean onPrepareOptionsMenu(Menu menu) { // if nav drawer is opened, hide the action items boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.a_More).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); } /** * Diplaying fragment view for selected nav drawer list item * */ private void displayView(int position) { // update the main content by replacing fragments Fragment fragment = null; switch (position) { case 0: fragment = new HomeFragment(); break; case 1: fragment = new FindPeopleFragment(); break; case 2: fragment = new PhotosFragment(); break; case 3: fragment = new CommunityFragment(); break; case 4: fragment = new PagesFragment(); break; case 5: fragment = new WhatsHotFragment(); break; default: break; } if (fragment != null) { FragmentManager fragmentManager = getFragmentManager(); // fragmentManager.beginTransaction() // .replace(R.id.frame_container, fragment).commit(); // update selected item and title, then close the drawer mDrawerList.setItemChecked(position, true); mDrawerList.setSelection(position); setTitle(navMenuTitles[position]); mDrawerLayout.closeDrawer(mDrawerList); } else { // error in creating fragment Log.e("MainActivity", "Error in creating fragment"); } } @Override public void setTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle); } /** * When using the ActionBarDrawerToggle, you must call it during * onPostCreate() and onConfigurationChanged()... */ @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggls mDrawerToggle.onConfigurationChanged(newConfig); } } 

在这个代码中,我遇到了情况0的问题。

这是我的HomeFragment代码: – package com.amar.demo;

 import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.FragmentTransaction; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.amar.demo.adapter.TabsPagerAdapter; public class HomeFragment extends FragmentActivity implements ActionBar.TabListener { private ViewPager viewPager; private TabsPagerAdapter mAdapter; private ActionBar actionBar; // Tab titles private String[] tabs = { "My Restaurant", "Offers", "Search & Book", "News & Updates" }; public HomeFragment() { } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_home, container, false); // code of tabes viewPager = (ViewPager) rootView.findViewById(R.id.pager); actionBar = getActionBar(); mAdapter = new TabsPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(mAdapter); actionBar.setHomeButtonEnabled(false); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Adding Tabs for (String tab_name : tabs) { actionBar.addTab(actionBar.newTab().setText(tab_name) .setTabListener(this)); } /** * on swiping the viewpager make respective tab selected * */ viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { // on changing the page // make respected tab selected actionBar.setSelectedNavigationItem(position); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); return rootView; } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { // TODO Auto-generated method stub } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { // TODO Auto-generated method stub } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { // TODO Auto-generated method stub } } 

这是我的deep.xml代码: –

  <!-- Framelayout to display Fragments --> <FrameLayout android:id="@+id/frame_container" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- Listview to display slider menu --> <ListView android:id="@+id/list_slidermenu" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="@color/list_background" android:choiceMode="singleChoice" android:divider="@color/list_divider" android:dividerHeight="1dp" android:listSelector="@drawable/list_selector" /> </android.support.v4.widget.DrawerLayout> 

这是我的homefragment.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="match_parent"> </android.support.v4.view.ViewPager> 

Solutions Collecting From Web of "滑块菜单片段中的Swapable选项卡"

您必须创build一个包含ViewPager的自定义布局的片段。

按照这些步骤,它将在整个过程中引导。

1.创build表示ViewPager的布局,将其命名为fragment_main.xml

 <TabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TabWidget android:id="@android:id/tabs" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0"/> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="0"/> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> </TabHost> 

2.创build一个片段来保存在上面的XML上声明的ViewPager,将其命名为MyFragment.java

正如你所看到的,我们在上面的XML中声明了ViewPager和其他元素。 同样在这个片段中,我们膨胀之前创build的布局,以及一个TabAdapter来处理所有的选项卡。

 import android.content.Context; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TabHost; import android.widget.TabWidget; import java.util.ArrayList; public static class MyFragment extends Fragment { private TabHost mTabHost; private ViewPager mViewPager; private TabsAdapter mTabsAdapter; public MyFragment() { } @Override public void onCreate(Bundle instance) { super.onCreate(instance); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_main, container, false); mTabHost = (TabHost) v.findViewById(android.R.id.tabhost); mTabHost.setup(); mViewPager = (ViewPager) v.findViewById(R.id.pager); mTabsAdapter = new TabsAdapter(getActivity(), mTabHost, mViewPager); // Here we load the content for each tab. mTabsAdapter.addTab(mTabHost.newTabSpec("one").setIndicator("One"), PageOneFragment.class, null); mTabsAdapter.addTab(mTabHost.newTabSpec("two").setIndicator("Two"), PageTwoFragment.class, null); return v; } public static class TabsAdapter extends FragmentPagerAdapter implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener { private final Context mContext; private final TabHost mTabHost; private final ViewPager mViewPager; private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); static final class TabInfo { private final String tag; private final Class<?> clss; private final Bundle args; TabInfo(String _tag, Class<?> _class, Bundle _args) { tag = _tag; clss = _class; args = _args; } } static class DummyTabFactory implements TabHost.TabContentFactory { private final Context mContext; public DummyTabFactory(Context context) { mContext = context; } public View createTabContent(String tag) { View v = new View(mContext); v.setMinimumWidth(0); v.setMinimumHeight(0); return v; } } public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) { super(activity.getSupportFragmentManager()); mContext = activity; mTabHost = tabHost; mViewPager = pager; mTabHost.setOnTabChangedListener(this); mViewPager.setAdapter(this); mViewPager.setOnPageChangeListener(this); } public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) { tabSpec.setContent(new DummyTabFactory(mContext)); String tag = tabSpec.getTag(); TabInfo info = new TabInfo(tag, clss, args); mTabs.add(info); mTabHost.addTab(tabSpec); notifyDataSetChanged(); } @Override public int getCount() { return mTabs.size(); } @Override public Fragment getItem(int position) { TabInfo info = mTabs.get(position); return Fragment.instantiate(mContext, info.clss.getName(), info.args); } public void onTabChanged(String tabId) { int position = mTabHost.getCurrentTab(); mViewPager.setCurrentItem(position); } public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } public void onPageSelected(int position) { // Unfortunately when TabHost changes the current tab, it kindly // also takes care of putting focus on it when not in touch mode. // The jerk. // This hack tries to prevent this from pulling focus out of our // ViewPager. TabWidget widget = mTabHost.getTabWidget(); int oldFocusability = widget.getDescendantFocusability(); widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); mTabHost.setCurrentTab(position); widget.setDescendantFocusability(oldFocusability); } public void onPageScrollStateChanged(int state) { } } } 

正如你所看到的,每个选项卡调用一个特定的片段。 这些片段代表每个选项卡的内容。 所以我们来创build它们,它们非常简单,只包含一个TextView

3.为第一个标签内容创build一个片段,将其命名为PageOneFragment.java

这个片段将保存第一个选项卡的内容。 你可以把任何东西放在这个片段中,它将与其他片段和其他标签分离。

在这里,我们在onCreateView方法中膨胀xml布局pageone_fragment.xml。 我们将在下一步创build这个xml布局。

 import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class PageOneFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.pageone_fragment, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onAttach(Activity activity) { super.onAttach(activity); } @Override public void onStart() { super.onStart(); } @Override public void onResume() { super.onResume(); } } 

我们必须像前面提到的那样创build这个片段的布局。

4.为PageOneFragment创build布局,将其命名为pageone_fragment.xml

这只是一个简单的布局,使用TextView来表示选项卡的内容。 你可以在这个布局中创build任何你想要的东西,它将与其他的片段和标签分开。

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/first_fragment" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:background="#ff4063ff"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="First Page" android:textColor="#FFFFFF" android:textStyle="bold" android:id="@+id/firstFragmentTextView" android:layout_gravity="center_horizontal|top" /> </LinearLayout> 

由于我们有两个标签,我们有两个片段,每个标签一个。 所以,让我们为第二个标签内容创build第二个片段。

5.为第二个选项卡内容创build片段,将其命名为PageTwoFragment.java

正如你所看到的,我们在onCreateView方法上膨胀了一个不同的布局,它被称为pagetwo_fragment.xml 。 我们将在下一步创build它。

 import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class PageTwoFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.pagetwo_fragment, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onAttach(Activity activity) { super.onAttach(activity); } @Override public void onStart() { super.onStart(); } @Override public void onResume() { super.onResume(); } } 

正如我们之前为PageOneFragment所做的那样,让我们​​为第二个片段创build布局,就像我们之前提到的一样。

6.为PageTwoFragment创build布局,将其命名为pagetwo_fragment.xml

这是一个带有单个TextView的简单布局,只是为了表示内容。 你可以在这里build立任何你想要的东西,它将与其他的片段和标签分开。

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/first_fragment" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:background="#ff4063ff"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="Second Page" android:textColor="#FFFFFF" android:textStyle="bold" android:id="@+id/firstFragmentTextView" android:layout_gravity="center_horizontal|top" /> </LinearLayout> 

7.从你的NavigationDrawer调用这个片段

如果你想从你的NavigationDrawer调用这个片段,在你的activity的displayView(int position)方法的switch语句中,你应该在你的一个case语句中这样做。

 case 0: fragment = new MyFragment(); break; 

这是最后的结果

运行在片段上的ViewPager ,每个片段都包含一个唯一片段,并带有唯一的内容。

在这里输入图像说明

而已。

希望这可以帮助你。

对于步骤7中的错误“types不匹配”

做了:

 replace **import android.app.Fragment** to **import android.support.v4.app.Fragment** 

并在以下情况下:

 android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit(); 
 public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) { tabSpec.setContent(new DummyTabFactory(mContext)); String tag = tabSpec.getTag(); TabInfo info = new TabInfo(tag, clss, args); mTabs.add(info); mTabHost.addTab(tabSpec); notifyDataSetChanged(); } 

在哪里声明mTabsvariables

谢谢