本例是用ViewPager去做的实现,支持自动滑动和手动滑动,不仅优酷网,实际上有很多商城和门户网站都有类似的实现:
具体思路:
1. 工程中需要添加android-support-v4.jar,才能使用ViewPager控件.
2. 图片的自动切换: 可使用Timer或者ScheduledExecutorService,这个有多重方式可以实现.
同时要切换底部的dots(园点)
3.Handler+Message机制更新UI,这个相信大家都很熟练,不再描述
4. 实现的一些细节:注意本例中的优化:图片的自动切换启动了其他的线程,要在Activity在可见到不可见的状态,也就是在onStop()方法中将线程停止,在onStart()方法中开启线程。否则,Timer没有停止,或者反复开启,会引起较大的内存消耗,时间一长就程序就会崩掉。 还有,就是在跳转到其他Activity的过程中会出现画面的卡顿
下面看一下效果图和具体代码:

工程结构如下图所示:
main.xml:

[java] view plaincopy
1<p> 2</p><p><strong>然后是具体的布局文件及代码实现:</strong></p><p>main.xml:</p> 3<?xml version="1.0" encoding="utf-8"?> 4<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 5 android:layout_width="fill_parent" 6 android:layout_height="fill_parent" 7 android:background="#FFFFFF" 8 android:orientation="vertical" > 9 10 <RelativeLayout 11 android:layout_width="fill_parent" 12 android:layout_height="40dip" 13 android:background="@drawable/title_bk" > 14 15 <ImageButton 16 android:id="@+id/btn_back" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:background="@drawable/btn_back_selector" 20 android:src="@drawable/btn_back" /> 21 22 <View 23 android:id="@+id/line0" 24 android:layout_width="1px" 25 android:layout_height="fill_parent" 26 android:layout_toRightOf="@id/btn_back" 27 android:background="#aa11264f" /> 28 29 <View 30 android:layout_width="1px" 31 android:layout_height="fill_parent" 32 android:layout_toRightOf="@id/line0" 33 android:background="#009ad6" /> 34 35 <TextView 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content" 38 android:layout_centerInParent="true" 39 android:text="优酷客户端" 40 android:textColor="#FFFFFF" 41 android:textSize="20sp" /> 42 </RelativeLayout> 43 44 <FrameLayout 45 android:layout_width="fill_parent" 46 android:layout_height="140dip" > 47 48 <android.support.v4.view.ViewPager 49 android:id="@+id/vp" 50 android:layout_width="fill_parent" 51 android:layout_height="fill_parent" /> 52 53 <LinearLayout 54 android:layout_width="fill_parent" 55 android:layout_height="35dip" 56 android:layout_gravity="bottom" 57 android:background="#33000000" 58 android:gravity="center" 59 android:orientation="vertical" > 60 61 <TextView 62 android:id="@+id/tv_title" 63 android:layout_width="wrap_content" 64 android:layout_height="wrap_content" 65 android:text="中国家庭院校园区域名字体现" 66 android:textColor="#ffffff" /> 67 68 <LinearLayout 69 android:layout_width="wrap_content" 70 android:layout_height="wrap_content" 71 android:layout_marginTop="3dip" 72 android:gravity="center" > 73 74 <View 75 android:id="@+id/v_dot0" 76 style="@style/dot_style" 77 android:background="@drawable/dot_focused" /> 78 79 <View 80 android:id="@+id/v_dot1" 81 style="@style/dot_style" /> 82 83 <View 84 android:id="@+id/v_dot2" 85 style="@style/dot_style" /> 86 87 <View 88 android:id="@+id/v_dot3" 89 style="@style/dot_style" /> 90 91 <View 92 android:id="@+id/v_dot4" 93 style="@style/dot_style" /> 94 </LinearLayout> 95 </LinearLayout> 96 </FrameLayout> 97 98</LinearLayout>
MyViewPagerActivity:
[java] view plaincopy
-
1 package com.tony.viewpager; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.concurrent.Executors; 6 import java.util.concurrent.ScheduledExecutorService; 7 import java.util.concurrent.TimeUnit; 8 9 10 import android.app.Activity; 11 import android.os.Bundle; 12 import android.os.Handler; 13 import android.os.Parcelable; 14 import android.support.v4.view.PagerAdapter; 15 import android.support.v4.view.ViewPager; 16 import android.support.v4.view.ViewPager.OnPageChangeListener; 17 import android.view.View; 18 import android.widget.ImageView; 19 import android.widget.ImageView.ScaleType; 20 import android.widget.TextView; 21 22 /** 23 * 仿优酷Android客户端图片左右滑动 24 * 25 */ 26 public class MyViewPagerActivity extends Activity { 27 private ViewPager viewPager; // android-support-v4中的滑动组件 28 private List<ImageView> imageViews; // 滑动的图片集合 29 30 private String[] titles; // 图片标题 31 private int[] imageResId; // 图片ID 32 private List<View> dots; // 图片标题正文的那些点 33 34 private TextView tv_title; 35 private int currentItem = 0; // 当前图片的索引号 36 37 // An ExecutorService that can schedule commands to run after a given delay, 38 // or to execute periodically. 39 private ScheduledExecutorService scheduledExecutorService; 40 41 // 切换当前显示的图片 42 private Handler handler = new Handler() { 43 public void handleMessage(android.os.Message msg) { 44 viewPager.setCurrentItem(currentItem);// 切换当前显示的图片 45 }; 46 }; 47 48 @Override 49 public void onCreate(Bundle savedInstanceState) { 50 super.onCreate(savedInstanceState); 51 setContentView(R.layout.main); 52 53 imageResId = new int[] { R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e }; 54 titles = new String[imageResId.length]; 55 titles[0] = "巩俐不低俗,我就不能低俗"; 56 titles[1] = "扑树又回来啦!再唱经典老歌引万人大合唱"; 57 titles[2] = "揭秘北京电影如何升级"; 58 titles[3] = "乐视网TV版大派送"; 59 titles[4] = "热血屌丝的反杀"; 60 61 imageViews = new ArrayList<ImageView>(); 62 63 // 初始化图片资源 64 for (int i = 0; i < imageResId.length; i++) { 65 ImageView imageView = new ImageView(this); 66 imageView.setImageResource(imageResId[i]); 67 imageView.setScaleType(ScaleType.CENTER_CROP); 68 imageViews.add(imageView); 69 } 70 71 72 dots = new ArrayList<View>(); 73 dots.add(findViewById(R.id.v_dot0)); 74 dots.add(findViewById(R.id.v_dot1)); 75 dots.add(findViewById(R.id.v_dot2)); 76 dots.add(findViewById(R.id.v_dot3)); 77 dots.add(findViewById(R.id.v_dot4)); 78 79 tv_title = (TextView) findViewById(R.id.tv_title); 80 tv_title.setText(titles[0]);// 81 82 viewPager = (ViewPager) findViewById(R.id.vp); 83 viewPager.setAdapter(new MyAdapter());// 设置填充ViewPager页面的适配器 84 // 设置一个监听器,当ViewPager中的页面改变时调用 85 viewPager.setOnPageChangeListener(new MyPageChangeListener()); 86 87 } 88 89 @Override 90 protected void onStart() { 91 scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); 92 // 当Activity显示出来后,每两秒钟切换一次图片显示 93 scheduledExecutorService.scheduleAtFixedRate(new ScrollTask(), 1, 2, TimeUnit.SECONDS); 94 super.onStart(); 95 } 96 97 @Override 98 protected void onStop() { 99 // 当Activity不可见的时候停止切换 100 scheduledExecutorService.shutdown(); 101 super.onStop(); 102 } 103 104 /** 105 * 换行切换任务 106 * 107 * @author Administrator 108 * 109 */ 110 private class ScrollTask implements Runnable { 111 112 public void run() { 113 synchronized (viewPager) { 114 System.out.println("currentItem: " + currentItem); 115 currentItem = (currentItem + 1) % imageViews.size(); 116 handler.obtainMessage().sendToTarget(); // 通过Handler切换图片 117 } 118 } 119 120 } 121 122 /** 123 * 当ViewPager中页面的状态发生改变时调用 124 * 125 * @author Administrator 126 * 127 */ 128 private class MyPageChangeListener implements OnPageChangeListener { 129 private int oldPosition = 0; 130 131 /** 132 * This method will be invoked when a new page becomes selected. 133 * position: Position index of the new selected page. 134 */ 135 public void onPageSelected(int position) { 136 currentItem = position; 137 tv_title.setText(titles[position]); 138 dots.get(oldPosition).setBackgroundResource(R.drawable.dot_normal); 139 dots.get(position).setBackgroundResource(R.drawable.dot_focused); 140 oldPosition = position; 141 } 142 143 public void onPageScrollStateChanged(int arg0) { 144 145 } 146 147 public void onPageScrolled(int arg0, float arg1, int arg2) { 148 149 } 150 } 151 152 /** 153 * 填充ViewPager页面的适配器 154 * 155 * @author Administrator 156 * 157 */ 158 private class MyAdapter extends PagerAdapter { 159 160 @Override 161 public int getCount() { 162 return imageResId.length; 163 } 164 165 @Override 166 public Object instantiateItem(View arg0, int arg1) { 167 ((ViewPager) arg0).addView(imageViews.get(arg1)); 168 return imageViews.get(arg1); 169 } 170 171 @Override 172 public void destroyItem(View arg0, int arg1, Object arg2) { 173 ((ViewPager) arg0).removeView((View) arg2); 174 } 175 176 @Override 177 public boolean isViewFromObject(View arg0, Object arg1) { 178 return arg0 == arg1; 179 } 180 181 @Override 182 public void restoreState(Parcelable arg0, ClassLoader arg1) { 183 184 } 185 186 @Override 187 public Parcelable saveState() { 188 return null; 189 } 190 191 @Override 192 public void startUpdate(View arg0) { 193 194 } 195 196 @Override 197 public void finishUpdate(View arg0) { 198 199 } 200 } 201 }
Drawable目录下
btn_back_selector.xml:
[java] view plaincopy
-
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android"> 3 4 <item android:drawable="@drawable/btn_top_pressed" android:state_focused="true"></item> 5 <item android:drawable="@drawable/btn_top_pressed" android:state_pressed="true"></item> 6 <item android:drawable="@drawable/btn_top_pressed" android:state_selected="true"></item> 7 <item android:drawable="@drawable/title_bk"></item> 8 9 </selector> 10 11 12 13 btn_top_pressed.xml: 14 15 [java] view plaincopy 16 17 <?xml version="1.0" encoding="utf-8"?> 18 <shape xmlns:android="http://schemas.android.com/apk/res/android" 19 android:shape="rectangle" > 20 21 <gradient 22 android:angle="270" 23 android:endColor="#009ad6" 24 android:startColor="#11264f" /> 25 26 </shape>
dot_focused.xml:
[java] view plaincopy
-
1 <?xml version="1.0" encoding="utf-8"?> 2 <shape xmlns:android="http://schemas.android.com/apk/res/android" 3 android:shape="oval" > 4 5 <solid android:color="#aaFFFFFF" /> 6 7 <corners android:radius="5dip" /> 8 9 </shape>
dot_normal.xml:
[java] view plaincopy
-
1 <?xml version="1.0" encoding="utf-8"?> 2 <shape xmlns:android="http://schemas.android.com/apk/res/android" 3 android:shape="oval" > 4 5 <solid android:color="#33000000" /> 6 7 <corners android:radius="5dip" /> 8 9 </shape>
title_bk.xml:
[java] view plaincopy
1<?xml version="1.0" encoding="utf-8"?> 2<shape xmlns:android="http://schemas.android.com/apk/res/android" 3 android:shape="rectangle" > 4 5 <gradient 6 android:angle="270" 7 android:endColor="#11264f" 8 android:startColor="#009ad6" /> 9 10</shape>
源码下载地址: