歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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. }  

注釋已經寫的很清楚了,應該沒什麼問題。

這裡程序中使用了

[java]

  1. TypedArray a = obtainStyledAttributes(R.styleable.Gallery);  
  2.             a.recycle();//重復使用對象的styleable屬性  

這是一個引用自制layout 元素的用法,必須在res/values 下面添加一個attrs.xml,並在其中定義 <declare-styleable> 標簽TAG,目的是自定義layout 的背景風格,並且通過TypeArray 的特性,讓相同的Layout 元素可以重復用於每一張圖片,大家可以看下apiDemos裡gallery1s的用法,這裡也是參考它的用法。看下attrs.xml的代碼:

[xhtml]

  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>  

還要說一點的是,對於選中和未選中的背景處理。我們在onItemClick中得到選中的Tab,然後為選中的和未選中的設置一個背景。這個背景這裡用自定義圖形shape的方法來定義,在res/drawable下新建xml文件,tab_button_select.xml中內容如下:


[xhtml]

  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>  

  其中的gradient標簽實現一個從startColor到endColor角度為90漸變色。其實我們經常用這種方式來自定義我們的控件,可以用來實現圓角,漸變,描邊等效果,分別在shape根節點下用gradient,corners,stroke標簽實現,大家可以自己去試試,效果還是很好的,也很簡單。

  下面來看下MainActivity的代碼,顯示layout的方法和我以前一篇仿Iphone效果的Tab中一樣,通過隱藏和顯示相應的layout來實現。當然,也可以通過intent來指向不同的Activity等方法來做。注意定義要顯示的Tab數組的時候,因為我們第一個顯示的不是第一個Tab,所以適當調整下數組的定義順序,同樣對應的layou也是。

[java]

  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.     }  
Copyright © Linux教程網 All Rights Reserved