Android UI进阶之用gallery实现可滑动的Tab

最近有很多事情要忙,一直没有更新博客,今天得空来写一写。话说春天什么时候来,还是冷兮兮的。

 今天还是来讲下Tab的实现。android自带的Tab在有比较多条目的时候会显得非常挤,这样不仅不美观,更加影响操作。如果Tab能做成左右滑动的,那就非常好了。其实实现这种效果并不难,而且方法也不少。今天给大家介绍下用gallery这个组件来实现的方法。

 首先我们需要写Gallery的适配器。这里我们要注意的是Gallery有一个特点,就是起始一个元素的左边会留下一块空位,如下图所示:

 

 

 

  这样我们的Tab显然不是很完美,如何解决?开始想的就是去看gallery的源码,重写他。不过既然我们做的是滑动的,让他左右都可滑动不就ok了?要实现左右滑动,要做的事情就是让里面的元素循环。Gallery是即时显示图像的,可以通过两点来做到:

  1.让getCount()方法返回一个非常大的值。

  2.在getView()中显示的时候通过循环取余来实现一直显示数组中的有限值。

  而且Gallery还提供了一个setSelection()方法,用来设置当前选择的条目,我们将显示的位置放在比较靠后的位置,这样就不会在左滑的时候滑到头,那样就可以以假乱真了。

  下面来看下适配器代码:

 

 

 

  1. public   class  TabAdapter  extends  BaseAdapter {  
  2.      private  Context mContext;  
  3.      private  List<String> mList;  
  4.      private   int  mSelectedTab;  
  5.      public  TabAdapter(Context context, List<String> list) {  
  6.         mContext = context;  
  7.        /*使用attrs里的 <declare-styleable>属性*/   
  8.         TypedArray a = obtainStyledAttributes(R.styleable.Gallery);  
  9.         a.recycle(); //重复使用对象的styleable属性   
  10.          if  (list ==  null )  
  11.             list = Collections.emptyList();  
  12.         mList = list;   
  13.     }  
  14.      /*
  15.      * 设置选中的Tab,并且刷新界面  
  16.      */   
  17.      public   void  setSelectedTab( int  tab) {  
  18.          if  (tab != mSelectedTab) {  
  19.             mSelectedTab = tab;  
  20.             notifyDataSetChanged();  
  21.         }  
  22.     }  
  23.       
  24.      public   int  getSelectedTab() {  
  25.          return  mSelectedTab;  
  26.     }  
  27.      public   int  getCount() {  
  28.          return   Integer.MAX_VALUE; //返回最大值   
  29.     }  
  30.      public  Object getItem( int  position) {  
  31.          return  mList.get(position);  
  32.     }  
  33.      public   long  getItemId( int  position) {  
  34.          return  position;  
  35.     }  
  36.      public  View getView( int  position, View convertView, ViewGroup parent) {  
  37.         TextView text =  null ; //这里只放一个TextView,可以根据需要来定制   
  38.          if  (convertView ==  null  ) {  
  39.              text =  new  TextView(mContext);  
  40.         }  else  {  
  41.             text = (TextView) convertView;  
  42.         }  
  43.           
  44.         text.setTextColor(Color.WHITE);  
  45.         text.setText(mList.get(position % mList.size())); //循环取余设置显示内容   
  46.           
  47.         text.setLayoutParams( new  Gallery.LayoutParams( 10240 ));  
  48.         text.setGravity(Gravity.CENTER);  
  49.           
  50.          /*
  51.          * 对于选中的Tab,给他一个选中的背景  
  52.          */   
  53.          if  (position == mSelectedTab)  
  54.             text.setBackgroundResource(R.drawable.tab_button_select);  
  55.          else   
  56.             text.setBackgroundResource(R.drawable.tab_button_unselect);  
  57.           
  58.          return  text;  
  59.     }  
  60. }  

public class TabAdapter extends BaseAdapter { private Context mContext; private List<String> mList; private int mSelectedTab; public TabAdapter(Context context, List<String> list) { mContext = context; /*使用attrs里的 <declare-styleable>属性*/ TypedArray a = obtainStyledAttributes(R.styleable.Gallery); a.recycle();//重复使用对象的styleable属性 if (list == null) list = Collections.emptyList(); mList = list; } /* * 设置选中的Tab,并且刷新界面 */ public void setSelectedTab(int tab) { if (tab != mSelectedTab) { mSelectedTab = tab; notifyDataSetChanged(); } } public int getSelectedTab() { return mSelectedTab; } public int getCount() { return Integer.MAX_VALUE;//返回最大值 } public Object getItem(int position) { return mList.get(position); } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { TextView text = null;//这里只放一个TextView,可以根据需要来定制 if (convertView == null ) { text = new TextView(mContext); } else { text = (TextView) convertView; } text.setTextColor(Color.WHITE); text.setText(mList.get(position % mList.size()));//循环取余设置显示内容 text.setLayoutParams(new Gallery.LayoutParams(102, 40)); text.setGravity(Gravity.CENTER); /* * 对于选中的Tab,给他一个选中的背景 */ if (position == mSelectedTab) text.setBackgroundResource(R.drawable.tab_button_select); else text.setBackgroundResource(R.drawable.tab_button_unselect); return text; } }

 

 

注释已经写的很清楚了,应该没什么问题。

这里程序中使用了

 

  1. TypedArray a = obtainStyledAttributes(R.styleable.Gallery);  
  2.             a.recycle(); //重复使用对象的styleable属性   

TypedArray a = obtainStyledAttributes(R.styleable.Gallery); a.recycle();//重复使用对象的styleable属性

 

 

这是一个引用自制layout 元素的用法,必须在res/values 下面添加一个attrs.xml,并在其中定义 <declare-styleable> 标签TAG,目的是自定义layout 的背景风格,并且通过TypeArray 的特性,让相同的Layout 元素可以重复用于每一张图片,大家可以看下apiDemos里gallery1s的用法,这里也是参考它的用法。看下attrs.xml的代码:

 

 

  1. <? xml   version = "1.0"   encoding = "utf-8" ?>   
  2. < resources >   
  3.      < declare-styleable   name = "Gallery" >   
  4.          < attr   name = "android:galleryItemBackground"   />   
  5.      </ declare-styleable >   
  6. </ resources >   

<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Gallery"> <attr name="android:galleryItemBackground" /> </declare-styleable> </resources>

 

还要说一点的是,对于选中和未选中的背景处理。我们在onItemClick中得到选中的Tab,然后为选中的和未选中的设置一个背景。这个背景这里用自定义图形shape的方法来定义,在res/drawable下新建xml文件,tab_button_select.xml中内容如下:

 

 

  1. <? xml   version = "1.0"   encoding = "utf-8" ?>   
  2. < shape   xmlns:android = "http://schemas.android.com/apk/res/android" >       
  3.      < gradient   android:startColor = "#FFA2A2A2"   android:endColor = "#FF5F5F5F"   
  4.          android:angle = "90.0" >   
  5.      </ gradient >   
  6. </ shape >   

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <gradient android:startColor="#FFA2A2A2" android:endColor="#FF5F5F5F" android:angle="90.0"> </gradient> </shape>

 

 

 

  其中的gradient标签实现一个从startColor到endColor角度为90渐变色。其实我们经常用这种方式来自定义我们的控件,可以用来实现圆角,渐变,描边等效果,分别在shape根节点下用gradient,corners,stroke标签实现,大家可以自己去试试,效果还是很好的,也很简单。

  下面来看下MainActivity的代码,显示layout的方法和我以前一篇仿Iphone效果的Tab中一样,通过隐藏和显示相应的layout来实现。当然,也可以通过intent来指向不同的Activity等方法来做。注意定义要显示的Tab数组的时候,因为我们第一个显示的不是第一个Tab,所以适当调整下数组的定义顺序,同样对应的layou也是。

 

 

  1. public   class  MainActivity  extends  Activity {  
  2.      private  Gallery gallery;  
  3.      private  TabAdapter textAdapter;  
  4.      private   static   final  String[] TAB_NAMES = {  
  5.           
  6.          "第四个" ,  
  7.          "第一个" ,  
  8.          "第二个" ,  
  9.          "第三个" ,  
  10.     }; //注意调整顺序   
  11.       
  12.      private  LinearLayout    mTabLayout_One;  
  13.      private  LinearLayout    mTabLayout_Two;  
  14.      private  LinearLayout    mTabLayout_Three;  
  15.      private  LinearLayout    mTabLayout_Four;  
  16.      @Override   
  17.      public   void  onCreate(Bundle savedInstanceState) {  
  18.          super .onCreate(savedInstanceState);  
  19.         setContentView(R.layout.main);  
  20.           
  21.         gallery = (Gallery) findViewById(R.id.gallery);  
  22.         textAdapter =  new  TabAdapter( this , Arrays.asList(TAB_NAMES));  
  23.         gallery.setAdapter(textAdapter);  
  24.         gallery.setSelection( 34 ); //这里根据你的Tab数自己算一下,让左边的稍微多一点,不要一滑就滑到头   
  25.           
  26.         mTabLayout_One = (LinearLayout)  this .findViewById( R.id.TabLayout_One );  
  27.         mTabLayout_Two = (LinearLayout)  this .findViewById( R.id.TabLayout_Two );  
  28.         mTabLayout_Three = (LinearLayout)  this .findViewById( R.id.TabLayout_Three );  
  29.         mTabLayout_Four = (LinearLayout)  this .findViewById( R.id.TabLayout_Four );  
  30.           
  31.         mTabLayout_One.setVisibility( View.GONE );  
  32.         mTabLayout_Two.setVisibility( View.VISIBLE );  
  33.         mTabLayout_Three.setVisibility( View.GONE );  
  34.         mTabLayout_Four.setVisibility( View.GONE );  
  35.           
  36.         gallery.setOnItemClickListener( new  OnItemClickListener() {  
  37.              @Override   
  38.              public   void  onItemClick(AdapterView<?> parent, View view,  int  position,  
  39.                      long  id) {  
  40.                 TabAdapter adapter = (TabAdapter)parent.getAdapter();  
  41.                 adapter.setSelectedTab(position);  
  42.                  switch (position %TAB_NAMES.length ){  
  43.                  case   0 :  
  44.                     mTabLayout_One.setVisibility( View.VISIBLE );  
  45.                     mTabLayout_Two.setVisibility( View.GONE );  
  46.                     mTabLayout_Three.setVisibility( View.GONE );  
  47.                     mTabLayout_Four.setVisibility( View.GONE );  
  48.                      break ;  
  49.                  case   1 :  
  50.                     mTabLayout_One.setVisibility( View.GONE );  
  51.                     mTabLayout_Two.setVisibility( View.VISIBLE );  
  52.                     mTabLayout_Three.setVisibility( View.GONE );  
  53.                     mTabLayout_Four.setVisibility( View.GONE );  
  54.                      break ;  
  55.                  case   2 :  
  56.                     mTabLayout_One.setVisibility( View.GONE );  
  57.                     mTabLayout_Two.setVisibility( View.GONE );  
  58.                     mTabLayout_Three.setVisibility( View.VISIBLE );  
  59.                     mTabLayout_Four.setVisibility( View.GONE );  
  60.                      break ;  
  61.                  case   3 :  
  62.                     mTabLayout_One.setVisibility( View.GONE );  
  63.                     mTabLayout_Two.setVisibility( View.GONE );  
  64.                     mTabLayout_Three.setVisibility( View.GONE );  
  65.                     mTabLayout_Four.setVisibility( View.VISIBLE );  
  66.                 }  
  67.             }  
  68.               
  69.         });  
  70.           
  71.     }  

public class MainActivity extends Activity { private Gallery gallery; private TabAdapter textAdapter; private static final String[] TAB_NAMES = { "第四个", "第一个", "第二个", "第三个", };//注意调整顺序 private LinearLayout mTabLayout_One; private LinearLayout mTabLayout_Two; private LinearLayout mTabLayout_Three; private LinearLayout mTabLayout_Four; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); gallery = (Gallery) findViewById(R.id.gallery); textAdapter = new TabAdapter(this, Arrays.asList(TAB_NAMES)); gallery.setAdapter(textAdapter); gallery.setSelection(34);//这里根据你的Tab数自己算一下,让左边的稍微多一点,不要一滑就滑到头 mTabLayout_One = (LinearLayout) this.findViewById( R.id.TabLayout_One ); mTabLayout_Two = (LinearLayout) this.findViewById( R.id.TabLayout_Two ); mTabLayout_Three = (LinearLayout) this.findViewById( R.id.TabLayout_Three ); mTabLayout_Four = (LinearLayout) this.findViewById( R.id.TabLayout_Four ); mTabLayout_One.setVisibility( View.GONE ); mTabLayout_Two.setVisibility( View.VISIBLE ); mTabLayout_Three.setVisibility( View.GONE ); mTabLayout_Four.setVisibility( View.GONE ); gallery.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TabAdapter adapter = (TabAdapter)parent.getAdapter(); adapter.setSelectedTab(position); switch(position %TAB_NAMES.length ){ case 0: mTabLayout_One.setVisibility( View.VISIBLE ); mTabLayout_Two.setVisibility( View.GONE ); mTabLayout_Three.setVisibility( View.GONE ); mTabLayout_Four.setVisibility( View.GONE ); break; case 1: mTabLayout_One.setVisibility( View.GONE ); mTabLayout_Two.setVisibility( View.VISIBLE ); mTabLayout_Three.setVisibility( View.GONE ); mTabLayout_Four.setVisibility( View.GONE ); break; case 2: mTabLayout_One.setVisibility( View.GONE ); mTabLayout_Two.setVisibility( View.GONE ); mTabLayout_Three.setVisibility( View.VISIBLE ); mTabLayout_Four.setVisibility( View.GONE ); break; case 3: mTabLayout_One.setVisibility( View.GONE ); mTabLayout_Two.setVisibility( View.GONE ); mTabLayout_Three.setVisibility( View.GONE ); mTabLayout_Four.setVisibility( View.VISIBLE ); } } }); }

 

 

 最后就是main.xml布局文件了:

 

 

  1. <? xml   version = "1.0"   encoding = "utf-8" ?>   
  2. < RelativeLayout   xmlns:android = "http://schemas.android.com/apk/res/android"   
  3.      android:orientation = "vertical"   android:layout_width = "fill_parent"   
  4.      android:layout_height = "fill_parent"   
  5.      android:background = "#C5CCD4FF" >   
  6.      < LinearLayout   
  7.              android:id  =  "@+id/TabLayout_One"   
  8.              android:layout_width  =  "fill_parent"   
  9.              android:layout_height  =  "fill_parent"   
  10.              android:layout_below  =  "@+id/gallery"   
  11.              >   
  12.              < ScrollView   android:layout_width = "fill_parent"   android:layout_height = "wrap_content" >   
  13.                  < RelativeLayout   
  14.                      android:layout_width  =  "fill_parent"   
  15.                      android:layout_height  =  "fill_parent"   
  16.                      android:visibility  =  "visible"   
  17.                      >   
  18.                      < TextView   
  19.                          android:textColor = "@android:color/black"   
  20.                          android:textSize = "30sp"   
  21.                          android:layout_width  =  "wrap_content"   
  22.                          android:layout_height  =  "wrap_content"   
  23.                          android:text  =  "这是第四个布局"   
  24.                      />   
  25.                      </ RelativeLayout >   
  26.                  </ ScrollView >   
  27.              </ LinearLayout >   
  28.               
  29.          < LinearLayout   
  30.              android:id  =  "@+id/TabLayout_Two"   
  31.              android:layout_width  =  "fill_parent"   
  32.              android:layout_height  =  "fill_parent"   
  33.              android:layout_below  =  "@+id/gallery"   
  34.              >   
  35.              < ScrollView   android:layout_width = "fill_parent"   android:layout_height = "wrap_content" >   
  36.                      < RelativeLayout   
  37.                          android:layout_width  =  "fill_parent"   
  38.                          android:layout_height  =  "fill_parent"   
  39.                          android:visibility  =  "visible"   
  40.                          android:layout_above  =  "@+id/Tabs"   
  41.                          >   
  42.                          < Button   
  43.                              android:layout_width  =  "wrap_content"   
  44.                              android:layout_height  =  "wrap_content"   
  45.                              android:text  =  "这是第一个布局"   
  46.                              android:textSize  =  "30sp"   
  47.                          />   
  48.                      </ RelativeLayout >    
  49.              </ ScrollView >   
  50.          </ LinearLayout >   
  51.          < LinearLayout   
  52.              android:id  =  "@+id/TabLayout_Three"   
  53.              android:layout_width  =  "fill_parent"   
  54.              android:layout_height  =  "fill_parent"   
  55.              android:layout_below  =  "@+id/gallery"   
  56.              >   
  57.              < ScrollView   android:layout_width = "fill_parent"   android:layout_height = "wrap_content" >   
  58.                  < RelativeLayout   
  59.                      android:layout_width  =  "fill_parent"   
  60.                      android:layout_height  =  "fill_parent"   
  61.                      android:visibility  =  "visible"   
  62.                      android:layout_above  =  "@+id/Tabs"   
  63.                      >   
  64.                      < TextView                           
  65.                          android:layout_width  =  "fill_parent"   
  66.                          android:layout_height  =  "fill_parent"   
  67.                          android:textSize = "25sp"        
  68.                          android:textColor = "#ffffff"                
  69.                          android:text = "dddddddddddddddddddddddddddddddddddd"   
  70.                      />   
  71.                  </ RelativeLayout >   
  72.              </ ScrollView >   
  73.          </ LinearLayout >   
  74.          < LinearLayout   
  75.              android:id  =  "@+id/TabLayout_Four"   
  76.              android:layout_width  =  "fill_parent"   
  77.              android:layout_height  =  "fill_parent"   
  78.              android:layout_below  =  "@+id/gallery"   
  79.              >   
  80.              < ScrollView   android:layout_width = "fill_parent"   android:layout_height = "wrap_content" >         
  81.                  < RelativeLayout   
  82.                      android:id  =  "@+id/TabLayout_Four"   
  83.                      android:layout_width  =  "fill_parent"   
  84.                      android:layout_height  =  "fill_parent"   
  85.                      android:visibility  =  "visible"   
  86.                      android:layout_above  =  "@+id/Tabs"   
  87.                      >   
  88.                      < TextView   
  89.                          android:textColor = "@android:color/black"   
  90.                          android:layout_width  =  "wrap_content"   
  91.                          android:layout_height  =  "wrap_content"   
  92.                          android:text  =  "很简单,是么"   
  93.                      />   
  94.                  </ RelativeLayout >   
  95.              </ ScrollView >   
  96.          </ LinearLayout >              
  97.      < Gallery    
  98.          android:id = "@+id/gallery"    
  99.          android:layout_alignParentTop = "true"   
  100.          android:layout_width = "fill_parent"   
  101.          android:layout_height = "wrap_content"   
  102.          android:unselectedAlpha = "1"   
  103.          android:spacing = "1dip" />   
  104. </ RelativeLayout >   

转载于:https://www.cnblogs.com/huaxiamingwang/archive/2012/02/27/2370277.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值