【问题标题】:How can I put titles in ViewPager using fragments?如何使用片段将标题放入 ViewPager?
【发布时间】:2012-04-06 00:39:14
【问题描述】:

我正在使用 ViewPager 允许用户在片段之间滑动。

如何在屏幕上添加每个片段的标题?

package com.multi.andres;

import java.util.List;
import java.util.Vector;

import com.viewpagerindicator.TitlePageIndicator;
import com.viewpagerindicator.TitleProvider;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

public class ViewPagerFragment extends FragmentActivity{

    private PagerAdapter mPagerAdapter; //contiene el pager adapter
    private static String[] titulosPaginas = { "APP 1", "APP 2" };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.lcmeter); //layout que contiene el ViewPager

        initialisePaging(); //inicializo las paginas
    }

    private void initialisePaging() {

        List<Fragment> fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this, FragmentPrueba1.class.getName()));
        fragments.add(Fragment.instantiate(this, FragmentPrueba2.class.getName()));
        this.mPagerAdapter  = new PagerAdapter(super.getSupportFragmentManager(), fragments);

        ViewPager pager = (ViewPager)super.findViewById(R.id.pager);
        pager.setAdapter(this.mPagerAdapter);

        //Agrega los titulos
        TitlePageIndicator titleIndicator = (TitlePageIndicator) findViewById(R.id.titulos);    //layout XML
        titleIndicator.setViewPager(pager);
    }

    /** *************************************************************************************************
    /** Clase:   public class PagerAdapter extends FragmentPagerAdapter implements TitleProvider
    /** Notas:   extends FragmentPagerAdapter permite el uso de las paginas de ViewPager pero con Fragments
    /**          implements TitleProvider permite el uso de los titulos en las paginas
    /** Funcion: crea paginas por las cuales deslizarse horizontalmente las cuales son usadas
    ****************************************************************************************************/
    public class PagerAdapter extends FragmentPagerAdapter implements TitleProvider {

        private List<Fragment> fragments;

        public String getTitle(int position) {
            // TODO Auto-generated method stub
            return titulosPaginas[position];    // titulo de la pagina
        }

        public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
        }

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

        @Override
        public Fragment getItem(int position) {
            return this.fragments.get(position);
        }

    }

}

但它没有显示 ViewPager 的标题,我不知道为什么。我之前使用 ViewPager 与标题,但没有与片段一起使用,我现在无法使标题正常工作。

【问题讨论】:

  • 你是说每个Tab都有自己的标题?

标签: java android android-fragments android-viewpager android-fragmentactivity


【解决方案1】:

您还可以使用 Jake Wharton 的 ViewPagerIndicator 库来获得所需的效果。 Davek804 的答案也有效,但它要求您引用整个 ActionBarSherlock 库,如果您只需要支持自定义/样式标题的 ViewPager,那么这不是可取的。

设置它以使其正常工作只需编写一小段 XML,在您的 Activity 中初始化您的 ViewPager,并实现 FragmentAdapter(其中 extends FragmentPagerAdapter implements TitleProvider)来指定哪些页面保存哪些页面Fragments.

  1. XML 布局

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.viewpagerindicator.TabPageIndicator
            android:id="@+id/titles"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"/>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    
    </LinearLayout>
    
  2. 在你的Activity中初始化

    //Set the pager with an adapter
    ViewPager pager = (ViewPager)findViewById(R.id.pager);
    pager.setAdapter(new CustomAdapter(getSupportFragmentManager()));
    
    //Bind the title indicator to the adapter
    TitlePageIndicator titleIndicator = (TitlePageIndicator) findViewById(R.id.titles);
    titleIndicator.setViewPager(pager);
    
  3. 实现CustomFragmentAdapter

    public static class CustomFragmentAdapter extends FragmentPagerAdapter 
            implements TitleProvider {
    
            public static final int POSITION_PAGE_1 = 0;
            public static final int POSITION_PAGE_2 = 1;
            public static final int POSITION_PAGE_3 = 2;
    
            private static final String[] TITLES = new String[] { 
                "Title 1", 
                "Title 2", 
                "Title 3" 
            };
    
            public static final int NUM_TITLES = TITLES.length;
    
            public CustomFragmentAdapter(FragmentManager fm) {      
                super(fm);
            }
    
            @Override
            public Fragment getItem(int position) {     
                switch (position) {
                case POSITION_TITLE_1:              
                    return PageOneFragment.newInstance();
                case POSITION_TITLE_2: 
                    return PageTwoFragment.newInstance();
                case POSITION_TITLE_3:
                    return PageThreeFragment.newInstance();         
                }
                return null;
            }
    
            @Override
            public int getCount() {
                return NUM_TITLES;
            }
    
            @Override
            public String getTitle(int position) {
                return TITLES[position % NUM_TITLES].toUpperCase();
            }
        }
    

编辑:

ViewPagerIndicator 库支持标题功能:

  1. TitlePageIndicator

  2. TabPageIndicator

  3. CirclePageIndicator

【讨论】:

  • 还请注意,在初始化ViewPager 时,还应考虑其他一些重要的方法。例如,pager.setOffscreenPageLimit(CustomFragmentAdapter.NUM_TITLES-1); 将防止您的ViewPager 破坏屏幕外的Fragments(您可能会或可能不会决定在您的应用程序中是否需要)。
  • 谢谢,但我必须如何在每个片段中创建 newInstance() 方法?完全有必要吗?如果你看一下我的程序,它似乎实例化了类,然后没有创建 newInstance()。你告诉我在 XML 中使用 TabPageIndicator 和 TitlePageIndicator 一样吗?
  • 抱歉……我从我写的应用程序中复制并粘贴了一些代码。如果您的 Fragment 不接受任何参数,那么您可以只为每个 Fragment 调用默认构造函数。
  • 我放了一个答案,因为必须放一些代码,请看一下:)
  • 看看我在 GitHub 上的一些代码。 MatchPagerActivity 在屏幕上显示ViewPager(在本例中为TabPagerIndicator),并设置xml file 中给出的屏幕布局。 MatchFragmentAdapter 作为 MatchPagerActivity 类中的一个内部嵌套类给出(参见页面底部的第一个链接)。
【解决方案2】:

或者如果你不喜欢从第三方库中使用,你可以使用支持 v4 PagerTabStrip 类。 例如:

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="0px"
    android:layout_weight="1">
    <android.support.v4.view.PagerTabStrip
        android:id="@+id/pts_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</android.support.v4.view.ViewPager>

并在 PagerAdapter 中重写 getPageTitle 方法:

public static class MyAdapter extends FragmentPagerAdapter  {
    ...
    @Override
    public CharSequence getPageTitle(int position) {
        return String.valueOf(position);
    }
}

您可以通过以下代码访问 xml 元素:

protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.pager);
    ...
    mAdapter = new MyAdapter(getSupportFragmentManager());
    // Add custom adapter
    mPager = (ViewPager)findViewById(R.id.pager);
    mPager.setAdapter(mAdapter);

    // Get PagerTabStrip
    PagerTabStrip strip = (PagerTabStrip) findViewById(R.id.pts_main);
    strip.setDrawFullUnderline(false);
    ...

希望对大家有所帮助

【讨论】:

  • 这是最简单方便的代码,只需几行代码即可在视图寻呼机中显示选项卡,无需使用任何第三方库。
【解决方案3】:

我说的是 SherlockFragmentActivity,你可以只使用 FragmentActivity。 getSupportActionBar 可以是 getActionBar()。

public class Polling extends SherlockFragmentActivity implements OnMenuItemClickListener {
    private ViewPager mViewPager;
    private TabsAdapter mTabsAdapter;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mViewPager = new ViewPager(this);
        mViewPager.setId(R.id.pager);
        setContentView(mViewPager);
        bar = getSupportActionBar();
        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        bar.setDisplayShowTitleEnabled(false);
        bar.setDisplayShowHomeEnabled(false);
        mTabsAdapter = new TabsAdapter(this, mViewPager);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.login),
                LoginFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.economics),
                EconFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.elections),
                ElectionsFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.politics),
                PoliticsFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.science),
                ScienceFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.finance),
                FinanceFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.religion),
                ReligionFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.military),
                MilitaryFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.international),
                InternationalFragment.class, null); 
    }

    public static class TabsAdapter extends FragmentPagerAdapter
    implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
        private final Context mContext;
        private final ActionBar mActionBar;
        private final ViewPager mViewPager;
        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

        static final class TabInfo {
            private final Class<?> clss;
            private final Bundle args;

            TabInfo(Class<?> _class, Bundle _args) {
                clss = _class;
                args = _args;
            }
        }

        public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
            super(activity.getSupportFragmentManager());
            mContext = activity;
            mActionBar = activity.getSupportActionBar();
            mViewPager = pager;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);
        }

        public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
            TabInfo info = new TabInfo(clss, args);
            tab.setTag(info);
            tab.setTabListener(this);
            mTabs.add(info);
            mActionBar.addTab(tab);
            notifyDataSetChanged();
        }

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

        public SherlockFragment getItem(int position) {
            TabInfo info = mTabs.get(position);
            return (SherlockFragment)Fragment.instantiate(mContext, info.clss.getName(), info.args);
        }

        public void onPageSelected(int position) {
            mActionBar.setSelectedNavigationItem(position);
        }
        public void onPageScrollStateChanged(int state) {}
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            mViewPager.setCurrentItem(tab.getPosition());
            //Log.v(TAG, "clicked");
            Object tag = tab.getTag();
            for (int i=0; i<mTabs.size(); i++) {
                if (mTabs.get(i) == tag) {
                    mViewPager.setCurrentItem(i);
                }
            }
        }
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
        public void onTabReselected(Tab tab, FragmentTransaction ft) {}
        public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {}
        public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {}
    }
}

【讨论】:

    【解决方案4】:

    @Alex Lockwood 谢谢 :) 我还有一个问题:/ 这是我的 XML:

    lcmeter.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >
        </android.support.v4.view.ViewPager>
    
        <com.viewpagerindicator.TitlePageIndicator
            android:id="@+id/titulos"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    

    如果在“android.support.v4.view.ViewPager”之前放置“TitlePageIndicator”,则在第一篇文章中使用我的原始代码,我可以看到标题,但我不能只单击标题更改页面而我的片段不是显示了,但是以这种方式显示了 XML,我可以浏览我的片段,但我看不到标题:/。我以这种方式尝试了 whit 构造函数:

    package com.multi.andres;
    
    import java.util.List;
    import java.util.Vector;
    
    import com.viewpagerindicator.TitlePageIndicator;
    import com.viewpagerindicator.TitleProvider;
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    import android.support.v4.view.ViewPager;
    
    public class ViewPagerFragment extends FragmentActivity{
    
        private PagerAdapter mPagerAdapter; //contiene el pager adapter
        String[] titulosPaginas = { "APP 1", "APP 2" };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            super.setContentView(R.layout.lcmeter); //layout que contiene el ViewPager
    
            initialisePaging(); //inicializo las paginas
        }
    
        private void initialisePaging() {
    
            List<Fragment> fragments = new Vector<Fragment>();
            fragments.add(Fragment.instantiate(this, FragmentPrueba1.class.getName()));
            fragments.add(Fragment.instantiate(this, FragmentPrueba2.class.getName()));
            this.mPagerAdapter  = new PagerAdapter(super.getSupportFragmentManager(), fragments);
    
            ViewPager pager = (ViewPager)super.findViewById(R.id.pager);
            pager.setAdapter(this.mPagerAdapter);
    
            //Agrega los titulos
            TitlePageIndicator titleIndicator = (TitlePageIndicator) findViewById(R.id.titulos);    //layout XML
            titleIndicator.setViewPager(pager);
        }
    
        /** *************************************************************************************************
        /** Clase:   public class PagerAdapter extends FragmentPagerAdapter implements TitleProvider
        /** Notas:   extends FragmentPagerAdapter permite el uso de las paginas de ViewPager pero con Fragments
        /**          implements TitleProvider permite el uso de los titulos en las paginas
        /** Funcion: crea paginas por las cuales deslizarse horizontalmente las cuales son usadas
        ****************************************************************************************************/
        public class PagerAdapter extends FragmentPagerAdapter implements TitleProvider {
    
            private List<Fragment> fragments;
    
            public String getTitle(int position) {
                // TODO Auto-generated method stub
                return titulosPaginas[position];    // titulo de la pagina
            }
    
            public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
                super(fm);
                this.fragments = fragments;
            }
    
            @Override
            public int getCount() {
                return this.fragments.size();
            }
    
            @Override
            public Fragment getItem(int position) {
                try {
                    FragmentPrueba1.class.newInstance();
                } catch (InstantiationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return this.fragments.get(position);
            }
    
        }
    
    }
    

    但是当我打开应用程序时我有一个 FC。这是我的片段两者都相等:

    package com.multi.andres;
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.LinearLayout;
    
    public class FragmentPrueba1 extends Fragment {
    
        FragmentPrueba1 (){
    
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
            return (LinearLayout)inflater.inflate(R.layout.prueba1, container, false);
    
        }
    
    }
    

    是XML片段:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" 
        android:background="#FF0000" >
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Numero 1 !!" />
    
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Esto es un boton XD" />
    
    </LinearLayout>
    

    我已阅读有关 Fragments 的信息,但我无法获得工作 Fragments 的标题,这没有意义:/ 我是新手,但我正在学习,对我来说非常复杂,非常感谢你的帮助真的很感激:)

    编辑:

    我想我已经找到了问题,它不是在 Java 代码上,问题是在 XML 文件 ViewPager 上:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >
        </android.support.v4.view.ViewPager>
    
        <com.viewpagerindicator.TitlePageIndicator
            android:id="@+id/titulos"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    

    这似乎“克服”了标题,因为如果我使用 Google 示例的 XML 文件,它在 android.support.v4.view.ViewPager 上添加了 android:layout_weight="1",我可以在底部看到标题屏幕,不是在顶部,而是一个进步:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多