转载

Android典型界面设计——ViewPage+Fragment实现区域顶部tab滑动切换

一、问题描述

本系列将结合案例应用,陆续向大家介绍一些Android典型界面的设计,首先说说tab导航,导航分为一层和两层(底部区块+区域内头部导航),主要实现方案有RadioGroup+ViewPage+Fragment、Viewpager Indicator、ActionBar Tabs、FragmentTabHost+Fragment等,下面我们先采用RadioGroup+ViewPage+Fragment实现区域头部导航。

如图所示:

Android典型界面设计——ViewPage+Fragment实现区域顶部tab滑动切换

二、案例主要组件

1、先看一下MainActivity布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical" >       <HorizontalScrollView         android:id="@+id/hvChannel"          android:layout_width="match_parent"         android:layout_height="wrap_content"         android:scrollbars="none"         >         <RadioGroup          android:id="@+id/rgChannel"          android:layout_width="wrap_content"         android:layout_height="wrap_content" android:orientation="horizontal">                      </RadioGroup>      </HorizontalScrollView>       <android.support.v4.view.ViewPager               android:id="@+id/vpNewsList"                android:layout_width="match_parent"         android:layout_height="0dp"         android:layout_weight="1"           >       </android.support.v4.view.ViewPager> </LinearLayout>

2、MainActivity代码:

public class MainActivity extends FragmentActivity implements OnPageChangeListener{  private ViewPager viewPager;  private RadioGroup rgChannel=null;  private HorizontalScrollView hvChannel;  private PageFragmentAdapter adapter=null;  private List<Fragment> fragmentList=new ArrayList<Fragment>();  @Override  protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main);   initView();  }  private void initView(){   rgChannel=(RadioGroup)super.findViewById(R.id.rgChannel);   viewPager=(ViewPager)super.findViewById(R.id.vpNewsList);   hvChannel=(HorizontalScrollView)super.findViewById(R.id.hvChannel);   rgChannel.setOnCheckedChangeListener(     new RadioGroup.OnCheckedChangeListener() {    @Override    public void onCheckedChanged(RadioGroup group,       int checkedId) {     viewPager.setCurrentItem(checkedId);      }   });   viewPager.setOnPageChangeListener(this);   initTab();//动态产生RadioButton   initViewPager();   rgChannel.check(0);  }  private void initTab(){   List<Channel> channelList=ChannelDb.getSelectedChannel();   for(int i=0;i<channelList.size();i++){    RadioButton rb=(RadioButton)LayoutInflater.from(this).      inflate(R.layout.tab_rb, null);    rb.setId(i);    rb.setText(channelList.get(i).getName());    RadioGroup.LayoutParams params=new     RadioGroup.LayoutParams(RadioGroup.LayoutParams.WRAP_CONTENT,        RadioGroup.LayoutParams.WRAP_CONTENT);    rgChannel.addView(rb,params);   }  }  private void initViewPager(){   List<Channel> channelList=ChannelDb.getSelectedChannel();   for(int i=0;i<channelList.size();i++){    NewsFragment frag=new NewsFragment();    Bundle bundle=new Bundle();    bundle.putString("weburl", channelList.get(i).getWeburl());    bundle.putString("name", channelList.get(i).getName());    frag.setArguments(bundle);  //向Fragment传入数据    fragmentList.add(frag);   }   adapter=new PageFragmentAdapter(super.getSupportFragmentManager(),fragmentList);   viewPager.setAdapter(adapter);   //viewPager.setOffscreenPageLimit(0);  }  /**   * 滑动ViewPager时调整ScroollView的位置以便显示按钮   * @param idx   */  private void setTab(int idx){   RadioButton rb=(RadioButton)rgChannel.getChildAt(idx);   rb.setChecked(true);   int left=rb.getLeft();   int width=rb.getMeasuredWidth();   DisplayMetrics metrics=new DisplayMetrics();   super.getWindowManager().getDefaultDisplay().getMetrics(metrics);   int screenWidth=metrics.widthPixels;   int len=left+width/2-screenWidth/2;   hvChannel.smoothScrollTo(len, 0);//滑动ScroollView  }  @Override  public void onPageScrollStateChanged(int arg0) {  }  @Override  public void onPageScrolled(int arg0, float arg1, int arg2) {  }  @Override  public void onPageSelected(int position) {   // TODO Auto-generated method stub   setTab(position);  } } 

其中initTab()方法实现向RadioGroup动态添加RadioButton

导航按钮数据来源于ChannelDb

private static List<Channel>   selectedChannel=new ArrayList<Channel>(); static{  selectedChannel.add(new Channel("","头条",0,"",""));  selectedChannel.add(new Channel("","娱乐",0,"",""));  selectedChannel.add(new Channel("","体育",0,"",""));  selectedChannel.add(new Channel("","财经",0,"",""));  selectedChannel.add(new Channel("","热点",0,"",""));  selectedChannel.add(new Channel("","科技",0,"",""));  selectedChannel.add(new Channel("","图片",0,"",""));  selectedChannel.add(new Channel("","汽车",0,"",""));  selectedChannel.add(new Channel("","时尚",0,"","")); } public static  List<Channel> getSelectedChannel(){   return selectedChannel; } 

导航按钮外观:tab_rb.xml和tab_selector.xml背景选择器(实现选择后带红色下划线效果)

<?xml version="1.0" encoding="utf-8"?> <RadioButton xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="wrap_content"     android:layout_height="30dp"     android:text="今日"     android:background="@drawable/tab_selector"     android:paddingLeft="15dp"     android:paddingRight="15dp"      android:paddingTop="10dp"     android:paddingBottom="10dp"       android:button="@null"     /> tab_selector.xml: <selector xmlns:android="http://schemas.android.com/apk/res/android" >    <item android:state_checked="true" ><!-- 选中状态 -->   <layer-list >    <item >     <shape android:shape="rectangle">      <stroke android:width="5dp"  android:color="#ff0000"/>      </shape>    </item>    <item  android:bottom="5dp" >     <shape android:shape="rectangle" >       <solid android:color="#fff"/>       </shape>    </item>   </layer-list>   </item>  <item ><!-- 默认状态 -->   <shape >     <solid  android:color="#FAFAFA"/>   </shape>  </item> </selector> 

3、PageFragmentAdapter适配器

public class PageFragmentAdapter extends FragmentPagerAdapter{ private List<Fragment> fragmentList; private FragmentManager fm; public PageFragmentAdapter(FragmentManager fm,List<Fragment> fragmentList){  super(fm);  this.fragmentList=fragmentList;  this.fm=fm; } @Override public Fragment getItem(int idx) {  return fragmentList.get(idx%fragmentList.size()); } @Override public int getCount() {  return fragmentList.size(); } @Override   public int getItemPosition(Object object) {      return POSITION_NONE;  //没有找到child要求重新加载 }  } 

4、NewsFragment组件:

public class NewsFragment extends Fragment {  private String weburl;  private String channelName;  @Override  public void onAttach(Activity activity) {   super.onAttach(activity);  }  private View view;  @Override  public View onCreateView(LayoutInflater inflater, ViewGroup container,    Bundle savedInstanceState) {   if(view==null){//优化View减少View的创建次数     //该部分可通过xml文件设计Fragment界面,再通过LayoutInflater转换为View组件    //这里通过代码为fragment添加一个TextView    TextView tvTitle=new TextView(getActivity());    tvTitle.setText(channelName);    tvTitle.setTextSize(16);    tvTitle.setGravity(Gravity.CENTER);    tvTitle.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));    view=tvTitle;   }   ViewGroup parent=(ViewGroup)view.getParent();   if(parent!=null){//如果View已经添加到容器中,要进行删除,负责会报错    parent.removeView(view);   }   return view;  }  @Override  public void setArguments(Bundle bundle) {//接收传入的数据   weburl=bundle.getString("weburl");   channelName=bundle.getString("name");   } } 

想要了解更多内容的小伙伴,可以点击 查看源码 ,亲自运行测试。

疑问咨询或技术交流,请加入官方QQ群: Android典型界面设计——ViewPage+Fragment实现区域顶部tab滑动切换 (452379712)

作者: 杰瑞教育

出处: http://www.cnblogs.com/jerehedu/

本文版权归 烟台杰瑞教育科技有限公司 和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

正文到此结束
Loading...