自定义控件(视图)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)开始编写代码,先进行布局设计,如下:
<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)。
布局效果如下:
(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变成空指针,也就是告诉系统可以回收
} } }
布署程序到模拟器上运行,结果如下:
同时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功能,完成代码,如下:
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 .优化上面代码:
(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变成空指针,也就是告诉系统可以回收
} } }
运行效果如下:
上面我们看到了,程序刚刚启动时候只能向右滑动,随着我们向右滑动,我们发现5张图片循环显示。当我们再次向左滑动,最后又不能显示了。
(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变成空指针,也就是告诉系统可以回收
} } }
这样就可以实现了随时随地(包括程序刚刚启动)可以双向滑动。
原理:
(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)的更多相关文章
- Android群英传笔记——第三章:Android控件架构与自定义控件讲解
Android群英传笔记--第三章:Android控件架构与自定义控件讲解 真的很久没有更新博客了,三四天了吧,搬家干嘛的,心累,事件又很紧,抽时间把第三章大致的看完了,当然,我还是有一点View的基 ...
- 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理
[源码下载] 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理 作者:webabcd 介绍背水一战 Windows 10 之 控件(自定义控件) ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- VisionPro笔记(1):动态创建控件
VisionPro学习笔记(1):动态创建控件 有的时候可能需要在程序中动态创建控件,VisionPro实例中提供了一例动态创建Blob控件的方法.当然,动态创建过多的控件会极大的消耗系统的资源,建 ...
- .NET MVC 学习笔记(七)— 控制input控件
.NET MVC 学习笔记(七)— 控制input控件 画面中有时候需要输入数字,这时就需要控制input的输入.以下为保留两位有效数字. /* * 初始化数字输入 */ function initD ...
- WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要有三种实现方式 ...
- 【转】WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要有三种实现方式: 简单忙碌状态控件BusyBox: Win8/win10效果忙 ...
- 分享一下我封装iOS自定义控件的体会,附上三个好用的控件Demo <时间选择器&多行输入框&日期选择器>
前段时间有小伙伴问到我:"这样的控件该怎么做呢?",我感觉是个比较简单的控件,可能对于入行不久的同志思路没有很清晰吧.趁着最近工作不忙,就来这里分享一下我封装自定义控件的几点体会吧 ...
- Android学习笔记(九)——布局和控件的自定义
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! View是 Android中一种最基本的 UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件 ...
随机推荐
- SQL Server 2008 R2 的版本和组件
SQL Server 2008 R2 的版本和组件 SQL Server 2008 R2 其他版本 SQL Server 2008 SQL Server 2005 SQL Server 2012 ...
- (四 )Knockout - ViewModel 的使用3 - 对象属性变化的实时更新
ko.observableArray()就可以自动检测属性,其实他只是监控对象,而不是对象中的属性 使用ko.observable()进行处理 DEMO1 实时更新属性 //定义user数据对象 va ...
- 《Linux内核分析》 week5作业-system call中断处理过程
一.使用gdb跟踪分析一个系统调用内核函数 1.在test.c文件中添加time函数与采用c语言内嵌汇编的time函数.具体实现请看下图. 2.然后在main函数中添加MenuConfig函数,进行注 ...
- jQuery1.9(辅助函数)学习之——.serializeArray();
.serializeArray();返回一个Array 描述: 将用作提交的表单元素的值编译成拥有name和value对象组成的数组.例如[ { name: a value: 1 }, { name: ...
- DZ 3.2 URL 伪静态配置 教程
原文转自:http://www.zccode.com/thread-682-1-1.html 教程说明: 1 首先需要下载URL重写工具,拷到服务器下面安装即可,这里配置IIS7(x64)伪静态. 工 ...
- Symfony2 是什么(转)
本文转自:http://www.cnblogs.com/Seekr/archive/2012/06/15/2550894.html Symfoy2 是什么? PHP世界里又一广受关注的web MVC框 ...
- Top 100 words for advanced learners.
aberration (n.) something that differs from the norm (In 1974, Poland won the World Cup, but the suc ...
- AdHoc发布时出现重复Provisioning Profile的解决方案
当在developer.apple.com更新Provisioning Profile(添加新机器)后,下载到本地,双击载入xcode,运行时没问题.但如果用adhoc发布,可能会发现重复的provi ...
- c++(smart pointer)
(一)首先对智能指针有一些概念性的了解 **********本部分内容摘自开源中国社区http://my.oschina.net/u/158589/blog/28994******** 1.什么是智能 ...
- 一个简单的以User权限启动外部应用程序
BOOL ExecuteAsUser(LPCWSTR lpszUserName, LPCWSTR lpszPassword, LPCWSTR lpszApplication, LPCWSTR lpsz ...