广告条效果(ViewPager)
广告条效果(ViewPager)
1. ViewPager的使用(参考ViewPager使用笔记)
1_创建工程名:
02.广告条效果
首页影片推广效果,并且拷贝图片到drawable-hdpi目录
2_写布局文件
<?xml version="1.0" encoding="utf-8"?>
<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"
>
<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="美国队长3"
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>
</RelativeLayout>
3_实例化ViewPager(单独)
private ViewPager viewpager;
viewpager = (ViewPager) findViewById(R.id.viewpager);
4_设置图片资源ID和图片标题集合和准备ImageView列表数据
private TextView tv_title;
private LinearLayout ll_point_group;
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元" };
设置数据
imageViews=new ArrayList<ImageView>();
for(int i=0;i<imageIds.length;i++)
{
ImageView imageView=new ImageView(this);
imageView.setBackgroundResource(imageIds[i]);
//添加到集合中
imageViews.add(imageView);
.......
}
5_为ViewPager设置适配器(单独)
//4.设置适配器(PagerAdapter)-item布局-绑定数据
viewpager.setAdapter(new MyPagerAdapter());
MyPagerAdapter
class MyPagerAdapter extends PagerAdapter
{
/**
* 得到图片的总数
* @return
*/
@Override
public int getCount()
{
return Integer.MAX_VALUE;
}
@Override
public Object instantiateItem(ViewGroup container, 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://手指在这个控件上移动
Log.e(TAG,"onTouch==事件取消");
break;
case MotionEvent.ACTION_UP://手指离开
Log.e(TAG,"onTouch==手指离开");
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(0, 4000);
break;
default:
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;
}
@Override
public boolean isViewFromObject(View view, Object object)
{
return view == object;
}
/**
* 释放资源
* viewpager 默认创建2个页面,先销毁再创建
* @param container viewpager
* @param position 要释放的位置
* @param object 要释放的页面
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object)
{
container.removeView((View) object);
}
}
2. 广告条的基本功能
1.根据页面改变设置文本
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;
2.添加指示点(在准备数据的循环体中循环添加)
//添加点
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=0;
}
point.setLayoutParams(params);
ll_point_group.addView(point);
3. 支持左右无限滑动
在MyPagerAdapter适配器中,在getCount()方法体中把图片总数变得很大
/**
* 得到图片的总数
* @return
*/
@Override
public int getCount()
{
return Integer.MAX_VALUE;
}
//设置中间位置,//要保证imageViews的整数倍
int item=Integer.MAX_VALUE/2-Integer.MAX_VALUE/2%imageViews.size();
viewpager.setCurrentItem(item);
tv_title.setText(imageDescriptions[prePosition]);
4.自动滑动页面
实现的方式有很多,这里使用handler,先发消息,然后
//在onCreate()中发消息
handler.sendEmptyMessageDelayed(0, 3000);
然后在handler中处理消息
int item=viewpager.getCurrentItem()+1//滑到最后一个不会蹦,viewpager会停止
viewpager.setCurrentItem(item)
//延迟发消息
handler.sendEmptyMessageDelayed(0, 4000);
5.当手滑动或者按下的时候停止滑动
在按下的时候移除消息,up的时候发消息,不过有个小bug,按下滑动就没有了up,从此以后不滚动!
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://手指在这个控件上移动
Log.e(TAG,"onTouch==事件取消");
break;
case MotionEvent.ACTION_UP://手指离开
Log.e(TAG,"onTouch==手指离开");
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(0, 4000);
break;
default:
break;
}
return false;
}
});
解决上述bug,当手滑动或者按下的时候停止滑动
其实,如果up事件丢失后,会触发一个取消,即MotionEvent.ACTION_CANCEL;打印log发现,如果按下,确实没滑动,放开滑动这没有问题,但是一滑动,就会触发取消,不会执行up。
在页面改变监听(MyOnPageChangeListener)中解决这个bug,
定义一个状态isDragging,是否已经滚动
/**
当页面滚动状态变化的时候回调这个方法
静止->滑动
滑动-->静止
静止-->拖拽
*/
@Override
public void onPageScrollStateChanged(int state)
{
if(state==ViewPager.SCROLL_STATE_DRAGGING)
{
isDragging=true;
handler.removeCallbacksAndMessages(null);//拖拽的时候移除
}
else if(state==ViewPager.SCROLL_STATE_SETTLING)
{
Log.e(TAG,"SCROLL_STATE_SETTLING-----------------");
}
else if(state==ViewPager.SCROLL_STATE_IDLE&&isDragging)
{
isDragging=false;//不让它多次执行
handler.removeCallbacksAndMessages(null);//发消息之前先移除,防止消息执行密集
handler.sendEmptyMessageDelayed(0, 4000);
}
}
6.添加某一条的点击事件
目的是得到当前item的信息,先得到position才能得到信息,设置一个tag,即
imageView.setTag(position)
有了tag,就能设置点击事件,
在点击事件和触摸事件同时存在的情况下,触摸事件应该返回false,否则点击事件不会生效
如果触摸事件返回false即不消费,也就是点击事件消费这个事件
此时的position也要取模,否则会越界崩溃
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();
}
});
改进成全屏引导页面
ViewPager的android:layout_height属性设置为填充父窗体
android:layout_height="match_parent"
怎么定时刷新界面-知识扩展
方式一、使用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;
}
第一种方式还适用于消息通知的方式实现更新,第二种方式通常是主动去检查是否需要刷新。对于定时刷新这种使用第二种方式更好。