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

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

这里程序中使用了

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

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

复制代码
<? 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>

  

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

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

复制代码
<? xml version="1.0" encoding="utf-8" ?>
< RelativeLayout xmlns:android ="http://schemas.android.com/apk/res/android"
  android:orientation
="vertical" android:layout_width ="fill_parent"
  android:layout_height
="fill_parent"
  android:background
="#C5CCD4FF" >
< LinearLayout
  android:id = "@+id/TabLayout_One"
  android:layout_width
= "fill_parent"
  android:layout_height
= "fill_parent"
  android:layout_below
= "@+id/gallery"
>
< TextView
  android:textColor ="@android:color/black"
  android:textSize
="30sp"
  android:layout_width
= "wrap_content"
  android:layout_height
= "wrap_content"
  android:text
= "这是第四个布局"
/>
</ LinearLayout >

< LinearLayout
  android:id = "@+id/TabLayout_Two"
  android:layout_width
= "fill_parent"
  android:layout_height
= "fill_parent"
  android:layout_below
= "@+id/gallery"
>

< Button
  android:layout_width = "wrap_content"
  android:layout_height
= "wrap_content"
  android:text
= "这是第一个布局"
  android:textSize
= "30sp"
/>
</ LinearLayout >
< LinearLayout
  android:id = "@+id/TabLayout_Three"
  android:layout_width
= "fill_parent"
  android:layout_height
= "fill_parent"
  android:layout_below
= "@+id/gallery"
>

< TextView
  android:layout_width = "fill_parent"
  android:layout_height
= "fill_parent"
  android:textSize
="25sp"
  android:textColor
="#ffffff"
  android:text
="你觉得怎么样?"
/>
</ LinearLayout >
< LinearLayout
  android:id = "@+id/TabLayout_Four"
  android:layout_width
= "fill_parent"
  android:layout_height
= "fill_parent"
  android:layout_below
= "@+id/gallery"
>
< TextView
  android:textColor ="@android:color/black"
  android:layout_width
= "wrap_content"
  android:layout_height
= "wrap_content"
  android:text
= "很简单,是么"
/>

</ LinearLayout >
< Gallery
  android:id ="@+id/gallery"
  android:layout_alignParentTop
="true"
  android:layout_width
="fill_parent"
  android:layout_height
="wrap_content"
  android:unselectedAlpha
="1"
  android:spacing
="1dip" />
</ RelativeLayout >
复制代码

这样我们用gallery实现的可滑动的Tab就完成了,看下最后的效果。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值