来自android.support.v4的ViewPager,TabHost和Fragments。一起工作并不起作用

时间:2012-01-12 12:27:43

标签: android android-tabhost fragment android-viewpager

我决定创建一个小型库,使用ViewPager,Tabhost和FragmentActivity创建出色的菜单。所以我有3个小班:

  1. 绘制菜单(绘制所有xml内容)

    public class DrawAMKMenu extends FragmentActivity {
    
    protected LinearLayout mLinearLayout;
    protected static TabHost mTabHost;
    protected static Context mContext;
    protected ViewPager mViewPager;
    protected RelativeLayout mMenuBar;
    protected Resources res;
    protected int screenwidth;
    
    protected Drawable ThumbResource = null;
    protected Drawable menuBg = null;
    protected TabWidget tw;
    
    
    
    /**
     * constructor
     * @param c
     * @param main_layout
     */
    protected DrawAMKMenu(FragmentActivity fa, LinearLayout main_layout){
        mContext = fa.getApplicationContext();
        mLinearLayout = main_layout;
        res = fa.getResources();
        Display display = fa.getWindowManager().getDefaultDisplay(); 
        screenwidth = display.getWidth();
    
    }
    
    /**
     *Draw main LinearLayout 
     */
    protected void DrawMenu()
    {
        mLinearLayout.removeAllViews();
        mLinearLayout.setBaselineAligned(true);
        mLinearLayout.setOrientation(LinearLayout.VERTICAL);
        mLinearLayout.addView(createTabHost());
    }
    /**
     * @return TabHost
     * draw the TabHost view
     */
    protected TabHost createTabHost(){
    
        mTabHost = new TabHost(mContext);
        mTabHost.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
    
    
        mTabHost.addView(createTabContentLayout());
        mTabHost.addView(createViewPager());
        mTabHost.addView(createMenuBar());  
    
        mTabHost.setTag("TabHost");
        SetupTabs(mTabHost);
    
    
    
        return mTabHost;
    }
    /**
     * Create FrameLayout for Content
     * @return FrameLayout
     */
    protected FrameLayout createTabContentLayout(){
        /*Frame layout for Content*/
        FrameLayout fl = new FrameLayout(mContext); 
        fl.setLayoutParams(new LinearLayout.LayoutParams(0,0,1));
        fl.setId(android.R.id.tabcontent);
        /*------------------------*/
        return fl;
    }
    
    /**
     * @return ViewPager
     * draw ViewPager element
     */
    protected ViewPager createViewPager(){
        mViewPager = new ViewPager(mContext);
        mViewPager.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT,1));
        mViewPager.setBackgroundColor(Color.WHITE);
        mViewPager.setTag("viewpager");
        return mViewPager;
    }  
    
    /**
     * @return RelativeLayout
     * draw Menu bar 
     */
    protected RelativeLayout createMenuBar(){
        /* Layout for Menu Bar */
        mMenuBar = new RelativeLayout(mContext);
        mMenuBar.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        //mMenuBar.setGravity(Gravity.BOTTOM);
    
        /* ------------------ */
    
        /* Tab Widget*/
        tw =  new TabWidget(mContext);
        tw.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT,0));
        tw.setOrientation(LinearLayout.HORIZONTAL);
    
        tw.setId(android.R.id.tabs);
        if(menuBg != null)
            tw.setBackgroundDrawable(menuBg);
        /*-----------*/
    
        /* Scroll bar for menu */
        HorizontalScrollView hsv = new HorizontalScrollView(mContext);
        hsv.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT,0));
        hsv.setScrollBarStyle(View.GONE);
        hsv.setFillViewport(true);
        /* ----------------- */
    
        //add tabWidget to HorizontalScrollView
        hsv.addView(tw);
    
        /*Seek Bar*/
        SeekBar sb = new SeekBar(mContext);
        sb.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        sb.setBackgroundColor(Color.TRANSPARENT);
        sb.setProgressDrawable(res.getDrawable(android.R.id.empty));
    
        if(ThumbResource!=null)
            sb.setThumb(ThumbResource);
        else
            sb.setThumb(res.getDrawable(android.R.id.empty));
        /*-------*/
    
    
        /*Frame layout for SeekBar*/
        FrameLayout fl = new FrameLayout(mContext);
        fl.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        fl.addView(sb);
        /*------------------------*/
    
    
        mMenuBar.addView(hsv);
        mMenuBar.addView(fl);
        return mMenuBar;
    
    }
    
    /**
     * Delete bottom strip from tabhost
     * @param tabHost
     */
    protected void SetupTabs(TabHost tabHost) {
    
        Field mBottomLeftStrip;
        Field mBottomRightStrip;
    
        try {
            mBottomLeftStrip = tw.getClass().getDeclaredField("mBottomLeftStrip");
            mBottomRightStrip = tw.getClass().getDeclaredField("mBottomRightStrip");
    
            if (!mBottomLeftStrip.isAccessible()) {
                mBottomLeftStrip.setAccessible(true);
            }
    
            if (!mBottomRightStrip.isAccessible()) {
                mBottomRightStrip.setAccessible(true);
            }
    
            mBottomLeftStrip.set(tw,  res.getDrawable(Color.TRANSPARENT));
            mBottomRightStrip.set(tw, res.getDrawable(Color.TRANSPARENT));
    
        } 
        catch (java.lang.NoSuchFieldException e) {
            // possibly 2.2
            try {
                Method stripEnabled = tw.getClass().getDeclaredMethod("setStripEnabled", boolean.class);
                stripEnabled.invoke(tw, false);
            } 
            catch (Exception e1) {
                e1.printStackTrace();
            }
        } 
        catch (Exception e) {}
    }
    
    
    
    }
    
  2. PagerAdapter类

    public class PagerAdapter extends FragmentPagerAdapter 
    
    private List<Fragment> pFragments;
    
    /**
     * @param fm
     * @param fragments
     */
    public PagerAdapter(FragmentManager fm, List<Fragment> fr) {
        super(fm);
        this.pFragments = fr;
    }
    
    /* (non-Javadoc)
     * @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
     */
    @Override
    public Fragment getItem(int position) {
        return this.pFragments.get(position);
    }
    
    /* (non-Javadoc)
     * @see android.support.v4.view.PagerAdapter#getCount()
     */
    @Override
    public int getCount() {
        return this.pFragments.size();
    }
    }
    
  3. 创建菜单类。

  4. 公共类AMKMenu扩展DrawAMKMenu实现TabHost.OnTabChangeListener,ViewPager.OnPageChangeListener {

    private PagerAdapter mPagerAdapter;
    private Vector<Fragment> fragments;
    private FragmentManager mFragmentManager;
    private FragmentActivity mFragmentActivity;
    private static HashMap<Integer, Class<?>> TabsClass;
    private static HashMap<Integer, String> TabsTabName;
    private static HashMap<Integer, Drawable> TabsIcon;
    
    
    /**
     * CONSTRUCTOR
     * Create AMKMenu object to setup settings and 
     * also initialize menu 
     * @param c
     * @param main_layout
     * @param fm 
     * @param screenWidth
     */
    public AMKMenu(FragmentActivity fa, LinearLayout main_layout) {
        super(fa, main_layout);
        mFragmentActivity = fa;
        mFragmentManager = fa.getSupportFragmentManager();
        TabsClass = new HashMap<Integer, Class<?>>();
        TabsTabName = new HashMap<Integer, String>();
        TabsIcon = new HashMap<Integer, Drawable>();
    
    }
    
    
    /**
     * Final method to create menu
     * Use it after you setup all settings
     */
    public void createMenu(){
        super.DrawMenu();
        initializeTabHost();
        intializeViewPager();
    
    }
    /**
     * A simple factory that returns dummy views to the Tabhost
     * @author Gavryschuk Anatoliy V.
     */
    public class TabFactory implements TabContentFactory {
    
        private final Context fContext;
    
        /**
         * @param context
         */
        public TabFactory(Context context) {
            fContext = context;
        }
    
        /** (non-Javadoc)
         * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
         */
        public View createTabContent(String tag) {
            View v = new View(fContext);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }
    
    }
    /**
     * Initialize ViewPager
     */
    protected void intializeViewPager() {
        fragments = new Vector<Fragment>();
        if(getTabsClass().size()>0)
        {
            for(int i=0;i<getTabsClass().size();i++)
            {
                fragments.add(Fragment.instantiate(mFragmentActivity, getTabsClass(i).getName()));
            }
        }
    
        setPagerAdapter(new PagerAdapter (mFragmentManager, fragments));
        mViewPager.setAdapter(getPagerAdapter());
        mViewPager.setOnPageChangeListener(this);
    }
    /**
     * Initialize the Tab Host
     */
    protected void initializeTabHost() {
        if(getTabsClass().size()>0)
        {
    
            TabHost mTabHost = (TabHost) mLinearLayout.findViewWithTag("TabHost");
            mTabHost.setup();
            for(int i=0;i<getTabsClass().size();i++)
            {
                TabSpec tabSpec = mTabHost.newTabSpec(getTabsTabName(i));
                tabSpec.setIndicator(getTabsTabName(i), getTabsIcon(i));
                tabSpec.setContent(new TabFactory(mFragmentActivity));
                mTabHost.addTab(tabSpec);
            }
    
            mTabHost.setOnTabChangedListener(this);
            mTabHost.getTabWidget().setHorizontalScrollBarEnabled(false);
    
            for(int i=0;i<mTabHost.getTabWidget().getChildCount();i++)
            {
                //mTabHost.getTabWidget().getChildAt(i).setLayoutParams(new LinearLayout.LayoutParams(65,65));
                mTabHost.getTabWidget().getChildAt(i).setBackgroundResource(0);
            }
    
    
            //  mTabHost.setCurrentTab(0);
        }else
            return;
    }...
    }
    

    以这种方式使用这个库之后

    AMKMenu menu = new AMKMenu(this, (LinearLayout)findViewById(R.id.main_layout));
    
        menu.setMenuBg(getResources().getDrawable(R.drawable.menu_bg));
        menu.setCursor(getResources().getDrawable(R.drawable.new_cursor));
    
        menu.AddTab(Tab1Fragment.class, "tab1", getResources().getDrawable(R.drawable.f_icon));
        menu.AddTab(Tab2Fragment.class, "tab2", getResources().getDrawable(R.drawable.s_icon));
        menu.AddTab(Tab3Fragment.class, "tab3", getResources().getDrawable(R.drawable.t_icon)); 
        menu.createMenu();
    

    我收到错误

      

    java.lang.IllegalArgumentException:找不到片段

    的id的新内容

    问题在于AMKMenu类中的intializeViewPager()方法。

    请有人(Android大师)帮助我,我做错了什么? 我希望我能清楚地解释一切。

1 个答案:

答案 0 :(得分:3)

听到我的解决方案(Tabs + Fragment + ViewPager)它对我来说很有用,希望对你有用

听到的是xml文件

<LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_weight="5" />

        <FrameLayout
            android:id="@+id/fragment_details"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="4.3" />
    </LinearLayout>

听到是MainActivity.java的代码我只发布相关代码,所以你必须管理它

public class MainActivity extends FragmentActivity implements
        DialogInterface.OnDismissListener, TabDataResponder {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        artistTab = getSupportActionBar().newTab().setText(
                R.string.tab_name_artist);
        albumTab = getSupportActionBar().newTab().setText(
                R.string.tab_name_album);
        songTab = getSupportActionBar().newTab().setText(
                R.string.tab_name_songs);

        map = new HashMap<String, Integer>();
        mViewPager = (ViewPager) findViewById(R.id.pager);
        FrameLayout deatil = (FrameLayout) findViewById(R.id.fragment_details);
        mDualPane = (deatil != null) && (deatil.getVisibility() == View.VISIBLE);
        mTabsAdapter = new TabsAdapter(this, getSupportActionBar(), mViewPager);

        if (savedInstanceState != null) {
            flag = true;
            index = savedInstanceState.getInt("index");
        }

        setUpTabView();

    }


    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("index", getSupportActionBar()
                .getSelectedNavigationIndex());
    }

    private void setUpTabView() {
        mTabsAdapter.addTab(artistTab, ArtistFragment.class, null);
        mTabsAdapter.addTab(albumTab, AlbumFragment.class, null);
        mTabsAdapter.addTab(songTab, SongFragment.class, null);
        getSupportActionBar().setSelectedNavigationItem(index);
    }

    public static class TabsAdapter extends FragmentPagerAdapter implements
            ViewPager.OnPageChangeListener, ActionBar.TabListener {

        private FragmentActivity mContext;
        private ActionBar mActionBar;
        private final ViewPager mViewPager;

        private final ArrayList<String> mTabs = new ArrayList<String>();
        private TabDataResponder responder;

        public TabsAdapter(FragmentActivity activity, ActionBar actionBar,
                ViewPager pager) {

            super(activity.getSupportFragmentManager());
            mContext = activity;
            mActionBar = actionBar;
            mViewPager = pager;

            // TabDataResponder is an interface which is implemented in MainActivity
            // You can find implementation @ the last

            responder = (TabDataResponder) activity;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);

            //I have used map to save state of the fragment
            map.put(SongFragment.TYPE_FRAGMENT.trim(), 0);
            map.put(AlbumFragment.TYPE_FRAGMENT.trim(), 0);
            map.put(ArtistFragment.TYPE_FRAGMENT.trim(), 0);
        }

        public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
            mTabs.add(clss.getName());
            // mArgs.add(args);
            mActionBar.addTab(tab.setTabListener(this));
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return mTabs.size();
        }

        @Override
        public Fragment getItem(int position) {
            return Fragment
                    .instantiate(mContext, mTabs.get(position), /*
                                                                 * mArgs.get(
                                                                 * position)
                                                                 */null);
        }

        @Override
        public void onPageScrolled(int position, float positionOffset,
                int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            Log.i(TAG, "PageSelected....");
            mActionBar.setSelectedNavigationItem(position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            Log.i(TAG, "ScrollSateChanged....");
        }

        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
        }

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            mViewPager.setCurrentItem(tab.getPosition());
            String a = null;
            if (mDualPane) {
                a = mTabs.get(tab.getPosition());
                responder.loadData(a, map.get(a));
            }
        }

        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            Log.i(TAG, "Tab is released now....");
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        setUpTabView();

    }
//This interface must be call from fragment class 
//@ the time of event you want to show detail 
// pass the class name in the type argument using class.getName() method
    @Override
    public void loadData(String type, int index) {
        DetailFragment viewer = (DetailFragment) getSupportFragmentManager()
                .findFragmentById(R.id.fragment_details);
        if (mDualPane) {
            if (viewer == null || viewer.getShownIndex() != index
                    || viewer.getTypeFragment() != type) {

                DetailFragment df = DetailFragment.newInstance(index, type);
                getSupportFragmentManager()
                        .beginTransaction()
                        .replace(R.id.fragment_details, df)
                        .setTransition(
                                FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                        .commit();
                map.put(type.trim(), index);

            }

        } else {
            Intent intent = new Intent();
            intent.setClass(MainActivity.this, DetailActivity.class);
            intent.putExtra("index", index);
            intent.putExtra("type", type);
            startActivity(intent);
        }
    }
}

并且听说我是如何处理细节片段效率不高但工作有点

public class DetailFragment extends Fragment{

    public static DetailFragment newInstance(int index, String  TYPE_FRAGMENT) {
        DetailFragment f = new DetailFragment();

        // Supply index input as an argument.
        Bundle args = new Bundle();
        args.putInt("index", index);
        args.putString("type", TYPE_FRAGMENT);
        f.setArguments(args);

        return f;
    }



    public int getShownIndex() {
        return getArguments().getInt("index", 0);
    }

    public String getTypeFragment(){
        String a = getArguments().getString("type");
        return a;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        //template is blank layout
        View view =  inflater.inflate(R.layout.template, container, false);
        if(getTypeFragment().equals(ArtistFragment.TYPE_FRAGMENT)){
            view = null;
            view = inflater.inflate(R.layout.artist_details, container, false);
            //....

        }
        else if(getTypeFragment().equals(AlbumFragment.TYPE_FRAGMENT)){

            //do's for album fragment
        }
        else if(getTypeFragment().equals(SongFragment.TYPE_FRAGMENT)){
            //do's for song fragment
        }
        return view;
    }

}

不要将标签状态保存在各自的片段中会发生冲突,我们已经在听取了

希望它有助于