Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 安卓圖片輪播Banner的實現

安卓圖片輪播Banner的實現

編輯:關於Android編程

圖片輪播Banner現在算是比較常見的功能了,可以用來循環播放廣告或者是熱門內容

在這裡我利用ViewPager模擬實現了Banner的功能,效果圖如下:

這裡寫圖片描述

可以看到,在剛打開應用時,顯示的只有一張動漫黃昏圖,且標示圖片數量的圓點也只有一個,這是程序的初始狀態。
然後我模擬了從服務器獲取要顯示的標題以及圖片鏈接的過程,當數據獲取成功後,就可以看到圖片開始變換輪播了,且標示圖片數量的圓點也變成了五個<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPtDCvajSu7j2uaSzzKOs0N64xMSsyM+yvL7Wo6y9q7j5sry+1rjEzqpGcmFtZUxheW91dKOsyLu688ztvNPSu7j2Vmlld1BhZ2Vyv9i8/qOs08PAtM/Uyr7NvMaso6xUZXh0Vmlld9PDwLTP1Mq+serM4qOsVmlld9fpvP7Tw8C0z9TKvtCh1LK146OsxKzIz7/JvPvQ1M6qR29uZTwvcD4NCjxwcmUgY2xhc3M9"brush:java;"> <framelayout android:layout_height="200dp" android:layout_width="match_parent" tools:context="com.czy.banner.MainActivity" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> </framelayout>

View用到了Style屬性,所以需要在styles.xml文件下添加自定義樣式dot_style,定義了圓點的大小、背景圖、邊距等屬性

工程中我也用到了universal-image-loader來下載網絡圖片,所以需要在自定義MyApplication中配置universal-image-loader屬性

/**
 * Created by ZY on 2016/7/29.
 */
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        initImageLoader(this);
    }

    private void initImageLoader(Context context) {
        File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache");
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                // 緩存路徑
                .diskCache(new UnlimitedDiskCache(cacheDir)).writeDebugLogs()
                // connectTimeout (10 s), readTimeout (10 s)  超時時間
                .imageDownloader(new BaseImageDownloader(context, 10 * 1000, 10 * 1000))
                // 緩存的文件數量
                .diskCacheFileCount(100)
                .build();
        ImageLoader.getInstance().init(config);
    }
}

然後在AndroidManifest.xml文件中為Application標簽添加

android:name=".MyApplication"

然後再自定義一個常量類Constant,用來獲取ImageLoader實例與DisplayImageOptions對象

/**
 * Created by ZY on 2016/7/29.
 * 常量
 */
public class Constant {

    public static ImageLoader getImageLoader() {
        return ImageLoader.getInstance();
    }

    public static DisplayImageOptions getDisplayImageOptions() {
        return new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.i) //設置圖片在下載期間顯示的圖片
                .showImageForEmptyUri(R.drawable.i)//設置圖片Uri為空或是錯誤的時候顯示的圖片
                .showImageOnFail(R.drawable.i)  //設置圖片加載/解碼過程中錯誤時候顯示的圖片
                .displayer(new FadeInBitmapDisplayer(500))//是否圖片加載好後漸入的動畫時間
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .build();
    }

}

再定義一個Banner實體,用來承載從網絡獲取到的數據

public class Banner {

    private String title;

    private String imgUrl;

    private String id;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

因為是利用ViewPager來實現Banner,所以還需要自定義一個Adapter繼承於PagerAdapter ,作為ViewPager的適配器

/**
 * Created by ZY on 2016/7/29.
 */
public class MyAdapter extends PagerAdapter {

    private Context context;

    private List imageViews;

    public MyAdapter(Context context,List imageViews) {
        this.context = context;
        this.imageViews = imageViews;
    }

    @Override
    public int getCount() {
        return imageViews.size();
    }

    @Override
    public Object instantiateItem(final ViewGroup container, final int position) {
        ImageView iv = imageViews.get(position);
        container.addView(iv);
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, position + "", Toast.LENGTH_SHORT).show();
            }
        });
        return iv;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }
}

在MainActivity當中,聲明的變量有:

    private ViewPager viewPager;

    private TextView articleTitle;

    private List imageViews;

    private List bannerList;

    private List dotList;
    //當前顯示的圖片索引
    private int currentItem = 0;

    private View dot0;
    private View dot1;
    private View dot2;
    private View dot3;
    private View dot4;

    private boolean flag = true;

    private Handler handler = new Handler();

    private MyAdapter adapter;

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(currentItem);
            currentItem = (currentItem + 1) % imageViews.size();
            if (flag) {
                bannerList = getNewBannerList();
                reset();
                adapter.notifyDataSetChanged();
                articleTitle.setText(bannerList.get(0).getTitle());
                flag = false;
            }
            handler.postDelayed(this, 2000);
        }
    };

初始化函數與重置函數,均會在onCreate(Bundle savedInstanceState)函數中調用,將兩者分開調用的原因是bannerList 會在程序剛打開時獲得一個初始值,即那一張動漫黃昏圖,之後會去網絡獲取新數據,如果獲取成功,則需要再次調用重置函數

    //初始化
    public void init() {
        bannerList = getDefaultBannerList();
        dotList = new ArrayList<>();
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        articleTitle = (TextView) findViewById(R.id.articleTitle);
        dot0 = findViewById(R.id.v_dot0);
        dot1 = findViewById(R.id.v_dot1);
        dot2 = findViewById(R.id.v_dot2);
        dot3 = findViewById(R.id.v_dot3);
        dot4 = findViewById(R.id.v_dot4);
        dotList.add(dot0);
        dotList.add(dot1);
        dotList.add(dot2);
        dotList.add(dot3);
        dotList.add(dot4);
    }

    //重置
    private void reset() {
        imageViews = new ArrayList<>();
        for (int i = 0; i < bannerList.size(); i++) {
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(R.drawable.i);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            Constant.getImageLoader().displayImage(bannerList.get(i).getImgUrl(),
                    imageView, Constant.getDisplayImageOptions());
            imageViews.add(imageView);
            dotList.get(i).setVisibility(View.VISIBLE);
        }
        adapter = new MyAdapter(MainActivity.this, imageViews);
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new MyPageChangeListener());
    }

bannerList 獲取默認值

//獲取默認值
    private List getDefaultBannerList() {
        List bannerList = new ArrayList<>();
        Banner banner = new Banner();
        banner.setTitle("享受閱讀的樂趣");
        banner.setId("0");
        banner.setImgUrl("");
        bannerList.add(banner);
        return bannerList;
    }

此外還需要實現ViewPager.OnPageChangeListener接口,用來在當圖片切換後更新標題與紅色圓點的位置

private class MyPageChangeListener implements ViewPager.OnPageChangeListener {

        private int oldPosition = 0;

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageSelected(int position) {
            currentItem = position;
            Banner banner = bannerList.get(position);
            articleTitle.setText(banner.getTitle());
            dotList.get(oldPosition).setBackgroundResource(R.drawable.dot_blur);
            dotList.get(position).setBackgroundResource(R.drawable.dot_focus);
            oldPosition = position;
        }
    }

因為還需要實現自動輪播圖片的功能,所以需要設置一個定時任務,這裡采用handler對象的postDelayed方法

首先需要聲明一個Handler 與Runnable 對象,在Runnable 對象中設置要執行的任務,即利用currentItem的值設置當前要顯示的圖片索引,然後利用flag設置在首次執行定時任務時為bannerList設置新值,重置Banner,而需要執行

articleTitle.setText(bannerList.get(0).getTitle());

的原因是設置標題的觸發點在監聽函數中,當重置了Banner後並不會觸發監聽函數,所以需要手動設置一次

    private Handler handler = new Handler();

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(currentItem);
            currentItem = (currentItem + 1) % imageViews.size();
            if (flag) {
                bannerList = getNewBannerList();
                reset();
                adapter.notifyDataSetChanged();
               articleTitle.setText(bannerList.get(0).getTitle());
                flag = false;
            }
            handler.postDelayed(this, 2000);
        }
    };

為bannerList設置新值的函數,模擬從網絡獲取數據的過程

private List getNewBannerList() {
        List bannerList = new ArrayList<>();
        Banner banner1 = new Banner();
        banner1.setTitle("Snackbar的使用");
        banner1.setImgUrl("http://pic3.zhimg.com/f665508fc07c122a7d79670600ca6c9e.jpg");
        bannerList.add(banner1);
        Banner banner2 = new Banner();
        banner2.setTitle(" 實現掃碼登錄");
        banner2.setImgUrl("http://pic3.zhimg.com//144edd4fa57e8b0b9c70bfea5c6b5dee.jpg");
        bannerList.add(banner2);
        Banner banner3 = new Banner();
        banner3.setTitle("Android簡易版天氣預報app的實現(改進版)");
        banner3.setImgUrl("http://pic4.zhimg.com/ea2e46e40b74da68960775b1cbcfd3bb.jpg");
        bannerList.add(banner3);
        Banner banner4 = new Banner();
        banner4.setTitle(" 自定義抽象化標題欄");
        banner4.setImgUrl("http://pic1.zhimg.com/9213def521eb908e37c15016c9d0ed24.jpg");
        bannerList.add(banner4);
        Banner banner5 = new Banner();
        banner5.setTitle("圍住神經貓(2)");
        banner5.setImgUrl("http://pic3.zhimg.com/32e1aaa65945ec773d3ffdf614c0b07e.jpg");
        bannerList.add(banner5);
        return bannerList;
    }

當中包含了要顯示的標題內容與圖片鏈接地址,依靠該圖片鏈接就可以在重置函數reset()中為ImageView設置圖片URL了

此外,定時任務的建立與取消分別在onResume()與onStop()函數當中,因為當Activuty要退出時會觸發onStop()函數,所以可以在這裡取消定時任務,而當暫停或停止後,想要恢復Activity均要調用onResume()函數,所以可以在在當中建立定時任務

 @Override
    protected void onResume() {
        super.onResume();
        handler.postDelayed(runnable, 2000);
    }

    @Override
    protected void onStop() {
        super.onStop();
        handler.removeCallbacks(runnable);
    }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved