Slider Menu片段中的可滑动选项卡

时间:2014-05-15 12:40:06

标签: android android-fragments android-tabs android-navigation android-sliding

我已经通过引用this tutorial实现了导航抽屉,现在我想要做的是在片段内显示滑动标签。即当我点击导航抽屉中的一个项目时,让我们说第一个项目,它应显示该项目的滑动标签。(我的列表视图中有6个片段。(同样: - A,B,C,D,E, F)。我在A Fragment上需要3个可交换的标签。)

如果item1是Events,当我点击它时,它应显示滑动标签。

但我面临以下问题: -

  1. 如何在片段内实现视图寻呼机?

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

  3. 当一个片段正在扩展FragmentActivity时,那么在我的主要活动中,代码显示错误,说明"类型不匹配",无法从A片段转换为片段。

  4. 这是我的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代码: -         包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>
    

3 个答案:

答案 0 :(得分:10)

您必须使用包含ViewPager的自定义布局创建片段。

按照以下步骤操作,它将指导整个过程。

1。创建表示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。创建一个片段来保存在上面的XML上声明的ViewPager,将其命名为MyFragment.java

如您所见,我们声明TabHost ViewPager以及上面XML中声明的其他元素。同样在这个片段中,我们膨胀之前创建的布局,并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)
        {
        }
    }
}

如您所见,每个标签都会调用一个特定的片段。这些片段代表每个选项卡的内容。因此,让我们创建它们,它们非常简单,只包含TextView

3。为第一个选项卡内容创建一个片段,将其命名为PageOneFragment.java

此片段将保留第一个标签的内容。您可以在此片段中放置任何内容,它将与其他片段和其他标签分开。

这里我们在onCreateView方法中扩充xml布局pageone_fragment.xml。我们将在下一步中创建这个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();
    }
}

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

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

这只是一个简单的布局,TextView代表选项卡的内容。您可以在此布局中构建任何所需的内容,它将与其他片段和选项卡分开。

<?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>

由于我们有两个标签,我们有两个片段,每个标签一个。因此,让我们为第二个标签内容创建第二个片段。

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

正如您所看到的,我们在onCreateView方法上夸大了不同的布局,它被称为pagetwo_fragment.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 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所做的那样,让我们​​也为第二个片段创建布局,如前所述。

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

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

<?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方法的switch声明中使用displayView(int position)来调用此片段,则应在case case 0: fragment = new MyFragment(); break; 方法中执行此操作例如,1}}语句。

ViewPager

这是最终结果

在片段上运行的{{1}},其中包含两个标签,每个标签都包含一个具有唯一内容的唯一片段。

enter image description here

那就是它。

希望这会对你有所帮助。

答案 1 :(得分:0)

对于步骤7中的错误&#34;输入不匹配

制作:

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();

答案 2 :(得分:-1)

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

mTab​​s变量的声明

感谢