你的位置:首页 > 操作系统

[操作系统]Android典型界面设计——ViewPage+Fragment实现区域顶部tab滑动切换


一、问题描述

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

  如图所示:

二、案例主要组件

  1、先看一下MainActivity布局

 <LinearLayout ="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.

<??><RadioButton ="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.<selector ="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的创建次数        //该部分可通过//这里通过代码为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群:JRedu技术交流 (452379712)

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