在上一篇的文章(https://blog.csdn.net/qq_36451275/article/details/95213305)中主要以优酷菜单讲解、从这篇开始,开始以广告条为例进行详细的讲解。
还是以优酷的为例:
一、简单介绍一下ViewPager的使用
学习流程
1_创建工程名:02.广告条效果
首页影片推广效果,包名为:com.xxxxx.viewpager,并且拷贝图片到drawable-hdpi目录
2_写布局文件
3_实例化ViewPager(单独)
4_设置图片资源ID和图片标题集合和准备ImageView列表数据
5_为ViewPager设置适配器(单独)
6_解决运行报错
注意在eclipse工具中最后一步要clean
所需布局:
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="180dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/viewpager"
android:background="#44000000"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="3dp"
android:text="惊奇队长"
android:textColor="#ffffff" />
<LinearLayout
android:id="@+id/ll_point_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal" />
</LinearLayout>
二、广告条的基本功能:
1、根据页面改变设置文本
2、添加指示点
3、支持左右无限滑动
4、自动滑动界面
怎么定时刷新界面-知识扩展
方式一、使用Timer(定时器)和TimerTask实现
方式二、使用Runnable和Handler
方式三、Alarm(闹铃)
在做Android客户端软件的时候经常需要刷新某区块内容,比如微博客户端就需要定期检测是否有新发布的微博内容,如果有新微博客户端就显示出来。Android里可以选用两种方式来实现此功能。
方式一、使用Timer(定时器)和TimerTask实现
示例代码:
public class MainActivity extends Activity {
private TextView msg;
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
update();
break;
}
super.handleMessage(msg);
}
void update() {
//刷新msg的内容
}
};
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
msg = (TextView) findViewById(R.id.txtMsg);
msg.setText("你好啊!");
timer.schedule(task, 1000 * 40, 1000 * 30); //启动timer
}
@Override
protected void onDestroy() {
if (timer != null) {// 停止timer
timer.cancel();
timer = null;
}
super.onDestroy();
}
}
方式二、使用Runnable和Handler
示例代码
public class MainActivity extends Activity {
private TextView msg;
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
this.update();
handler.postDelayed(this, 1000 * 120);// 间隔120秒
}
void update() {
//刷新msg的内容
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
msg = (TextView) findViewById(R.id.txtMsg);
msg.setText("你好啊!");
handler.postDelayed(runnable, 1000 * 60);
}
@Override
protected void onDestroy() {
handler.removeCallbacks(runnable); //停止刷新
super.onDestroy();
}
}
第三种:Alarm
示例代码:
开始计时
Intent intent = new Intent(widgetUpdate);
refreshIntent = PendingIntent.getBroadcast(pContext, 0, intent, 0);
alarm = (AlarmManager)pContext.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC, 0, 1000, refreshIntent);//每秒刷新1次
停止计时
if (alarm!=null) {
alarm.cancel(refreshIntent);
refreshIntent.cancel();
refreshIntent = null;
alarm = null;
}
第一种方式还适用于消息通知的方式实现更新,第二种方式通常是主动去检查是否需要刷新。对于定时刷新这种使用第二种方式更好。
5、当手滑动或者按下的时候停止滑动
按住图片不放的情况
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN){
handler.removeCallbacksAndMessages(null);
System.out.println("ACTION_DOWN");
}else if(event.getAction()==MotionEvent.ACTION_UP){
System.out.println("ACTION_UP");
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(0,3000);
}else if(event.getAction()==MotionEvent.ACTION_CANCEL){
System.out.println("ACTION_CANCEL");
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(0,3000);
}else if(event.getAction()==MotionEvent.ACTION_MOVE){
System.out.println("ACTION_MOVE");
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(0,3000);
}
return false;
}
});
@Override
public void onPageScrollStateChanged(int state) {
//正在拖动
if(state ==ViewPager.SCROLL_STATE_DRAGGING){
System.out.println("SCROLL_STATE_DRAGGING");
//消息移除
handler.removeCallbacksAndMessages(null);
//停止状态
}else if(state ==ViewPager.SCROLL_STATE_IDLE){
System.out.println("SCROLL_STATE_IDLE");
handler.removeCallbacksAndMessages(null);//这个一定要加上
handler.sendEmptyMessageDelayed(0, 3000);
//目标页面加载完成
}else if(state ==ViewPager.SCROLL_STATE_SETTLING){
System.out.println("SCROLL_STATE_SETTLING");
}
}
6、添加点击事件
ImageView imageView = new ImageView(this);
imageView.setTag(i);//把位置设置tag
imageView.setBackgroundResource(ids[i]);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = (int) v.getTag();//把tag转换成位置
String text = imageDescriptions[position];
Toast.makeText(MainActivity.this, "text=="+text, Toast.LENGTH_SHORT).show();
}
});
三、实现广告条的整体逻辑处理:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private ViewPager viewpager;
private TextView tv_title;
private LinearLayout ll_point_group;
//ListView的使用
//1.在布局文件中定义ListView
//2.在代码中实例化ListView
//3.准备数据
//4.设置适配器-item布局-绑定数据
private ArrayList<ImageView> imageViews;
// 图片资源ID
private final int[] imageIds = {
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e };
/**
* 上一次高亮显示的位置
*/
private int prePosition = 0;
/**
* 是否已经滚动
*/
private boolean isDragging = false;
// 图片标题集合
private final String[] imageDescriptions = {
"尚硅谷波河争霸赛!",
"凝聚你我,放飞梦想!",
"抱歉没座位了!",
"7月就业名单全部曝光!",
"平均起薪11345元"
};
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int item = viewpager.getCurrentItem()+1;
viewpager.setCurrentItem(item);
//延迟发消息
handler.sendEmptyMessageDelayed(0,4000);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewpager = (ViewPager) findViewById(R.id.viewpager);
tv_title = (TextView) findViewById(R.id.tv_title);
ll_point_group = (LinearLayout) findViewById(R.id.ll_point_group);
//ViewPager的使用
//1.在布局文件中定义ViewPager
//2.在代码中实例化ViewPager
//3.准备数据
imageViews = new ArrayList<>();
for (int i = 0 ;i < imageIds.length;i++){
ImageView imageView = new ImageView(this);
imageView.setBackgroundResource(imageIds[i]);
//添加到集合中
imageViews.add(imageView);
//添加点
ImageView point = new ImageView(this);
point.setBackgroundResource(R.drawable.point_selector);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(8,8);
if(i==0){
point.setEnabled(true); //显示红色
}else{
point.setEnabled(false);//显示灰色
params.leftMargin = 8;
}
point.setLayoutParams(params);
ll_point_group.addView(point);
}
//4.设置适配器(PagerAdapter)-item布局-绑定数据
viewpager.setAdapter(new MyPagerAdapter());
//设置监听ViewPager页面的改变
viewpager.addOnPageChangeListener(new MyOnPageChangeListener());
//设置中间位置
int item = Integer.MAX_VALUE/2 - Integer.MAX_VALUE/2%imageViews.size();//要保证imageViews的整数倍
viewpager.setCurrentItem(item);
tv_title.setText(imageDescriptions[prePosition]);
//发消息
handler.sendEmptyMessageDelayed(0,3000);
}
class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {
/**
* 当页面滚动了的时候回调这个方法
* @param position 当前页面的位置
* @param positionOffset 滑动页面的百分比
* @param positionOffsetPixels 在屏幕上滑动的像数
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
/**
* 当某个页面被选中了的时候回调
* @param position 被选中页面的位置
*/
@Override
public void onPageSelected(int position) {
int realPosition = position%imageViews.size();
//设置对应页面的文本信息
tv_title.setText(imageDescriptions[realPosition]);
//把上一个高亮的设置默认-灰色
ll_point_group.getChildAt(prePosition).setEnabled(false);
//当前的设置为高亮-红色
ll_point_group.getChildAt(realPosition).setEnabled(true);
prePosition = realPosition;
}
/**
当页面滚动状态变化的时候回调这个方法
静止->滑动
滑动-->静止
静止-->拖拽
*/
@Override
public void onPageScrollStateChanged(int state) {
if(state == ViewPager.SCROLL_STATE_DRAGGING){
isDragging = true;
handler.removeCallbacksAndMessages(null);
Log.e(TAG,"SCROLL_STATE_DRAGGING-------------------");
}else if(state == ViewPager.SCROLL_STATE_SETTLING){
Log.e(TAG,"SCROLL_STATE_SETTLING-----------------");
}else if(state == ViewPager.SCROLL_STATE_IDLE&&isDragging){
isDragging = false;
Log.e(TAG,"SCROLL_STATE_IDLE------------");
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(0,4000);
}
}
}
class MyPagerAdapter extends PagerAdapter{
/**
* 得到图片的总数
* @return
*/
@Override
public int getCount() {
// return imageViews.size();
return Integer.MAX_VALUE;
}
/**
* 相当于getView方法
* @param container ViewPager自身
* @param position 当前实例化页面的位置
* @return
*/
@Override
public Object instantiateItem(ViewGroup container, final int position) {
int realPosition = position%imageViews.size();
final ImageView imageView = imageViews.get(realPosition);
container.addView(imageView);//添加到ViewPager中
// Log.e(TAG, "instantiateItem==" + position + ",---imageView==" + imageView);
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN://手指按下
Log.e(TAG,"onTouch==手指按下");
handler.removeCallbacksAndMessages(null);
break;
case MotionEvent.ACTION_MOVE://手指在这个控件上移动
break;
case MotionEvent.ACTION_CANCEL://手指在这个控件上移动
Log.e(TAG,"onTouch==事件取消");
// handler.removeCallbacksAndMessages(null);
// handler.sendEmptyMessageDelayed(0,4000);
break;
case MotionEvent.ACTION_UP://手指离开
Log.e(TAG,"onTouch==手指离开");
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(0,4000);
break;
}
return false;
}
});
imageView.setTag(position);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG,"点击事件");
int position = (int) v.getTag()%imageViews.size();
String text = imageDescriptions[position];
Toast.makeText(MainActivity.this, "text=="+text, Toast.LENGTH_SHORT).show();
}
});
return imageView;
}
/**
* 比较view和object是否同一个实例
* @param view 页面
* @param object 这个方法instantiateItem返回的结果
* @return
*/
@Override
public boolean isViewFromObject(View view, Object object) {
// if(view == object){
// return true;
// }else{
// return false;
// }
return view == object;
}
/**
* 释放资源
* @param container viewpager
* @param position 要释放的位置
* @param object 要释放的页面
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
// Log.e(TAG, "destroyItem==" + position + ",---object==" + object);
container.removeView((View) object);
}
}
}
四、ViewPager扩展:
Object instantiateItem(View container, int position)
此方法已废弃,使用 instantiateItem(ViewGroup, int)代替
abstract boolean isViewFromObject(View view, Object object)
Determines whether a page View is associated with a specific key object as returned by instantiateItem(ViewGroup, int).
void notifyDataSetChanged()
调用该方法更新数据
void registerDataSetObserver(DataSetObserver observer)
注册观察者
void restoreState(Parcelable state, ClassLoader loader)
恢复与adapter关联的所有页面的状态实例,并且该页面是通过saveState()方法保存的。
Parcelable saveState()
保存于adapter关联的所有的页面,直到调用restoreState方法时被恢复
void setPrimaryItem(View container, int position, Object object)
This method is deprecated. Use setPrimaryItem(ViewGroup, int, Object)
void setPrimaryItem(ViewGroup container, int position, Object object)
Called to inform the adapter of which item is currently considered to be the "primary", that is the one show to the user as the current page.
void startUpdate(View container)
该方法已废弃.使用 startUpdate(ViewGroup)代替
void startUpdate(ViewGroup container)
开始调用显示页面
void unregisterDataSetObserver(DataSetObserver observer)
在回调函数中通过adapter的数据变化注销观察者对象