Android典型界面设计(8) ——ViewPager+PagerSlidingTabStrip实现双导航

来源:互联网 发布:三菱plc编程指令大全 编辑:程序博客网 时间:2024/05/20 03:40
一、问题描述

  PagerSlidingTabStrip是android开源项目,指示器控件。官网地址:https://github.com/astuetz/PagerSlidingTabStrip

  该组件可和ViewPager结合实现效果不错的滑动式导航,最大特点是滑动条可跟随ViewPager联动,不过PagerSlidingTabStrip只有文字或图片两种,没有提供图片和文字的混合的形式,感觉更适合实现头部的导航,不太适合做底部导航(一般底部导航都是典型的上图下字的导航),不过可以通过修改源码来实现这种图文混合的导航,下面就使用ViewPager+PagerSlidingTabStrip实现如图所示效果:

二、修改PagerSlidingTabStrip组件

  PagerSlidingTabStrip提供文本指示器和图标指示器两种,即 tab 是 text 还是 icon。如果是 icon 的话,通过 Viewpager 的 adapter 实现接口IconTabProvider重写getPageIconResId方法:


public  class  MainPagerAdapter  extends  FragmentPagerAdapter   implements  IconTabProvider{        @Override        public  int  getPageIconResId(int position){            …}}

如果是Text的话,只需重写适配器自身的getPageTitle()方法:

public  class  MainPagerAdapter  extends  FragmentPagerAdapter  {        @Override        public  int  getPageTitle (int position){            …}}

这里我们还需要图文混排的指示器(底部导航需要),因此在源码做如下改动:

定义接口:

public  class  MainPagerAdapter  extends  FragmentPagerAdapter  {        @Override        public  int  getPageTitle (int position){            …}}

定义属性和set/get方法

private String[] tabTexts;//存储所有指示器的文本内容private int normalIconRes[];//存储所有指示器未选择的图标    private int lightIconRes[];//存储所有指示器已选择的图标修改notifyDataSetChanged()方法(红色部分为更改代码):for (int i = 0; i < tabCount; i++) {            if (pager.getAdapter() instanceof IconTabProvider) {                addIconTab(i, ((IconTabProvider) pager.getAdapter())                        .getPageIconResId(i));            } else if(pager.getAdapter() instanceof ViewTabProvider){                addViewTab(i, ((ViewTabProvider)pager.getAdapter()).getTabView(i));                }else {                addTextTab(i, pager.getAdapter().getPageTitle(i).toString());            }        }


  添加addViewTab()方法:实现将tab添加到指示器中,并为tab注册单击事件,当单击tab时ViewPager翻页,并调用updateTabStyles()更新Tab的样式

     private int currentIdx=0;//记录当前指示器的索引值private void addViewTab(final int position, View tab){        tab.setFocusable(true);        tab.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                pager.setCurrentItem(position);                currentIdx=position;                updateTabStyles();            }        });    tab.setPadding(tabPadding, 0, tabPadding, 0);    tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);    }复制代码

添加setSelectedTextColor()以便设置已选择指示器的字体颜色

private  int  tabSelectedTextColor;//表示已选择的文本字体颜色public  void  setSelectedTextColor(int color){        this.tabSelectedTextColor=color;        updateTabStyles();}

修改updateTabStyles()方法,红色部分为变更代码


if (v instance  of  TextView) {        TextView tab = (TextView) v;        tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);        tab.setTypeface(tabTypeface, tabTypefaceStyle);        tab.setTextColor(tabTextColor);        if(i==0 && tabSelectedTextColor!=0){                    tab.setTextColor(tabSelectedTextColor);            }            if (textAllCaps) {                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {                    tab.setAllCaps(true);                } else {                    tab.setText(tab.getText().toString().toUpperCase(locale));                }            }}else if(v  instanceof  ViewGroup){    ImageView tabIcon=(ImageView)v.findViewById(android.R.id.icon);    TextView tabTxt=(TextView)v.findViewById(android.R.id.title);    tabTxt.setText(tabTexts[i]);    if(currentIdx==i){            tabIcon.setImageResource(this.lightIconRes[i]);            tabTxt.setTextColor(tabSelectedTextColor);    }else{            tabTxt.setTextColor(tabTextColor);            tabIcon.setImageResource(this.normalIconRes[i]);        }    }    }
三、MainActivity部分,实现外层底部导航

1、MainActivity布局文件,指示器在底部

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity" >        <com.example.pagerslidingtabscripdemo.view.MyViewPager        android:id="@+id/newsPager"        android:layout_width="match_parent"        android:layout_height="wrap_content"         android:layout_above="@+id/newsTabs"        />        <com.astuetz.PagerSlidingTabStrip            android:id="@+id/newsTabs"            android:layout_width="match_parent"            android:layout_height="48dp"            android:background="@drawable/backgroud_tabs"            android:layout_alignParentBottom="true"            /></RelativeLayout>

2、重写ViewPager方法,实现禁止ViewPager滑动


public class MyViewPager extends ViewPager {    private boolean isPagingEnable=true;    public MyViewPager(Context context,AttributeSet attrs) {        super(context,attrs);    }    public MyViewPager(Context context){        super(context);    }    @Override    public boolean onTouchEvent(MotionEvent event){        return this.isPagingEnable&&super.onTouchEvent(event);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent event){        return this.isPagingEnable&&super.onInterceptTouchEvent(event);    }    public void setPagingEnabled(boolean enable){        this.isPagingEnable=enable;    }}

3、MainActivity代码:


private PagerSlidingTabStrip tabs;    private MyViewPager pages;    private List<Fragment> fragmentList;    private MainPagerAdapter adapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tabs=(PagerSlidingTabStrip)super.findViewById(R.id.newsTabs);        pages=(MyViewPager)super.findViewById(R.id.newsPager);        fragmentList=new ArrayList<Fragment>();        initView();            }        private void initView(){        initFragment();        adapter=new MainPagerAdapter(super.getSupportFragmentManager(),                fragmentList, this);        pages.setAdapter(adapter);        pages.setPagingEnabled(false);        tabs.setNormalIconRes(TabsData.normalIconRes);//设置未选择的图标        tabs.setLightIconRes(TabsData.lightIconRes);//设置已选择的图标        tabs.setTabTexts(TabsData.boards);//设置文本        tabs.setViewPager(pages);//与ViewPager关联,这样指示器就可以和ViewPager联动        tabs.setSelectedTextColor(Color.RED);//设置当前选择的tab的文本颜色        tabs.setIndicatorColor(Color.TRANSPARENT);//去除指示器的底部横线        tabs.setDividerColor(Color.TRANSPARENT);//去除tab间的分割线    }    private void initFragment(){        fragmentList=new ArrayList<Fragment>();        fragmentList.add(new NewsFragment());        for(int i=1;i<TabsData.boards.length;i++){            Bundle bundle=new Bundle();            bundle.putString("title", TabsData.boards[i]);            CommentFragment fragment=new CommentFragment();            fragment.setArguments(bundle);            fragmentList.add(fragment);        }    }


4、TabsData数据:


public class TabsData {    public  static  String[]  boards={"新闻","阅读","试听","发现"," 我"};    public  static int[]  normalIconRes={R.drawable.foot_news_normal,    R.drawable.foot_read_normal,R.drawable.foot_vdio_normal,R.drawable.foot_fond_normal,R.drawable.foot_out_normal};    Public  static  int[]  lightIconRes={R.drawable.foot_news_light,            R.drawable.foot_read_light,R.drawable.foot_vdio_light,            R.drawable.foot_found_light,R.drawable.foot_out_light}; }

5、MainPagerAdapter适配器:

public class MainPagerAdapter extends FragmentPagerAdapter implements ViewTabProvider {    private List<Fragment> fragmentList;    private Context context;    public MainPagerAdapter(FragmentManager fm,List<Fragment> fragmentList,Context context) {        super(fm);        this.fragmentList=fragmentList;        this.context=context;    }    @Override    public Fragment getItem(int arg0) {        return fragmentList.get(arg0);    }    @Override    public int getCount() {        return fragmentList.size();    }    @Override    public View getTabView(int position) {        View view=LayoutInflater.from(context).inflate(R.layout.footer_tabs, null);        return view;}}


6、CommentFragment代码:

public class CommentFragment extends Fragment {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    @Override    public void onAttach(Activity activity) {        super.onAttach(activity);    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,            Bundle savedInstanceState) {        TextView tvTitle=new TextView(super.getActivity());        tvTitle.setText(title);        tvTitle.setLayoutParams(new LayoutParams(                LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));        tvTitle.setGravity(Gravity.CENTER);        tvTitle.setTextSize(20);        return tvTitle;    }    private String title;    @Override    public void setArguments(Bundle bundle) {        title=bundle.getString("title");    }}

四、NewsFragment 实现内层头部导航

1、Xml文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity" >    <com.astuetz.PagerSlidingTabStrip        android:id="@+id/tabs"        android:layout_width="match_parent"        android:layout_height="48dp"        android:background="@drawable/backgroud_tabs"        />    <android.support.v4.view.ViewPager        android:id="@+id/pager"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        /></LinearLayout>

  注意:fragment中使用PagerSlidingTabStrip组件须采用LinearLayout布局,不能使用相对布局

2、代码:

public  class NewsFragment extends Fragment {    @Override    public void onAttach(Activity activity) {        super.onAttach(activity);    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    private View view;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,            Bundle savedInstanceState) {        if(view==null){            view=inflater.inflate(R.layout.news_fragment, null);            ViewPager pages=(ViewPager)view.findViewById(R.id.pager);            PagerSlidingTabStrip tabs=(PagerSlidingTabStrip)view.findViewById(R.id.tabs);            initFragment();            adapter=new ChannelPagerAdapter(super.getActivity().getSupportFragmentManager(),                    fragmentList, titles);            pages.setAdapter(adapter);            tabs.setViewPager(pages);            tabs.setSelectedTextColor(Color.RED);                        tabs.setDividerColor(Color.TRANSPARENT);            tabs.setIndicatorColor(Color.RED);        }        ViewGroup parent=(ViewGroup)view.getParent();        if(parent!=null){            parent.removeView(view);        }        return view;    }    private ChannelPagerAdapter adapter;    private List<Fragment> fragmentList;    private String[] titles={"头条","娱乐","体育","财经","热点","科技"};    private void initFragment(){        Fragment fragment=null;        fragmentList=new ArrayList<Fragment>();        for(String title: titles){            fragment=new ChannelNewsFragment();            Bundle bundle=new Bundle();            bundle.putString("title",title);            fragment.setArguments(bundle);            fragmentList.add(fragment);        }    }}

3、  ChannelNewsFragment

public class ChannelNewsFragment extends Fragment {    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    public void onAttach(Activity activity) {        super.onAttach(activity);    }    public View onCreateView(LayoutInflater inflater, ViewGroup container,            Bundle savedInstanceState) {        TextView tvTitle=new TextView(super.getActivity());        tvTitle.setText(title);        tvTitle.setLayoutParams(new LayoutParams(                LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));        tvTitle.setGravity(Gravity.CENTER);        tvTitle.setTextSize(20);        return tvTitle;    }    private String title;    public void setArguments(Bundle bundle) {        title=bundle.getString("title");    }}

 

作者:杰瑞教育
出处:http://blog.csdn.net/jerehedu
版权声明:本文版权归烟台杰瑞教育科技有限公司和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 
技术咨询:JRedu技术交流
0 0
原创粉丝点击