zoukankan      html  css  js  c++  java
  • 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就完成了,看下最后的效果。

    大家有什么问题可以留言交流哈。特别是对让左边不留空的方法有好的解决办法的话,希望能提出来,大家一起学习交流。

    本文系参加“第二届 Google 暑期大学生博客分享大赛 - 2011 Android 成长篇 

  • 相关阅读:
    GCC-windows的预编译版本——nuwen MinGW
    stm32 flash和sram
    NAND Flash和NOR Flash的比较
    emwin如何在windows10下vs2015或2017进行仿真。
    IIC简介(转载)
    ubuntu版本查看
    下载速度更加快的 SourceForge 镜像
    使用virtualbox安装的Ubuntu,窗口分辨率过小,使用增强工具完成和vmtools一样的功能。
    C#中的结构体与类的区别
    理解C#值类型和引用类型
  • 原文地址:https://www.cnblogs.com/noTice520/p/1978408.html
Copyright © 2011-2022 走看看