可以说广告栏是应用中必不可少的部分,有不少应用的广告栏中的图片以及点击图片后的逻辑是固定的,等待下一次升级后才会变化,这种模式不但对用户还是对应用经营者来说体验都是比较差的,当然还有大部分应用的广告栏是动态的,所谓动态,有以下几点概念:
1.图片(地址)是有服务端返回;
2.图片个数根据服务端返回的url个数决定;
3.点击图片逻辑由服务端返回;
4.支持自动切换;
动态广告栏需满足1.2.3点,第4点则属于附加条件。那么如何实现这三点呢?首先想到的便是ViewPaper,好,接下来我们先实现一个静态的,假如只有三张图片:
先看布局文件:
<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=".MainActivity" > <FrameLayout android:id="@+id/fl_ad" android:layout_width="fill_parent" android:layout_height="160dip" > <android.support.v4.view.ViewPager android:id="@+id/vp" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="30dip" android:layout_gravity="bottom" android:background="#20000000" android:gravity="center_vertical" android:orientation="vertical" > <LinearLayout android:id="@+id/ll_dots" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:layout_marginRight="10dp" android:layout_marginTop="3dip" android:gravity="center" > <View android:id="@+id/v_dot0" style="@style/dot_style" android:background="@drawable/ic_dot_selected" /> <View android:id="@+id/v_dot1" style="@style/dot_style" /> <View android:id="@+id/v_dot2" style="@style/dot_style" /> </LinearLayout> </LinearLayout> </FrameLayout> </RelativeLayout>
布局很简单是不是,外层FrameLayout,然后指示器(白点三个)覆盖在viewpaper上部,调整好位置。
再看主代码:
public class MainActivity extends Activity { private LayoutInflater mInflater; private List<View> imageViews; // 滑动的图片集合 private View v_dot0,v_dot1,v_dot2; private ViewPager vp; private MyAdapter myAdapter; private List<View> dots; // 图片标题正文的那些点 private int currentItem = 0; // 当前图片的索引号 private Timer adTimer = null; // 切换当前显示的图片 @SuppressLint("HandlerLeak") private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 1: vp.setCurrentItem(currentItem);// 切换当前显示的图片 break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mInflater = LayoutInflater.from(this); initView(); initViewPaper(); adTimer=new Timer(); adTimer.schedule(new ScrollTask(), 5*1000, 3* 1000); } private void initView() { vp=(ViewPager) findViewById(R.id.vp); //白点 v_dot0=(View) findViewById(R.id.v_dot0); v_dot1=(View) findViewById(R.id.v_dot1); v_dot2=(View) findViewById(R.id.v_dot2); } private void initViewPaper() { imageViews = new ArrayList<View>(); //初始化图片上层切换白点 dots=new ArrayList<View>(); dots.add(v_dot0); dots.add(v_dot1); dots.add(v_dot2); // 初始化图片资源 for (int i = 0; i <3; i++) { View view = mInflater.inflate(R.layout.activity_personal_ad_img, null); ImageView imageView = (ImageView) view.findViewById(R.id.img); switch (i) { case 0: imageView.setImageResource(R.drawable.ic_launcher);//第一张图片 //设置广告点击事件 view.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(getApplicationContext(), "点击了1", Toast.LENGTH_LONG).show(); } }); break; case 1: imageView.setImageResource(R.drawable.ic_launcher);//第二张图片 //设置广告点击事件 view.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(getApplicationContext(), "点击了2", Toast.LENGTH_LONG).show(); } }); break; case 2: imageView.setImageResource(R.drawable.ic_launcher);//第三张图片 //设置广告点击事件 view.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(getApplicationContext(), "点击了3", Toast.LENGTH_LONG).show(); } }); break; } imageViews.add(view); } myAdapter= new MyAdapter(); vp.setAdapter(myAdapter);// 设置填充ViewPager页面的适配器 // 设置一个监听器,当ViewPager中的页面改变时调用 vp.setOnPageChangeListener(new MyPageChangeListener()); } /** * 换行切换任务 * * @author byl * */ private class ScrollTask extends TimerTask { public void run() { if(imageViews!=null&&imageViews.size()>0){ currentItem = (currentItem + 1) % imageViews.size(); handler.sendEmptyMessage(1); // 通过Handler切换图片 } } } /** * 当ViewPager中页面的状态发生改变时调用 * * @author byl * */ private class MyPageChangeListener implements OnPageChangeListener { private int oldPosition = 0; public void onPageSelected(int position) { currentItem = position; dots.get(oldPosition).setBackgroundResource(R.drawable.ic_dot_nor); dots.get(position).setBackgroundResource(R.drawable.ic_dot_selected); oldPosition = position; } public void onPageScrollStateChanged(int arg0) { } public void onPageScrolled(int arg0, float arg1, int arg2) { } } /** * 填充ViewPager页面的适配器 * * @author byl * */ private class MyAdapter extends PagerAdapter { @Override public int getCount() { return imageViews.size(); } @Override public Object instantiateItem(View arg0, int arg1) { ((ViewPager) arg0).addView(imageViews.get(arg1)); return imageViews.get(arg1); } @Override public void destroyItem(View arg0, int arg1, Object arg2) { ((ViewPager) arg0).removeView((View) arg2); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } } @Override protected void onDestroy() { super.onDestroy(); if(adTimer!=null){ adTimer.cancel(); adTimer=null; } }
initViewPaper()中将三张广告图片(动态设置后)依次添加进imageViews(List<View>)中,并将三个小白点依次添加进dots(List<View>)中,设置Adapter,然后注册vp滑动监听vp.setOnPageChangeListener(new MyPageChangeListener());并在onPageSelected中去改变白点的状态。
自动切换则需要用到一个定时器:
adTimer=new Timer(); adTimer.schedule(new ScrollTask(), 5*1000, 3* 1000);
/** * 换行切换任务 * * @author byl * */ private class ScrollTask extends TimerTask { public void run() { if(imageViews!=null&&imageViews.size()>0){ currentItem = (currentItem + 1) % imageViews.size(); handler.sendEmptyMessage(1); // 通过Handler切换图片 } } }
// 切换当前显示的图片 @SuppressLint("HandlerLeak") private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 1: vp.setCurrentItem(currentItem);// 切换当前显示的图片 break; } }; };
效果如图:
是不是很简单,我们知道了静态广告栏的实现,那么动态广告栏其实只要稍作修改即可,无非是多了几步:
1.获取服务端返回的数据;
2.根据返回的数据确定imageViews个数;
3.根据返回的数据确定每个image的点击事件;
由于广告广告栏个数一般在3-6个,再多其实也没有什么意义,所以我这里设定了最高7张广告,实现方法是先把指示器设定为7个并全部隐藏,然后根据服务端返回的图片数量来确定要显示几个指示器;
首先,将广告的属性提取为一个对象:
1.图片URL;
2.图片点击类型;(可能是网页链接,也可能是应用中的某个Activity)
3.目标链接;(即点击后要跳转的链接)
public class Adv { private String img_url; private String type; private String target_url; public String getImg_url() { return img_url; } public void setImg_url(String img_url) { this.img_url = img_url; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getTarget_url() { return target_url; } public void setTarget_url(String target_url) { this.target_url = target_url; } }
具体属性可根据自己业务来定,网络图片加载本人用的是afinal开源控件,首先来模拟一下服务端返回的数据:
private void initAD() { imageResUrl=new ArrayList<Adv>(); Adv adv=new Adv(); adv.setImg_url("http://media.appshooting.com.tw/wp-content/uploads/2014/03/71eTnHBdXKL-640x312.jpg"); adv.setTarget_url("www.baidu.com"); adv.setType("1"); imageResUrl.add(adv); adv=new Adv(); adv.setImg_url("http://s.siliconimg.com/kb/content_images/2013/03/25/125164/1364177162_901.jpg"); adv.setTarget_url("www.baidu.com"); adv.setType("1"); imageResUrl.add(adv); adv=new Adv(); adv.setImg_url("http://www.ubergizmo.com/wp-content/uploads/2011/02/doubletwist-640x312.jpg"); adv.setTarget_url("www.baidu.com"); adv.setType("1"); imageResUrl.add(adv); adv=new Adv(); adv.setImg_url("http://cdn.arstechnica.net/wp-content/uploads/2013/09/google-plus-services-640x312.jpg"); adv.setTarget_url("www.baidu.com"); adv.setType("2"); imageResUrl.add(adv); }
初始化ViewPaper:
private void initViewPaper() { //首先将白点全部隐藏,再根据获取的图片数量显示 v_dot0.setVisibility(View.GONE); v_dot1.setVisibility(View.GONE); v_dot2.setVisibility(View.GONE); v_dot3.setVisibility(View.GONE); v_dot4.setVisibility(View.GONE); v_dot5.setVisibility(View.GONE); v_dot6.setVisibility(View.GONE); imageViews = new ArrayList<View>(); //初始化图片上层切换白点 dots = new ArrayList<View>(); // 初始化图片资源 for (int i = 0; i < imageResUrl.size(); i++) { final Adv adv=imageResUrl.get(i); View view = mInflater.inflate(R.layout.activity_personal_ad_img, null); ImageView imageView = (ImageView) view.findViewById(R.id.img); finalImageLoader.display(imageView,adv.getImg_url()); //设置广告点击事件 view.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { switch (Integer.parseInt(adv.getType())) { case 1://连接类型 Intent it = new Intent(Intent.ACTION_VIEW, Uri.parse(adv.getTarget_url())); it.setClassName("com.android.browser", "com.android.browser.BrowserActivity"); startActivity(it); break; case 2: Toast.makeText(getApplicationContext(), "点击了", Toast.LENGTH_LONG).show(); break; } } }); imageViews.add(view); switch (i) { case 0: v_dot0.setVisibility(View.VISIBLE); dots.add(v_dot0); break; case 1: v_dot1.setVisibility(View.VISIBLE); dots.add(v_dot1); break; case 2: v_dot2.setVisibility(View.VISIBLE); dots.add(v_dot2); break; case 3: v_dot3.setVisibility(View.VISIBLE); dots.add(v_dot3); break; case 4: v_dot4.setVisibility(View.VISIBLE); dots.add(v_dot4); break; case 5: v_dot5.setVisibility(View.VISIBLE); dots.add(v_dot5); break; case 6: v_dot6.setVisibility(View.VISIBLE); dots.add(v_dot6); break; } } if( imageResUrl.size()<=1){ v_dot0.setVisibility(View.GONE); }else{ for(int i=0;i<dots.size();i++){ if(i==0){ dots.get(i).setBackgroundResource(R.drawable.ic_dot_selected); }else{ dots.get(i).setBackgroundResource(R.drawable.ic_dot_nor); } } } myAdapter= new MyAdapter(); vp.setAdapter(myAdapter);// 设置填充ViewPager页面的适配器 // 设置一个监听器,当ViewPager中的页面改变时调用 vp.setOnPageChangeListener(new MyPageChangeListener()); }
在使用的过程中发现,从其他界面切换回本界面时,时不时的会出现广告栏白屏的现象,因此不能像静态广告栏那样,一直让广告图片自动切换,所以本人在onResume方法中启动自动切换,而在onPause方法中停止:
@Override protected void onResume() { super.onResume(); currentItem=0; initViewPaper(); adTimer=new Timer(); adTimer.schedule(new ScrollTask(), 5*1000, 3* 1000); } @Override protected void onPause() { super.onPause(); if(adTimer!=null){ adTimer.cancel(); adTimer=null; } }
效果如图:
如果再加上一些动画效果就跟好了:
是不是感觉棒棒哒!
源码下载地址:http://download.csdn.net/detail/baiyuliang2013/8702219