自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)...
1.首先我们看看运行效果,如下:
2. 下面就是详细实现这个效果的过程:
(1)新建一个Android工程,命名为"广告条的效果",如下:
(2)这里用到一个控件ViewPager,这个控件是在android-support-v4.jar(google提供扩展工具包)之中。这个包里面工具控件使用要使用全路径名声明(在Activity 或者 xml 中需要工具控件的全路径名)。
在上面android-support-v4.jar下找到包android.support.v4.view中有ViewPager.class,如下:
可是我们发现ViewPager.class的源码没有关联好,如下操作:
去除构建路径之后,如下:
重新构建路径,如下:
重新构建完之后,如下图:
这时候在刚刚诞生的 引用的库 中的"android-support-v4.jar",找到ViewPager.class,如下:
连接源代码,如下:
路径:D:\software\Android\SDT\android-sdk-windows\extras\android\support\v4\src\java
点击确定,出现下面的结果:
(3)开始编写代码,先进行布局设计,如下:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context="com.himi.youkumenu.MainActivity" > 6 7 <android.support.v4.view.ViewPager 8 android:layout_width="match_parent" 9 android:layout_height="200dp" 10 android:id="@+id/viewpager"/> 11 <LinearLayout 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:background="#33000000" 15 android:orientation="vertical" 16 android:layout_alignBottom="@id/viewpager"> 17 <TextView 18 android:layout_width="match_parent" 19 android:layout_height="wrap_content" 20 android:gravity="center" 21 android:text="@string/app_name" 22 android:textColor="@android:color/white" 23 android:textSize="18sp" 24 /> 25 <LinearLayout 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 android:id="@+id/point_group" 29 android:orientation="horizontal"> 30 </LinearLayout> 31 </LinearLayout> 32 33 34 </RelativeLayout>
这么上面我们看到了,要使用ViewPager必须使用全路径android.support.v4.view.ViewPager。在ViewPager的下方是用LinearLayout实现的一个广告条的横幅说明,广告条中文字使用TextView,切换的点是用LinearLayout动态添加(所以这个LinearLayout我们加了id)。
布局效果如下:
(4)接下来完成MainActivity.java,如下:
1 package com.himi.viewpager; 2 3 import java.util.ArrayList; 4 5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.support.v4.view.PagerAdapter; 8 import android.support.v4.view.ViewPager; 9 import android.view.View; 10 import android.view.ViewGroup; 11 import android.widget.ImageView; 12 import android.widget.LinearLayout; 13 import android.widget.TextView; 14 15 public class MainActivity extends Activity { 16 17 private ViewPager viewpager; 18 private LinearLayout pointGroup; 19 private TextView imageDesc; 20 21 //图片资源ID 22 private final int[] imageIds = { 23 R.drawable.a, 24 R.drawable.b, 25 R.drawable.c, 26 R.drawable.d, 27 R.drawable.e 28 }; 29 private ArrayList<ImageView> imageList; 30 @Override 31 protected void onCreate(Bundle savedInstanceState) { 32 super.onCreate(savedInstanceState); 33 setContentView(R.layout.activity_main); 34 35 viewpager = (ViewPager) findViewById(R.id.viewpager); 36 pointGroup = (LinearLayout) findViewById(R.id.point_group); 37 imageDesc = (TextView) findViewById(R.id.image_desc); 38 39 //初始化图片资源 40 imageList = new ArrayList<ImageView>(); 41 for(int i=0; i<imageIds.length; i++) { 42 ImageView image = new ImageView(this); 43 image.setBackgroundResource(imageIds[i]); 44 imageList.add(image); 45 } 46 viewpager.setAdapter(new MyPagerAdapter()); 47 } 48 49 private class MyPagerAdapter extends PagerAdapter { 50 51 @Override 52 /** 53 * 获取页面的总数 54 */ 55 public int getCount() { 56 // TODO 自动生成的方法存根 57 return imageList.size(); 58 } 59 60 @Override 61 /** 62 * 判断View和Object的对应的关系 63 */ 64 public boolean isViewFromObject(View view, Object object) { 65 return view == object; 66 } 67 68 @Override 69 /** 70 * 获得相应的位置桑的View 71 * @param container view容器,其实就是viewpager自身 72 * @param position 相应的位置 73 */ 74 public Object instantiateItem(ViewGroup container, int position) { 75 //给container添加内容 76 container.addView(imageList.get(position)); 77 78 return imageList.get(position); 79 } 80 81 @Override 82 /** 83 * 销毁对应位置上的object 84 * @param container view容器,其实就是viewpager自身 85 * @param position 相应的位置 86 * @param object 待删除的对象 87 */ 88 public void destroyItem(ViewGroup container, int position, Object object) { 89 container.removeView((View) object); 90 object = null;//object变成空指针,也就是告诉系统可以回收 91 } 92 93 } 94 95 }
布署程序到模拟器上运行,结果如下:
同时Logcat打印日志:
09-23 03:54:42.088: E/AndroidRuntime(1016): FATAL EXCEPTION: main
09-23 03:54:42.088: E/AndroidRuntime(1016): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.himi.viewpager/com.himi.viewpager.MainActivity}: android.view.InflateException: Binary XML file line #7: Error inflating class android.support.v4.view.ViewPager
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.ActivityThread.access$600(ActivityThread.java:123)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.os.Handler.dispatchMessage(Handler.java:99)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.os.Looper.loop(Looper.java:137)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.ActivityThread.main(ActivityThread.java:4424)
09-23 03:54:42.088: E/AndroidRuntime(1016): at java.lang.reflect.Method.invokeNative(Native Method)
09-23 03:54:42.088: E/AndroidRuntime(1016): at java.lang.reflect.Method.invoke(Method.java:511)
09-23 03:54:42.088: E/AndroidRuntime(1016): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-23 03:54:42.088: E/AndroidRuntime(1016): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-23 03:54:42.088: E/AndroidRuntime(1016): at dalvik.system.NativeStart.main(Native Method)
09-23 03:54:42.088: E/AndroidRuntime(1016): Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class android.support.v4.view.ViewPager
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:691)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
09-23 03:54:42.088: E/AndroidRuntime(1016): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.Activity.setContentView(Activity.java:1835)
09-23 03:54:42.088: E/AndroidRuntime(1016): at com.himi.viewpager.MainActivity.onCreate(MainActivity.java:33)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.Activity.performCreate(Activity.java:4465)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
09-23 03:54:42.088: E/AndroidRuntime(1016): ... 11 more
09-23 03:54:42.088: E/AndroidRuntime(1016): Caused by: java.lang.ClassNotFoundException: android.support.v4.view.ViewPager
09-23 03:54:42.088: E/AndroidRuntime(1016): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
09-23 03:54:42.088: E/AndroidRuntime(1016): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
09-23 03:54:42.088: E/AndroidRuntime(1016): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.view.LayoutInflater.createView(LayoutInflater.java:552)
09-23 03:54:42.088: E/AndroidRuntime(1016): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
09-23 03:54:42.088: E/AndroidRuntime(1016): ... 21 more
原因是:这里我们导入的" android-support-v4.jar "是第三方jar包,这个第三方jar包,默认是编译的时候才会使用它,导出的(运行的时候)也必须使用这个jar包(这里就是因为导出时候,工程没有关联这个"android-support-v4.jar",才会强制退出),这样这个第三方jar也会导入到形成的apk文件中。
解决方法:
右击工程,点击"属性",找到"Java构建路径",然后去勾选这个导入的第三方jar包,如下:
点击Eclipse菜单栏的"项目"---->"清理",重新编译工程,现在我们再来布署程序到模拟器上,如下:
(5)上面只是实现基本的ViewPager功能,完成代码,如下:
1 package com.himi.viewpager; 2 3 import java.util.ArrayList; 4 5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.support.v4.view.PagerAdapter; 8 import android.support.v4.view.ViewPager; 9 import android.support.v4.view.ViewPager.OnPageChangeListener; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.ImageView; 13 import android.widget.LinearLayout; 14 import android.widget.TextView; 15 16 public class MainActivity extends Activity { 17 18 private ViewPager viewpager; 19 private LinearLayout pointGroup; 20 private TextView imageDesc; 21 22 //图片资源ID 23 private final int[] imageIds = { 24 R.drawable.a, 25 R.drawable.b, 26 R.drawable.c, 27 R.drawable.d, 28 R.drawable.e 29 }; 30 //图片标题集合 31 private final String[] imageDescriptions = { 32 "巩俐不低俗,我就不能低俗", 33 "扑树又回来了!再唱经典老歌引万人大合唱", 34 "揭秘北京电影如何升级", 35 "乐视网TV版大派送", 36 "热血屌丝的反杀" 37 }; 38 private ArrayList<ImageView> imageList; 39 /** 40 * 上一个页面的位置 41 */ 42 protected int lastPosition; 43 44 @SuppressWarnings("deprecation") 45 @Override 46 protected void onCreate(Bundle savedInstanceState) { 47 super.onCreate(savedInstanceState); 48 setContentView(R.layout.activity_main); 49 50 viewpager = (ViewPager) findViewById(R.id.viewpager); 51 pointGroup = (LinearLayout) findViewById(R.id.point_group); 52 imageDesc = (TextView) findViewById(R.id.image_desc); 53 //初始化imageDesc(TextView) 54 imageDesc.setText(imageDescriptions[0]); 55 imageList = new ArrayList<ImageView>(); 56 for(int i=0; i<imageIds.length; i++) { 57 //初始化图片资源 58 ImageView image = new ImageView(this); 59 image.setBackgroundResource(imageIds[i]); 60 imageList.add(image); 61 62 //添加指示点 63 ImageView point = new ImageView(this); 64 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(5,5); 65 params.rightMargin = 20; 66 point.setLayoutParams(params); 67 68 point.setBackgroundResource(R.drawable.point_bg); 69 if(i == 0) { 70 point.setEnabled(true); 71 }else { 72 point.setEnabled(false); 73 } 74 pointGroup.addView(point); 75 } 76 viewpager.setAdapter(new MyPagerAdapter()); 77 //给viewpager添加一个事件监听 78 viewpager.setOnPageChangeListener(new OnPageChangeListener() { 79 80 81 /** 82 * 页面切换后调用 83 * @param postion 新的页面位置 84 */ 85 public void onPageSelected( int position) { 86 //设置文字描述 87 imageDesc.setText(imageDescriptions[position]); 88 //设置指示点的状态,把当前掉enable为true 89 pointGroup.getChildAt(position).setEnabled(true); 90 //把上一个点设置为false 91 pointGroup.getChildAt(lastPosition).setEnabled(false); 92 lastPosition = position; 93 } 94 95 /** 96 * 页面正在滚动的时候,回调 97 */ 98 public void onPageScrolled( int position, float positionOffset, 99 int positionOffsetPixels) { 100 101 } 102 103 /** 104 * 当页面状态发生变化,回调 105 */ 106 public void onPageScrollStateChanged(int state) { 107 // TODO 自动生成的方法存根 108 109 } 110 }); 111 112 } 113 114 private class MyPagerAdapter extends PagerAdapter { 115 116 @Override 117 /** 118 * 获取页面的总数 119 */ 120 public int getCount() { 121 // TODO 自动生成的方法存根 122 return imageList.size(); 123 } 124 125 @Override 126 /** 127 * 判断View和Object的对应的关系 128 */ 129 public boolean isViewFromObject(View view, Object object) { 130 return view == object; 131 } 132 133 @Override 134 /** 135 * 获得相应的位置桑的View 136 * @param container view容器,其实就是viewpager自身 137 * @param position 相应的位置 138 */ 139 public Object instantiateItem(ViewGroup container, int position) { 140 //给container添加View 141 container.addView(imageList.get(position)); 142 //返回一个和该view相应的object对象 143 return imageList.get(position); 144 } 145 146 @Override 147 /** 148 * 销毁对应位置上的object 149 * @param container view容器,其实就是viewpager自身 150 * @param position 相应的位置 151 * @param object 待删除的对象 152 */ 153 public void destroyItem(ViewGroup container, int position, Object object) { 154 container.removeView((View) object); 155 object = null;//object变成空指针,也就是告诉系统可以回收 156 } 157 158 } 159 160 }
与此同时每个广告条的点设置如下:
point_normal.xml,如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <shape xmlns:android="http://schemas.android.com/apk/res/android" 3 android:shape="oval"> 4 <size android:width="5dp" android:height="5dp"/> 5 <solid android:color="#55000000"/> 6 7 </shape>
point_focused.xml,如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <shape xmlns:android="http://schemas.android.com/apk/res/android" 3 android:shape="oval"> 4 <size android:width="5dp" android:height="5dp"/> 5 <solid android:color="#aaFFFFFF"/> 6 </shape>
point_bg.xml,如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android" > 3 <item android:drawable="@drawable/point_normal" android:state_enabled="false"/> 4 <item android:drawable="@drawable/point_focused" android:state_enabled="true"/> 5 6 </selector>
运行效果如下:
2 .优化上面代码:
(1)实现广告条循环滑动效果:
MainActivity.java,如下:
1 package com.himi.viewpager; 2 3 import java.util.ArrayList; 4 5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.support.v4.view.PagerAdapter; 8 import android.support.v4.view.ViewPager; 9 import android.support.v4.view.ViewPager.OnPageChangeListener; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.ImageView; 13 import android.widget.LinearLayout; 14 import android.widget.TextView; 15 16 public class MainActivity extends Activity { 17 18 private ViewPager viewpager; 19 private LinearLayout pointGroup; 20 private TextView imageDesc; 21 22 //图片资源ID 23 private final int[] imageIds = { 24 R.drawable.a, 25 R.drawable.b, 26 R.drawable.c, 27 R.drawable.d, 28 R.drawable.e 29 }; 30 //图片标题集合 31 private final String[] imageDescriptions = { 32 "巩俐不低俗,我就不能低俗", 33 "扑树又回来了!再唱经典老歌引万人大合唱", 34 "揭秘北京电影如何升级", 35 "乐视网TV版大派送", 36 "热血屌丝的反杀" 37 }; 38 private ArrayList<ImageView> imageList; 39 /** 40 * 上一个页面的位置 41 */ 42 protected int lastPosition; 43 44 @SuppressWarnings("deprecation") 45 @Override 46 protected void onCreate(Bundle savedInstanceState) { 47 super.onCreate(savedInstanceState); 48 setContentView(R.layout.activity_main); 49 50 viewpager = (ViewPager) findViewById(R.id.viewpager); 51 pointGroup = (LinearLayout) findViewById(R.id.point_group); 52 imageDesc = (TextView) findViewById(R.id.image_desc); 53 //初始化imageDesc(TextView) 54 imageDesc.setText(imageDescriptions[0]); 55 imageList = new ArrayList<ImageView>(); 56 for(int i=0; i<imageIds.length; i++) { 57 //初始化图片资源 58 ImageView image = new ImageView(this); 59 image.setBackgroundResource(imageIds[i]); 60 imageList.add(image); 61 62 //添加指示点 63 ImageView point = new ImageView(this); 64 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(5,5); 65 params.rightMargin = 20; 66 point.setLayoutParams(params); 67 68 point.setBackgroundResource(R.drawable.point_bg); 69 if(i == 0) { 70 point.setEnabled(true); 71 }else { 72 point.setEnabled(false); 73 } 74 pointGroup.addView(point); 75 } 76 viewpager.setAdapter(new MyPagerAdapter()); 77 //给viewpager添加一个事件监听 78 viewpager.setOnPageChangeListener(new OnPageChangeListener() { 79 80 81 /** 82 * 页面切换后调用 83 * @param postion 新的页面位置 84 */ 85 public void onPageSelected( int position) { 86 position = position%imageList.size(); 87 //设置文字描述 88 imageDesc.setText(imageDescriptions[position]); 89 //设置指示点的状态,把当前掉enable为true 90 pointGroup.getChildAt(position).setEnabled(true); 91 //把上一个点设置为false 92 pointGroup.getChildAt(lastPosition).setEnabled(false); 93 lastPosition = position; 94 } 95 96 /** 97 * 页面正在滚动的时候,回调 98 */ 99 public void onPageScrolled( int position, float positionOffset, 100 int positionOffsetPixels) { 101 102 } 103 104 /** 105 * 当页面状态发生变化,回调 106 */ 107 public void onPageScrollStateChanged(int state) { 108 // TODO 自动生成的方法存根 109 110 } 111 }); 112 113 } 114 115 private class MyPagerAdapter extends PagerAdapter { 116 117 @Override 118 /** 119 * 获取页面的总数 120 */ 121 public int getCount() { 122 // TODO 自动生成的方法存根 123 return Integer.MAX_VALUE; 124 } 125 126 @Override 127 /** 128 * 判断View和Object的对应的关系 129 */ 130 public boolean isViewFromObject(View view, Object object) { 131 return view == object; 132 } 133 134 @Override 135 /** 136 * 获得相应的位置桑的View 137 * @param container view容器,其实就是viewpager自身 138 * @param position 相应的位置 139 */ 140 public Object instantiateItem(ViewGroup container, int position) { 141 //给container添加View 142 container.addView(imageList.get(position%imageList.size())); 143 //返回一个和该view相应的object对象 144 return imageList.get(position%imageList.size()); 145 } 146 147 @Override 148 /** 149 * 销毁对应位置上的object 150 * @param container view容器,其实就是viewpager自身 151 * @param position 相应的位置 152 * @param object 待销毁的对象 153 */ 154 public void destroyItem(ViewGroup container, int position, Object object) { 155 container.removeView((View) object); 156 object = null;//object变成空指针,也就是告诉系统可以回收 157 } 158 159 } 160 161 }
运行效果如下:
上面我们看到了,程序刚刚启动时候只能向右滑动,随着我们向右滑动,我们发现5张图片循环显示。当我们再次向左滑动,最后又不能显示了。
(2)上面我们已经发现了,程序刚刚启动的时候,我们只能向左滑动屏幕,这样用户体验不好,应该我们随时可以双向滑动,当然也包括程序刚刚启动的时候。
MainActivity.java,如下:
1 package com.himi.viewpager; 2 3 import java.util.ArrayList; 4 5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.support.v4.view.PagerAdapter; 8 import android.support.v4.view.ViewPager; 9 import android.support.v4.view.ViewPager.OnPageChangeListener; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.ImageView; 13 import android.widget.LinearLayout; 14 import android.widget.TextView; 15 16 public class MainActivity extends Activity { 17 18 private ViewPager viewpager; 19 private LinearLayout pointGroup; 20 private TextView imageDesc; 21 22 //图片资源ID 23 private final int[] imageIds = { 24 R.drawable.a, 25 R.drawable.b, 26 R.drawable.c, 27 R.drawable.d, 28 R.drawable.e 29 }; 30 //图片标题集合 31 private final String[] imageDescriptions = { 32 "巩俐不低俗,我就不能低俗", 33 "扑树又回来了!再唱经典老歌引万人大合唱", 34 "揭秘北京电影如何升级", 35 "乐视网TV版大派送", 36 "热血屌丝的反杀" 37 }; 38 private ArrayList<ImageView> imageList; 39 /** 40 * 上一个页面的位置 41 */ 42 protected int lastPosition; 43 44 @SuppressWarnings("deprecation") 45 @Override 46 protected void onCreate(Bundle savedInstanceState) { 47 super.onCreate(savedInstanceState); 48 setContentView(R.layout.activity_main); 49 50 viewpager = (ViewPager) findViewById(R.id.viewpager); 51 pointGroup = (LinearLayout) findViewById(R.id.point_group); 52 imageDesc = (TextView) findViewById(R.id.image_desc); 53 //初始化imageDesc(TextView) 54 imageDesc.setText(imageDescriptions[0]); 55 imageList = new ArrayList<ImageView>(); 56 for(int i=0; i<imageIds.length; i++) { 57 //初始化图片资源 58 ImageView image = new ImageView(this); 59 image.setBackgroundResource(imageIds[i]); 60 imageList.add(image); 61 62 //添加指示点 63 ImageView point = new ImageView(this); 64 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(5,5); 65 params.rightMargin = 20; 66 point.setLayoutParams(params); 67 68 point.setBackgroundResource(R.drawable.point_bg); 69 if(i == 0) { 70 point.setEnabled(true); 71 }else { 72 point.setEnabled(false); 73 } 74 pointGroup.addView(point); 75 } 76 viewpager.setAdapter(new MyPagerAdapter()); 77 78 viewpager.setCurrentItem(Integer.MAX_VALUE/2 - (Integer.MAX_VALUE/2%imageList.size())); 79 //给viewpager添加一个事件监听 80 viewpager.setOnPageChangeListener(new OnPageChangeListener() { 81 82 83 /** 84 * 页面切换后调用 85 * @param postion 新的页面位置 86 */ 87 public void onPageSelected( int position) { 88 position = position%imageList.size(); 89 //设置文字描述 90 imageDesc.setText(imageDescriptions[position]); 91 //设置指示点的状态,把当前掉enable为true 92 pointGroup.getChildAt(position).setEnabled(true); 93 //把上一个点设置为false 94 pointGroup.getChildAt(lastPosition).setEnabled(false); 95 lastPosition = position; 96 } 97 98 /** 99 * 页面正在滚动的时候,回调 100 */ 101 public void onPageScrolled( int position, float positionOffset, 102 int positionOffsetPixels) { 103 104 } 105 106 /** 107 * 当页面状态发生变化,回调 108 */ 109 public void onPageScrollStateChanged(int state) { 110 // TODO 自动生成的方法存根 111 112 } 113 }); 114 115 } 116 117 private class MyPagerAdapter extends PagerAdapter { 118 119 @Override 120 /** 121 * 获取页面的总数 122 */ 123 public int getCount() { 124 // TODO 自动生成的方法存根 125 return Integer.MAX_VALUE; 126 } 127 128 @Override 129 /** 130 * 判断View和Object的对应的关系 131 */ 132 public boolean isViewFromObject(View view, Object object) { 133 return view == object; 134 } 135 136 @Override 137 /** 138 * 获得相应的位置桑的View 139 * @param container view容器,其实就是viewpager自身 140 * @param position 相应的位置 141 */ 142 public Object instantiateItem(ViewGroup container, int position) { 143 //给container添加View 144 container.addView(imageList.get(position%imageList.size())); 145 //返回一个和该view相应的object对象 146 return imageList.get(position%imageList.size()); 147 } 148 149 @Override 150 /** 151 * 销毁对应位置上的object 152 * @param container view容器,其实就是viewpager自身 153 * @param position 相应的位置 154 * @param object 待销毁的对象 155 */ 156 public void destroyItem(ViewGroup container, int position, Object object) { 157 container.removeView((View) object); 158 object = null;//object变成空指针,也就是告诉系统可以回收 159 } 160 161 } 162 163 }
这样就可以实现了随时随地(包括程序刚刚启动)可以双向滑动。
原理:
(3)让广告页面自动每个一段时间跳转下一个,这样自动循环显示。
自动循环方式:
• 定时器:Timer
• 开子线程while true 循环
• ClockManager
• 用Handler发送延时信息,实现循环(这里我们使用这个)
MainActivity.java,如下:
1 package com.himi.viewpager; 2 3 import java.util.ArrayList; 4 5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.os.Handler; 8 import android.support.v4.view.PagerAdapter; 9 import android.support.v4.view.ViewPager; 10 import android.support.v4.view.ViewPager.OnPageChangeListener; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.widget.ImageView; 14 import android.widget.LinearLayout; 15 import android.widget.TextView; 16 17 public class MainActivity extends Activity { 18 19 private ViewPager viewpager; 20 private LinearLayout pointGroup; 21 private TextView imageDesc; 22 23 //图片资源ID 24 private final int[] imageIds = { 25 R.drawable.a, 26 R.drawable.b, 27 R.drawable.c, 28 R.drawable.d, 29 R.drawable.e 30 }; 31 //图片标题集合 32 private final String[] imageDescriptions = { 33 "巩俐不低俗,我就不能低俗", 34 "扑树又回来了!再唱经典老歌引万人大合唱", 35 "揭秘北京电影如何升级", 36 "乐视网TV版大派送", 37 "热血屌丝的反杀" 38 }; 39 private ArrayList<ImageView> imageList; 40 /** 41 * 上一个页面的位置 42 */ 43 protected int lastPosition; 44 45 @SuppressWarnings("deprecation") 46 @Override 47 protected void onCreate(Bundle savedInstanceState) { 48 super.onCreate(savedInstanceState); 49 setContentView(R.layout.activity_main); 50 51 viewpager = (ViewPager) findViewById(R.id.viewpager); 52 pointGroup = (LinearLayout) findViewById(R.id.point_group); 53 imageDesc = (TextView) findViewById(R.id.image_desc); 54 //初始化imageDesc(TextView) 55 imageDesc.setText(imageDescriptions[0]); 56 imageList = new ArrayList<ImageView>(); 57 for(int i=0; i<imageIds.length; i++) { 58 //初始化图片资源 59 ImageView image = new ImageView(this); 60 image.setBackgroundResource(imageIds[i]); 61 imageList.add(image); 62 63 //添加指示点 64 ImageView point = new ImageView(this); 65 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(5,5); 66 params.rightMargin = 20; 67 point.setLayoutParams(params); 68 69 point.setBackgroundResource(R.drawable.point_bg); 70 if(i == 0) { 71 point.setEnabled(true); 72 }else { 73 point.setEnabled(false); 74 } 75 pointGroup.addView(point); 76 } 77 viewpager.setAdapter(new MyPagerAdapter()); 78 79 viewpager.setCurrentItem(Integer.MAX_VALUE/2 - (Integer.MAX_VALUE/2%imageList.size())); 80 // 给viewpager添加一个事件监听 81 viewpager.setOnPageChangeListener(new OnPageChangeListener() { 82 83 /** 84 * 页面切换后调用 85 * 86 * @param postion 87 * 新的页面位置 88 */ 89 public void onPageSelected(int position) { 90 position = position % imageList.size(); 91 // 设置文字描述 92 imageDesc.setText(imageDescriptions[position]); 93 // 设置指示点的状态,把当前掉enable为true 94 pointGroup.getChildAt(position).setEnabled(true); 95 // 把上一个点设置为false 96 pointGroup.getChildAt(lastPosition).setEnabled(false); 97 lastPosition = position; 98 } 99 100 /** 101 * 页面正在滚动的时候,回调 102 */ 103 public void onPageScrolled(int position, float positionOffset, 104 int positionOffsetPixels) { 105 106 } 107 108 /** 109 * 当页面状态发生变化,回调 110 */ 111 public void onPageScrollStateChanged(int state) { 112 // TODO 自动生成的方法存根 113 114 } 115 }); 116 117 /** 118 * 自动循环: 119 * 1、定时器:Timer 120 * 2、 开子线程while true 循环 121 * 3、 ClockManager 122 * 4、 用Handler发送延时信息,实现循环(这里我们使用这个) 123 */ 124 isRunning = true; 125 handler.sendEmptyMessageDelayed(0, 2000); 126 127 } 128 129 /** 130 * 判断自动滚动广告条 131 */ 132 private boolean isRunning = false; 133 134 private Handler handler = new Handler(){ 135 public void handleMessage(android.os.Message msg) { 136 //让viewpager滑动到下一页 137 viewpager.setCurrentItem(viewpager.getCurrentItem()+1); 138 if(isRunning) { 139 handler.sendEmptyMessageDelayed(0, 2000); 140 } 141 }; 142 }; 143 144 protected void onDestroy() { 145 isRunning = false; 146 } 147 148 private class MyPagerAdapter extends PagerAdapter { 149 @Override 150 /** 151 * 获取页面的总数 152 */ 153 public int getCount() { 154 // TODO 自动生成的方法存根 155 return Integer.MAX_VALUE; 156 } 157 @Override 158 /** 159 * 判断View和Object的对应的关系 160 */ 161 public boolean isViewFromObject(View view, Object object) { 162 return view == object; 163 } 164 @Override 165 /** 166 * 获得相应的位置桑的View 167 * @param container view容器,其实就是viewpager自身 168 * @param position 相应的位置 169 */ 170 public Object instantiateItem(ViewGroup container, int position) { 171 // 给container添加View 172 container.addView(imageList.get(position % imageList.size())); 173 // 返回一个和该view相应的object对象 174 return imageList.get(position % imageList.size()); 175 } 176 @Override 177 /** 178 * 销毁对应位置上的object 179 * @param container view容器,其实就是viewpager自身 180 * @param position 相应的位置 181 * @param object 待销毁的对象 182 */ 183 public void destroyItem(ViewGroup container, int position, Object object) { 184 container.removeView((View) object); 185 object = null;// object变成空指针,也就是告诉系统可以回收 186 } 187 188 } 189 190 }
转载于:https://www.cnblogs.com/hebao0514/p/4831135.html
自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)...相关推荐
- Android群英传笔记——第三章:Android控件架构与自定义控件讲解
Android群英传笔记--第三章:Android控件架构与自定义控件讲解 真的很久没有更新博客了,三四天了吧,搬家干嘛的,心累,事件又很紧,抽时间把第三章大致的看完了,当然,我还是有一点View的基 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- 二级VB培训笔记06:窗体与常用控件综合案例【个人信息注册】
二级VB培训笔记06:窗体与常用控件综合案例[个人信息注册] 一.常用控件属性与方法思维导图 二.综合案例--个人信息注册 1.创建工程,修改名称为"个人信息注册",窗体名称设置为 ...
- LabView学习笔记(三):基本控件
Labview学习笔记: LabView学习笔记(一):基础介绍 LabView学习笔记(二):滤波器实验 LabView学习笔记(三):基本控件 LabView学习笔记(四):动态数据类型 LabV ...
- 学习笔记:VB.net动态添加控件数组并传递事件
学习笔记:VB.net动态添加控件数组并传递事件 控件数组和事件 "中间人" 动态添加控件 控件数组和事件 新建一个用户窗体,在定义控件数组时,不能用Withevnets来定义数组 ...
- VC2008学习笔记(二)——插入WMP控件并创建类
一.在资源视图加入窗体 二.新加入的窗体 三.插入Widows Media Player控件 右键点击"插入ActiveX 控件"--选择Windows Media Player, ...
- 【读书笔记《Android游戏编程之从零开始》】6.Android 游戏开发常用的系统控件(TabHost、ListView)...
3.9 TabSpec与TabHost TabHost类官方文档地址:http://developer.android.com/reference/android/widget/TabHost.htm ...
- 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第三章:简单控件
第 3 章 简单控件 本章介绍了App开发常见的几类简单控件的用法,主要包括:显示文字的文本视图.容纳视图的常用布局.响应点击的按钮控件.显示图片的图像视图等.然后结合本章所学的知识,演示了一个实战项 ...
- flutter笔记4:使用material原生控件开发一个APP
接着上一篇,我们做一个这样的APP: 开始之前,我发现了一个好玩的东西,每次我们在终端中输入命令: flutter run 终端里会有这个东西: 按照上图所示,我们的进入这个网页看看是个啥: 好高大上 ...
最新文章
- 山东省2021年普通高考成绩录取去向查询,2018年山东高考录取去向查询时间及入口...
- 收藏|MySQL常用语法小结
- 执行cp命令时提示cp: 略过目录
- 数据挖掘之人工神经网络BP算法
- RxJava RxPermissions 动态权限 简介 原理 案例 MD
- python动态显示进度条_实例详解python如何轻松实现动态进度条
- 阅读器xodo_佐道Xodo——手机最佳pdf阅读器
- Android系统架构开篇
- 离合器预减振超载造成变速箱怠速异响matlab与python仿真分析
- 英特尔展示业界首个一体封装光学以太网交换机
- 小程序使用echarts
- Linux硬件IO的优化简介
- 实验二木马分析(控制分析)实验和实验三冰河木马实验
- 2019ICPC南京区域赛ABCHIJK
- 基于java的小额支付管理平台
- OpenWRT软路由系统安装与优化
- HTML旅游景点网页作业制作——旅游中国11个页面(HTML+CSS+JavaScript)
- 3D游戏角色建模设计这样做,模型满分!
- hadoop初体验——WordCount实例
- android中英文切换功能,Android开发之中英文切换
热门文章
- [Alamofire] 错误总结
- pl/sql developer中建立job
- win7局域网里输入正确密码也访问不了其他的机器
- 为什么前端工程师很难找?
- GoF著作中未提到的设计模式(4):Double Dispatch
- java根据系统时间拼凑文件名字
- c语言 枚举类型 uint32_最全面C语言数据基本数据类型解析
- (2)ZYNQ FPGA加载比特流(FPGA不积跬步101)
- (72)加法器设计(全加器)
- word2vec实例详解python_在python下实现word2vec词向量训练与加载实例