自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

时间:2023-02-14 07:30:15

1.首先我们看看运行效果,如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

2. 下面就是详细实现这个效果的过程:

(1)新建一个Android工程,命名为"广告条的效果",如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

(2)这里用到一个控件ViewPager,这个控件是在android-support-v4.jar(google提供扩展工具包)之中。这个包里面工具控件使用要使用全路径名声明(在Activity 或者 xml 中需要工具控件的全路径名)。

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

在上面android-support-v4.jar下找到包android.support.v4.view中有ViewPager.class,如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

可是我们发现ViewPager.class的源码没有关联好,如下操作:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

去除构建路径之后,如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

重新构建路径,如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

重新构建完之后,如下图:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

这时候在刚刚诞生的 引用的库 中的"android-support-v4.jar",找到ViewPager.class,如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

连接源代码,如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

路径:D:\software\Android\SDT\android-sdk-windows\extras\android\support\v4\src\java

点击确定,出现下面的结果:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

(3)开始编写代码,先进行布局设计,如下:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.himi.youkumenu.MainActivity" > <android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="@+id/viewpager"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#33000000"
android:orientation="vertical"
android:layout_alignBottom="@id/viewpager">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/app_name"
android:textColor="@android:color/white"
android:textSize="18sp"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/point_group"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout> </RelativeLayout>

这么上面我们看到了,要使用ViewPager必须使用全路径android.support.v4.view.ViewPager。在ViewPager的下方是用LinearLayout实现的一个广告条的横幅说明,广告条中文字使用TextView,切换的点是用LinearLayout动态添加(所以这个LinearLayout我们加了id)。

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

布局效果如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

(4)接下来完成MainActivity.java,如下:

 package com.himi.viewpager;

 import java.util.ArrayList;

 import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; public class MainActivity extends Activity { private ViewPager viewpager;
private LinearLayout pointGroup;
private TextView imageDesc; //图片资源ID
private final int[] imageIds = {
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e
};
private ArrayList<ImageView> imageList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); viewpager = (ViewPager) findViewById(R.id.viewpager);
pointGroup = (LinearLayout) findViewById(R.id.point_group);
imageDesc = (TextView) findViewById(R.id.image_desc); //初始化图片资源
imageList = new ArrayList<ImageView>();
for(int i=0; i<imageIds.length; i++) {
ImageView image = new ImageView(this);
image.setBackgroundResource(imageIds[i]);
imageList.add(image);
}
viewpager.setAdapter(new MyPagerAdapter());
} private class MyPagerAdapter extends PagerAdapter { @Override
/**
* 获取页面的总数
*/
public int getCount() {
// TODO 自动生成的方法存根
return imageList.size();
} @Override
/**
* 判断View和Object的对应的关系
*/
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
/**
* 获得相应的位置桑的View
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
*/
public Object instantiateItem(ViewGroup container, int position) {
//给container添加内容
container.addView(imageList.get(position)); return imageList.get(position);
} @Override
/**
* 销毁对应位置上的object
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
* @param object 待删除的对象
*/
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
object = null;//object变成空指针,也就是告诉系统可以回收
} } }

布署程序到模拟器上运行,结果如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

同时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包,如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

点击Eclipse菜单栏的"项目"---->"清理",重新编译工程,现在我们再来布署程序到模拟器上,如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

(5)上面只是实现基本的ViewPager功能,完成代码,如下:

 package com.himi.viewpager;

 import java.util.ArrayList;

 import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; public class MainActivity extends Activity { private ViewPager viewpager;
private LinearLayout pointGroup;
private TextView imageDesc; //图片资源ID
private final int[] imageIds = {
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e
};
//图片标题集合
private final String[] imageDescriptions = {
"巩俐不低俗,我就不能低俗",
"扑树又回来了!再唱经典老歌引万人大合唱",
"揭秘北京电影如何升级",
"乐视网TV版大派送",
"热血屌丝的反杀"
};
private ArrayList<ImageView> imageList;
/**
* 上一个页面的位置
*/
protected int lastPosition; @SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); viewpager = (ViewPager) findViewById(R.id.viewpager);
pointGroup = (LinearLayout) findViewById(R.id.point_group);
imageDesc = (TextView) findViewById(R.id.image_desc);
//初始化imageDesc(TextView)
imageDesc.setText(imageDescriptions[0]);
imageList = new ArrayList<ImageView>();
for(int i=0; i<imageIds.length; i++) {
//初始化图片资源
ImageView image = new ImageView(this);
image.setBackgroundResource(imageIds[i]);
imageList.add(image); //添加指示点
ImageView point = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(5,5);
params.rightMargin = 20;
point.setLayoutParams(params); point.setBackgroundResource(R.drawable.point_bg);
if(i == 0) {
point.setEnabled(true);
}else {
point.setEnabled(false);
}
pointGroup.addView(point);
}
viewpager.setAdapter(new MyPagerAdapter());
//给viewpager添加一个事件监听
viewpager.setOnPageChangeListener(new OnPageChangeListener() { /**
* 页面切换后调用
* @param postion 新的页面位置
*/
public void onPageSelected( int position) {
//设置文字描述
imageDesc.setText(imageDescriptions[position]);
//设置指示点的状态,把当前掉enable为true
pointGroup.getChildAt(position).setEnabled(true);
//把上一个点设置为false
pointGroup.getChildAt(lastPosition).setEnabled(false);
lastPosition = position;
} /**
* 页面正在滚动的时候,回调
*/
public void onPageScrolled( int position, float positionOffset,
int positionOffsetPixels) { } /**
* 当页面状态发生变化,回调
*/
public void onPageScrollStateChanged(int state) {
// TODO 自动生成的方法存根 }
}); } private class MyPagerAdapter extends PagerAdapter { @Override
/**
* 获取页面的总数
*/
public int getCount() {
// TODO 自动生成的方法存根
return imageList.size();
} @Override
/**
* 判断View和Object的对应的关系
*/
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
/**
* 获得相应的位置桑的View
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
*/
public Object instantiateItem(ViewGroup container, int position) {
//给container添加View
container.addView(imageList.get(position));
//返回一个和该view相应的object对象
return imageList.get(position);
} @Override
/**
* 销毁对应位置上的object
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
* @param object 待删除的对象
*/
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
object = null;//object变成空指针,也就是告诉系统可以回收
} } }

与此同时每个广告条的点设置如下:

point_normal.xml,如下:

 <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="5dp" android:height="5dp"/>
<solid android:color="#55000000"/> </shape>

point_focused.xml,如下:

 <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="5dp" android:height="5dp"/>
<solid android:color="#aaFFFFFF"/>
</shape>

point_bg.xml,如下:

 <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/point_normal" android:state_enabled="false"/>
<item android:drawable="@drawable/point_focused" android:state_enabled="true"/> </selector>

运行效果如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

2 .优化上面代码:

(1)实现广告条循环滑动效果:

MainActivity.java,如下:

 package com.himi.viewpager;

 import java.util.ArrayList;

 import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; public class MainActivity extends Activity { private ViewPager viewpager;
private LinearLayout pointGroup;
private TextView imageDesc; //图片资源ID
private final int[] imageIds = {
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e
};
//图片标题集合
private final String[] imageDescriptions = {
"巩俐不低俗,我就不能低俗",
"扑树又回来了!再唱经典老歌引万人大合唱",
"揭秘北京电影如何升级",
"乐视网TV版大派送",
"热血屌丝的反杀"
};
private ArrayList<ImageView> imageList;
/**
* 上一个页面的位置
*/
protected int lastPosition; @SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); viewpager = (ViewPager) findViewById(R.id.viewpager);
pointGroup = (LinearLayout) findViewById(R.id.point_group);
imageDesc = (TextView) findViewById(R.id.image_desc);
//初始化imageDesc(TextView)
imageDesc.setText(imageDescriptions[0]);
imageList = new ArrayList<ImageView>();
for(int i=0; i<imageIds.length; i++) {
//初始化图片资源
ImageView image = new ImageView(this);
image.setBackgroundResource(imageIds[i]);
imageList.add(image); //添加指示点
ImageView point = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(5,5);
params.rightMargin = 20;
point.setLayoutParams(params); point.setBackgroundResource(R.drawable.point_bg);
if(i == 0) {
point.setEnabled(true);
}else {
point.setEnabled(false);
}
pointGroup.addView(point);
}
viewpager.setAdapter(new MyPagerAdapter());
//给viewpager添加一个事件监听
viewpager.setOnPageChangeListener(new OnPageChangeListener() { /**
* 页面切换后调用
* @param postion 新的页面位置
*/
public void onPageSelected( int position) {
position = position%imageList.size();
//设置文字描述
imageDesc.setText(imageDescriptions[position]);
//设置指示点的状态,把当前掉enable为true
pointGroup.getChildAt(position).setEnabled(true);
//把上一个点设置为false
pointGroup.getChildAt(lastPosition).setEnabled(false);
lastPosition = position;
} /**
* 页面正在滚动的时候,回调
*/
public void onPageScrolled( int position, float positionOffset,
int positionOffsetPixels) { } /**
* 当页面状态发生变化,回调
*/
public void onPageScrollStateChanged(int state) {
// TODO 自动生成的方法存根 }
}); } private class MyPagerAdapter extends PagerAdapter { @Override
/**
* 获取页面的总数
*/
public int getCount() {
// TODO 自动生成的方法存根
return Integer.MAX_VALUE;
} @Override
/**
* 判断View和Object的对应的关系
*/
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
/**
* 获得相应的位置桑的View
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
*/
public Object instantiateItem(ViewGroup container, int position) {
//给container添加View
container.addView(imageList.get(position%imageList.size()));
//返回一个和该view相应的object对象
return imageList.get(position%imageList.size());
} @Override
/**
* 销毁对应位置上的object
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
* @param object 待销毁的对象
*/
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
object = null;//object变成空指针,也就是告诉系统可以回收
} } }

运行效果如下:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

上面我们看到了,程序刚刚启动时候只能向右滑动,随着我们向右滑动,我们发现5张图片循环显示。当我们再次向左滑动,最后又不能显示了。

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

(2)上面我们已经发现了,程序刚刚启动的时候,我们只能向左滑动屏幕,这样用户体验不好,应该我们随时可以双向滑动,当然也包括程序刚刚启动的时候。

MainActivity.java,如下:

 package com.himi.viewpager;

 import java.util.ArrayList;

 import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; public class MainActivity extends Activity { private ViewPager viewpager;
private LinearLayout pointGroup;
private TextView imageDesc; //图片资源ID
private final int[] imageIds = {
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e
};
//图片标题集合
private final String[] imageDescriptions = {
"巩俐不低俗,我就不能低俗",
"扑树又回来了!再唱经典老歌引万人大合唱",
"揭秘北京电影如何升级",
"乐视网TV版大派送",
"热血屌丝的反杀"
};
private ArrayList<ImageView> imageList;
/**
* 上一个页面的位置
*/
protected int lastPosition; @SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); viewpager = (ViewPager) findViewById(R.id.viewpager);
pointGroup = (LinearLayout) findViewById(R.id.point_group);
imageDesc = (TextView) findViewById(R.id.image_desc);
//初始化imageDesc(TextView)
imageDesc.setText(imageDescriptions[0]);
imageList = new ArrayList<ImageView>();
for(int i=0; i<imageIds.length; i++) {
//初始化图片资源
ImageView image = new ImageView(this);
image.setBackgroundResource(imageIds[i]);
imageList.add(image); //添加指示点
ImageView point = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(5,5);
params.rightMargin = 20;
point.setLayoutParams(params); point.setBackgroundResource(R.drawable.point_bg);
if(i == 0) {
point.setEnabled(true);
}else {
point.setEnabled(false);
}
pointGroup.addView(point);
}
viewpager.setAdapter(new MyPagerAdapter()); viewpager.setCurrentItem(Integer.MAX_VALUE/2 - (Integer.MAX_VALUE/2%imageList.size()));
//给viewpager添加一个事件监听
viewpager.setOnPageChangeListener(new OnPageChangeListener() { /**
* 页面切换后调用
* @param postion 新的页面位置
*/
public void onPageSelected( int position) {
position = position%imageList.size();
//设置文字描述
imageDesc.setText(imageDescriptions[position]);
//设置指示点的状态,把当前掉enable为true
pointGroup.getChildAt(position).setEnabled(true);
//把上一个点设置为false
pointGroup.getChildAt(lastPosition).setEnabled(false);
lastPosition = position;
} /**
* 页面正在滚动的时候,回调
*/
public void onPageScrolled( int position, float positionOffset,
int positionOffsetPixels) { } /**
* 当页面状态发生变化,回调
*/
public void onPageScrollStateChanged(int state) {
// TODO 自动生成的方法存根 }
}); } private class MyPagerAdapter extends PagerAdapter { @Override
/**
* 获取页面的总数
*/
public int getCount() {
// TODO 自动生成的方法存根
return Integer.MAX_VALUE;
} @Override
/**
* 判断View和Object的对应的关系
*/
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
/**
* 获得相应的位置桑的View
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
*/
public Object instantiateItem(ViewGroup container, int position) {
//给container添加View
container.addView(imageList.get(position%imageList.size()));
//返回一个和该view相应的object对象
return imageList.get(position%imageList.size());
} @Override
/**
* 销毁对应位置上的object
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
* @param object 待销毁的对象
*/
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
object = null;//object变成空指针,也就是告诉系统可以回收
} } }

这样就可以实现了随时随地(包括程序刚刚启动)可以双向滑动。

原理:

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)

(3)让广告页面自动每个一段时间跳转下一个,这样自动循环显示。

自动循环方式:

  • 定时器:Timer

  • 开子线程while  true 循环

  • ClockManager

      • 用Handler发送延时信息,实现循环(这里我们使用这个)

MainActivity.java,如下:

 package com.himi.viewpager;

 import java.util.ArrayList;

 import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; public class MainActivity extends Activity { private ViewPager viewpager;
private LinearLayout pointGroup;
private TextView imageDesc; //图片资源ID
private final int[] imageIds = {
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e
};
//图片标题集合
private final String[] imageDescriptions = {
"巩俐不低俗,我就不能低俗",
"扑树又回来了!再唱经典老歌引万人大合唱",
"揭秘北京电影如何升级",
"乐视网TV版大派送",
"热血屌丝的反杀"
};
private ArrayList<ImageView> imageList;
/**
* 上一个页面的位置
*/
protected int lastPosition; @SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); viewpager = (ViewPager) findViewById(R.id.viewpager);
pointGroup = (LinearLayout) findViewById(R.id.point_group);
imageDesc = (TextView) findViewById(R.id.image_desc);
//初始化imageDesc(TextView)
imageDesc.setText(imageDescriptions[0]);
imageList = new ArrayList<ImageView>();
for(int i=0; i<imageIds.length; i++) {
//初始化图片资源
ImageView image = new ImageView(this);
image.setBackgroundResource(imageIds[i]);
imageList.add(image); //添加指示点
ImageView point = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(5,5);
params.rightMargin = 20;
point.setLayoutParams(params); point.setBackgroundResource(R.drawable.point_bg);
if(i == 0) {
point.setEnabled(true);
}else {
point.setEnabled(false);
}
pointGroup.addView(point);
}
viewpager.setAdapter(new MyPagerAdapter()); viewpager.setCurrentItem(Integer.MAX_VALUE/2 - (Integer.MAX_VALUE/2%imageList.size()));
// 给viewpager添加一个事件监听
viewpager.setOnPageChangeListener(new OnPageChangeListener() { /**
* 页面切换后调用
*
* @param postion
* 新的页面位置
*/
public void onPageSelected(int position) {
position = position % imageList.size();
// 设置文字描述
imageDesc.setText(imageDescriptions[position]);
// 设置指示点的状态,把当前掉enable为true
pointGroup.getChildAt(position).setEnabled(true);
// 把上一个点设置为false
pointGroup.getChildAt(lastPosition).setEnabled(false);
lastPosition = position;
} /**
* 页面正在滚动的时候,回调
*/
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) { } /**
* 当页面状态发生变化,回调
*/
public void onPageScrollStateChanged(int state) {
// TODO 自动生成的方法存根 }
}); /**
* 自动循环:
* 1、定时器:Timer
* 2、 开子线程while true 循环
* 3、 ClockManager
* 4、 用Handler发送延时信息,实现循环(这里我们使用这个)
*/
isRunning = true;
handler.sendEmptyMessageDelayed(0, 2000); } /**
* 判断自动滚动广告条
*/
private boolean isRunning = false; private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
//让viewpager滑动到下一页
viewpager.setCurrentItem(viewpager.getCurrentItem()+1);
if(isRunning) {
handler.sendEmptyMessageDelayed(0, 2000);
}
};
}; protected void onDestroy() {
isRunning = false;
} private class MyPagerAdapter extends PagerAdapter {
@Override
/**
* 获取页面的总数
*/
public int getCount() {
// TODO 自动生成的方法存根
return Integer.MAX_VALUE;
}
@Override
/**
* 判断View和Object的对应的关系
*/
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
/**
* 获得相应的位置桑的View
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
*/
public Object instantiateItem(ViewGroup container, int position) {
// 给container添加View
container.addView(imageList.get(position % imageList.size()));
// 返回一个和该view相应的object对象
return imageList.get(position % imageList.size());
}
@Override
/**
* 销毁对应位置上的object
* @param container view容器,其实就是viewpager自身
* @param position 相应的位置
* @param object 待销毁的对象
*/
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
object = null;// object变成空指针,也就是告诉系统可以回收
} } }

     

自定义控件(视图)2期笔记03:自定义控件之使用系统控件(优酷案例之广告条Viewpager)的更多相关文章

  1. Android群英传笔记——第三章:Android控件架构与自定义控件讲解

    Android群英传笔记--第三章:Android控件架构与自定义控件讲解 真的很久没有更新博客了,三四天了吧,搬家干嘛的,心累,事件又很紧,抽时间把第三章大致的看完了,当然,我还是有一点View的基 ...

  2. 背水一战 Windows 10 &lpar;79&rpar; - 自定义控件&colon; Layout 系统&comma; 控件模板&comma; 事件处理

    [源码下载] 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理 作者:webabcd 介绍背水一战 Windows 10 之 控件(自定义控件) ...

  3. IOS学习笔记&lpar;四&rpar;之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  4. VisionPro笔记(1)&colon;动态创建控件

     VisionPro学习笔记(1):动态创建控件 有的时候可能需要在程序中动态创建控件,VisionPro实例中提供了一例动态创建Blob控件的方法.当然,动态创建过多的控件会极大的消耗系统的资源,建 ...

  5. &period;NET MVC 学习笔记(七)— 控制input控件

    .NET MVC 学习笔记(七)— 控制input控件 画面中有时候需要输入数字,这时就需要控制input的输入.以下为保留两位有效数字. /* * 初始化数字输入 */ function initD ...

  6. WPF自定义控件与样式&lpar;11&rpar;-等待&sol;忙&sol;正在加载状态-控件实现

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要有三种实现方式 ...

  7. 【转】WPF自定义控件与样式&lpar;11&rpar;-等待&sol;忙&sol;正在加载状态-控件实现

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要有三种实现方式: 简单忙碌状态控件BusyBox: Win8/win10效果忙 ...

  8. 分享一下我封装iOS自定义控件的体会,附上三个好用的控件Demo &lt&semi;时间选择器&amp&semi;多行输入框&amp&semi;日期选择器&gt&semi;

    前段时间有小伙伴问到我:"这样的控件该怎么做呢?",我感觉是个比较简单的控件,可能对于入行不久的同志思路没有很清晰吧.趁着最近工作不忙,就来这里分享一下我封装自定义控件的几点体会吧 ...

  9. Android学习笔记(九)——布局和控件的自定义

    //此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! View是 Android中一种最基本的 UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件 ...

随机推荐

  1. 领导让我重新做一个微信H5页面!

    leader:我们需要做一个微信H5页面,效果如图,功能如描述,时间越快越好. 需求是不是很简单呢?2015-11-24 12:44:00文末有最新更新 背景描述 前几天微信转发相关项目开发后,这是第 ...

  2. Hibernate createCriteria查询详解

    本文转载自 : http://penghao122.javaeye.com/blog/80794 1.创建一个Criteria实例 net.sf.hibernate.Criteria这个接口代表对一个 ...

  3. paip&period;注册java程序为LINUX系统服务的总结。

    paip.注册java程序为LINUX系统服务的总结. ////////////////实现开机启动. 标准方法是按照/etc/init.d/下面的文件,修改一下:然后chkconfig xxx on ...

  4. javascript事件大全4

    javascript事件列表解说 事件 浏览器支持 解说 一般事件 onclick IE3.N2 鼠标点击时触发此事件 ondblclick IE4.N4 鼠标双击时触发此事件 onmousedown ...

  5. Java hashCode

    Java中的集合(Collection)有两类,一类是List,再有一类是Set. 你知道它们的区别吗?前者集合内的元素是有序的,元素可以重复:后者元素无序,但元素不可重复. 那么这里就有一个比较严重 ...

  6. nginx使用ssl模块配置HTTPS支持

    默认情况下ssl模块并未被安装,如果要使用该模块则需要在编译时指定–with-http_ssl_module参数,安装模块依赖于OpenSSL库和一些引用文件,通常这些文件并不在同一个软件包中.通常这 ...

  7. C&num; 将&bsol;u1234类型的字符转化成汉字

    用代码获取网页的json数据时,经常会出现\u1234等字符,其实我们是知道他是汉字的 可以用下面的方法将\u1234翻译成汉字 /// <summary> /// /// </su ...

  8. memcache基础

    一.Memcache是一种缓存技术(内存),你可以把它想像成一张巨大的内存表,形式如下[它就是一个服务] key value key值(字符串) 可以放(字符串[二进制数据[视频.音频.图片]],数值 ...

  9. WPF自学入门(十)WPF MVVM简单介绍

     前面文章中,我们已经知道,WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI. 我们不管 ...

  10. 6 python高级数据处理和可视化

    6.2. pyplot作图 1.折线图和散点图 t = np.arange(0,4,0.1) plt.plot(t,t,'o',t,t+2,t,t**2,'o') plt.show() 2.柱线图 p ...