安卓首页图片轮播效果(淘宝、京东首页广告效果)

来源:互联网 发布:windows kit 8.1 编辑:程序博客网 时间:2024/04/28 21:21

直奔主题:


1、主要原理就是利用定时任务器定时切换ViewPager的页面。

2、里面用了一个读取网络图片的插件,做客户端使用本地图片轮播的也很少。


先上个效果图:

项目代码结构截图:



自定义View 的布局文件layout_slideshow.xml:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent">  
  5.   
  6.     <android.support.v4.view.ViewPager  
  7.         android:id="@+id/viewPager"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="match_parent" />  
  10.   
  11.     <LinearLayout android:id="@+id/dotLayout"  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="wrap_content"  
  14.         android:layout_alignParentBottom="true"  
  15.         android:padding="8dp"  
  16.         android:gravity="right"  
  17.         android:orientation="horizontal">  
  18.   
  19.         <View  
  20.             android:id="@+id/v_dot1"  
  21.             android:layout_width="8dp"  
  22.             android:layout_height="8dp"  
  23.             android:background="@drawable/dot_focus" />  
  24.   
  25.         <View  
  26.             android:id="@+id/v_dot2"  
  27.             android:layout_width="8dp"  
  28.             android:layout_height="8dp"  
  29.             android:layout_marginLeft="5dp"  
  30.             android:background="@drawable/dot_blur" />  
  31.   
  32.     </LinearLayout>  
  33. </RelativeLayout>  



主界面布局文件activity_main.xml:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#FFFFFF"  
  6.     tools:context="com.example.slideshowdemo.MainActivity"  >  
  7.   
  8.           
  9.     <!-- 主题图片 -->  
  10.     <com.example.slideshowdemo.customview.SlideShowView  
  11.         android:id="@+id/slideshowView"  
  12.         android:layout_width="fill_parent"  
  13.         android:layout_height="180dp"  
  14.         android:layout_centerHorizontal="true" />  
  15.       
  16. </LinearLayout>  


自定义View 代码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.slideshowdemo.customview;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import java.util.concurrent.Executors;  
  6. import java.util.concurrent.ScheduledExecutorService;  
  7. import java.util.concurrent.TimeUnit;  
  8.   
  9. import android.content.Context;  
  10. import android.graphics.drawable.Drawable;  
  11. import android.os.AsyncTask;  
  12. import android.os.Handler;  
  13. import android.os.Message;  
  14. import android.os.Parcelable;  
  15. import android.support.v4.view.PagerAdapter;  
  16. import android.support.v4.view.ViewPager;  
  17. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  18. import android.util.AttributeSet;  
  19. import android.view.LayoutInflater;  
  20. import android.view.View;  
  21. import android.widget.FrameLayout;  
  22. import android.widget.ImageView;  
  23. import android.widget.ImageView.ScaleType;  
  24. import android.widget.LinearLayout;  
  25.   
  26. import com.example.slideshowdemo.R;  
  27. import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;  
  28. import com.nostra13.universalimageloader.core.ImageLoader;  
  29. import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;  
  30. import com.nostra13.universalimageloader.core.assist.QueueProcessingType;  
  31.   
  32.   
  33. /** 
  34.  * ViewPager实现的轮播图广告自定义视图,如京东首页的广告轮播图效果; 
  35.  * 既支持自动轮播页面也支持手势滑动切换页面 
  36.  *  
  37.  * 
  38.  */  
  39.   
  40. public class SlideShowView extends FrameLayout {  
  41.       
  42.     // 使用universal-image-loader插件读取网络图片,需要工程导入universal-image-loader-1.8.6-with-sources.jar  
  43.     private ImageLoader imageLoader = ImageLoader.getInstance();  
  44.   
  45.     //轮播图图片数量  
  46.     private final static int IMAGE_COUNT = 5;  
  47.     //自动轮播的时间间隔  
  48.     private final static int TIME_INTERVAL = 5;  
  49.     //自动轮播启用开关  
  50.     private final static boolean isAutoPlay = true;   
  51.       
  52.     //自定义轮播图的资源  
  53.     private String[] imageUrls;  
  54.     //放轮播图片的ImageView 的list  
  55.     private List<ImageView> imageViewsList;  
  56.     //放圆点的View的list  
  57.     private List<View> dotViewsList;  
  58.       
  59.     private ViewPager viewPager;  
  60.     //当前轮播页  
  61.     private int currentItem  = 0;  
  62.     //定时任务  
  63.     private ScheduledExecutorService scheduledExecutorService;  
  64.       
  65.     private Context context;  
  66.       
  67.     //Handler  
  68.     private Handler handler = new Handler(){  
  69.   
  70.         @Override  
  71.         public void handleMessage(Message msg) {  
  72.             // TODO Auto-generated method stub  
  73.             super.handleMessage(msg);  
  74.             viewPager.setCurrentItem(currentItem);  
  75.         }  
  76.           
  77.     };  
  78.       
  79.     public SlideShowView(Context context) {  
  80.         this(context,null);  
  81.         // TODO Auto-generated constructor stub  
  82.     }  
  83.     public SlideShowView(Context context, AttributeSet attrs) {  
  84.         this(context, attrs, 0);  
  85.         // TODO Auto-generated constructor stub  
  86.     }  
  87.     public SlideShowView(Context context, AttributeSet attrs, int defStyle) {  
  88.         super(context, attrs, defStyle);  
  89.         this.context = context;  
  90.   
  91.         initImageLoader(context);  
  92.           
  93.         initData();  
  94.         if(isAutoPlay){  
  95.             startPlay();  //此处调用,可能viewpager还是空,不妥?
  96.         }  
  97.           
  98.     }  
  99.     /** 
  100.      * 开始轮播图切换 
  101.      */  
  102.     private void startPlay(){  
  103.         scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();  
  104.         scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 14, TimeUnit.SECONDS);  
  105.     }  
  106.     /** 
  107.      * 停止轮播图切换 
  108.      */  
  109.     private void stopPlay(){  
  110.         scheduledExecutorService.shutdown();  
  111.     }  
  112.     /** 
  113.      * 初始化相关Data 
  114.      */  
  115.     private void initData(){  
  116.         imageViewsList = new ArrayList<ImageView>();  
  117.         dotViewsList = new ArrayList<View>();  
  118.   
  119.         // 一步任务获取图片  
  120.         new GetListTask().execute("");  
  121.     }  
  122.     /** 
  123.      * 初始化Views等UI 
  124.      */  
  125.     private void initUI(Context context){  
  126.         if(imageUrls == null || imageUrls.length == 0)  
  127.             return;  
  128.           
  129.         LayoutInflater.from(context).inflate(R.layout.layout_slideshow, thistrue);  
  130.           
  131.         LinearLayout dotLayout = (LinearLayout)findViewById(R.id.dotLayout);  
  132.         dotLayout.removeAllViews();  
  133.           
  134.         // 热点个数与图片特殊相等  
  135.         for (int i = 0; i < imageUrls.length; i++) {  
  136.             ImageView view =  new ImageView(context);  
  137.             view.setTag(imageUrls[i]);  
  138.             if(i==0)//给一个默认图  
  139.                 view.setBackgroundResource(R.drawable.appmain_subject_1);  
  140.             view.setScaleType(ScaleType.FIT_XY);  
  141.             imageViewsList.add(view);  
  142.               
  143.             ImageView dotView =  new ImageView(context);  
  144.             LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);  
  145.             params.leftMargin = 4;  
  146.             params.rightMargin = 4;  
  147.             dotLayout.addView(dotView, params);  
  148.             dotViewsList.add(dotView);  
  149.         }  
  150.           
  151.         viewPager = (ViewPager) findViewById(R.id.viewPager);  
  152.         viewPager.setFocusable(true);  
  153.           
  154.         viewPager.setAdapter(new MyPagerAdapter());  
  155.         viewPager.setOnPageChangeListener(new MyPageChangeListener());  
  156.     }  
  157.       
  158.     /** 
  159.      * 填充ViewPager的页面适配器 
  160.      *  
  161.      */  
  162.     private class MyPagerAdapter  extends PagerAdapter{  
  163.   
  164.         @Override  
  165.         public void destroyItem(View container, int position, Object object) {  
  166.             // TODO Auto-generated method stub  
  167.             //((ViewPag.er)container).removeView((View)object);  
  168.             ((ViewPager)container).removeView(imageViewsList.get(position));  
  169.         }  
  170.   
  171.         @Override  
  172.         public Object instantiateItem(View container, int position) {  
  173.             ImageView imageView = imageViewsList.get(position);  
  174.   
  175.             imageLoader.displayImage(imageView.getTag() + "", imageView);  
  176.               
  177.             ((ViewPager)container).addView(imageViewsList.get(position));  
  178.             return imageViewsList.get(position);  
  179.         }  
  180.   
  181.         @Override  
  182.         public int getCount() {  
  183.             // TODO Auto-generated method stub  
  184.             return imageViewsList.size();  
  185.         }  
  186.   
  187.         @Override  
  188.         public boolean isViewFromObject(View arg0, Object arg1) {  
  189.             // TODO Auto-generated method stub  
  190.             return arg0 == arg1;  
  191.         }  
  192.         @Override  
  193.         public void restoreState(Parcelable arg0, ClassLoader arg1) {  
  194.             // TODO Auto-generated method stub  
  195.   
  196.         }  
  197.   
  198.         @Override  
  199.         public Parcelable saveState() {  
  200.             // TODO Auto-generated method stub  
  201.             return null;  
  202.         }  
  203.   
  204.         @Override  
  205.         public void startUpdate(View arg0) {  
  206.             // TODO Auto-generated method stub  
  207.   
  208.         }  
  209.   
  210.         @Override  
  211.         public void finishUpdate(View arg0) {  
  212.             // TODO Auto-generated method stub  
  213.               
  214.         }  
  215.           
  216.     }  
  217.     /** 
  218.      * ViewPager的监听器 
  219.      * 当ViewPager中页面的状态发生改变时调用 
  220.      *  
  221.      */  
  222.     private class MyPageChangeListener implements OnPageChangeListener{  
  223.   
  224.        boolean isAutoPlay = false;  
  225.   
  226.         @Override  
  227.         public void onPageScrollStateChanged(int arg0) {  
  228.             // TODO Auto-generated method stub  
  229.             switch (arg0) {  
  230.             case 1:// 手指press状态,只在手势的时候有这个状态,直接setcurrentitem不会有这个状态
  231.                 isAutoPlay = false;  
  232.                 break;  
  233.             case 2:// up状态,已经滑动完毕,手势和setcurrentitem都有这个状态  
  234.                 isAutoPlay = true;  
  235.                 break;  
  236.             case 0:// up后,惯性滑动完毕,手势和setcurrentitem都有这个状态  
  237.                 // 当前为最后一张,则切换到第一张  
  238. //如果不是手势滑,在定时器里已经有取模操作,
  239.                 if (viewPager.getCurrentItem() == viewPager.getAdapter().getCount() - 1 && !isAutoPlay) {  
  240.                     viewPager.setCurrentItem(0);  
  241.                 }  
  242.                 // 当前为第一张,此时从左向右滑,则切换到最后一张  
  243.                 else if (viewPager.getCurrentItem() == 0 && !isAutoPlay) {  
  244.                     viewPager.setCurrentItem(viewPager.getAdapter().getCount() - 1);  
  245.                 }  
  246.                 break;  
  247.         }  
  248.         }  
  249.   
  250.         @Override  
  251.         public void onPageScrolled(int arg0, float arg1, int arg2) {  
  252.             // TODO Auto-generated method stub  
  253.               
  254.         }  
  255.   
  256.         @Override  
  257.         public void onPageSelected(int pos) {  
  258.             // TODO Auto-generated method stub  
  259.               
  260.             currentItem = pos;  
  261.             for(int i=0;i < dotViewsList.size();i++){  
  262.                 if(i == pos){  
  263.                     ((View)dotViewsList.get(pos)).setBackgroundResource(R.drawable.dot_focus);  
  264.                 }else {  
  265.                     ((View)dotViewsList.get(i)).setBackgroundResource(R.drawable.dot_blur);  
  266.                 }  
  267.             }  
  268.         }  
  269.           
  270.     }  
  271.       
  272.     /** 
  273.      *执行轮播图切换任务 
  274.      * 
  275.      */  
  276.     private class SlideShowTask implements Runnable{  
  277.   
  278.         @Override  
  279.         public void run() {  
  280.             // TODO Auto-generated method stub  
  281.             synchronized (viewPager) {  
  282.                 currentItem = (currentItem+1)%imageViewsList.size();  
  283.                 handler.obtainMessage().sendToTarget();  
  284.             }  
  285.         }  
  286.           
  287.     }  
  288.       
  289.     /** 
  290.      * 销毁ImageView资源,回收内存 
  291.      *  
  292.      */  
  293.     private void destoryBitmaps() {  
  294.   
  295.         for (int i = 0; i < IMAGE_COUNT; i++) {  
  296.             ImageView imageView = imageViewsList.get(i);  
  297.             Drawable drawable = imageView.getDrawable();  
  298.             if (drawable != null) {  
  299.                 //解除drawable对view的引用  
  300.                 drawable.setCallback(null);  
  301.             }  
  302.         }  
  303.     }  
  304.    
  305.   
  306.     /** 
  307.      * 异步任务,获取数据 
  308.      *  
  309.      */  
  310.     class GetListTask extends AsyncTask<String, Integer, Boolean> {  
  311.   
  312.         @Override  
  313.         protected Boolean doInBackground(String... params) {  
  314.             try {  
  315.                 // 这里一般调用服务端接口获取一组轮播图片,下面是从百度找的几个图片  
  316.                   
  317.                 imageUrls = new String[]{  
  318.                         "http://image.zcool.com.cn/56/35/1303967876491.jpg",  
  319.                         "http://image.zcool.com.cn/59/54/m_1303967870670.jpg",  
  320.                         "http://image.zcool.com.cn/47/19/1280115949992.jpg",  
  321.                         "http://image.zcool.com.cn/59/11/m_1303967844788.jpg"  
  322.                 };  
  323.                 return true;  
  324.             } catch (Exception e) {  
  325.                 e.printStackTrace();  
  326.                 return false;  
  327.             }  
  328.         }  
  329.   
  330.         @Override  
  331.         protected void onPostExecute(Boolean result) {  
  332.             super.onPostExecute(result);  
  333.             if (result) {  
  334.                 initUI(context);  
  335.             }  
  336.         }  
  337.     }  
  338.       
  339.     /** 
  340.      * ImageLoader 图片组件初始化 
  341.      *  
  342.      * @param context 
  343.      */  
  344.     public static void initImageLoader(Context context) {  
  345.         // This configuration tuning is custom. You can tune every option, you  
  346.         // may tune some of them,  
  347.         // or you can create default configuration by  
  348.         // ImageLoaderConfiguration.createDefault(this);  
  349.         // method.  
  350.         ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context).threadPriority(Thread.NORM_PRIORITY - 2).denyCacheImageMultipleSizesInMemory().discCacheFileNameGenerator(new Md5FileNameGenerator()).tasksProcessingOrder(QueueProcessingType.LIFO).writeDebugLogs() // Remove  
  351.                                                                                                                                                                                                                                                                                                 // for  
  352.                                                                                                                                                                                                                                                                                                 // release  
  353.                                                                                                                                                                                                                                                                                                 // app  
  354.                 .build();  
  355.         // Initialize ImageLoader with configuration.  
  356.         ImageLoader.getInstance().init(config);  
  357.     }  
  358. }  



主界面Activity代码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.slideshowdemo;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6. public class MainActivity extends Activity {  
  7.   
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.activity_main);  
  12.     }  
  13.   
  14. }  

下面附上使用到的图片素材:

热点图1:

热点图2:

效果默认图片:(建议做一个灰色的不含有具体内容的默认加载图片,这里做demo就随便找了一个)


真正无限循环的viewpager参考:http://blog.csdn.net/lamp_zy/article/details/52442623




0 1
原创粉丝点击