Android中使用ViewPager製作廣告欄滾屏效果


自制頁面效果圖 :

 

\

一. ViewPager適配頁面問題

 

1. ViewPager出現的問題

 

ViewPager佔滿全屏問題 : ViewPager在XML中定義了android:layout_height 和 android:layout_width 之後, 不論這兩個屬性的值是 fill_parent 還是 wrap_content, 都會出現ViewPager佔滿全屏的問題;

 

不使用固定值定義寬高: 爲了使ViewPager能適配各種類型的手機, 如果給ViewPager定義了高度和寬度, 與各種手機的界面兼容性肯定要大大的降低, 因此出現了下面的解決方案;

 

2. 解決方案

 

代碼中添加組件 : 不在XML界面定義該組件, 可以在佈局文件中,定義一個LinearLayout容器, 然後在代碼中動態添加ViewPager;

好處 : 這樣的好處是可以在代碼中獲取屏幕的寬高, 我們可以根據比例設定ViewPager的大小, 這樣就解決了屏幕適配的問題;

 

3. 代碼實現

 

 

	//從佈局文件中獲取ViewPager父容器
	pagerLayout = (LinearLayout) findViewById(R.id.view_pager_content);
	//創建ViewPager
    	adViewPager = new ViewPager(this);
    	
    	//獲取屏幕像素相關信息
    	DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
    	
        //根據屏幕信息設置ViewPager廣告容器的寬高
        adViewPager.setLayoutParams(new LayoutParams(dm.widthPixels, dm.heightPixels * 2 / 5));
        
        //將ViewPager容器設置到佈局文件父容器中
    	pagerLayout.addView(adViewPager);



 

 

二. ViewPager廣告欄基本解決方案

 

1. ViewPager適配器PagerAdapter

 

自定義PagerAdapter類 : 我們需要自定義一個類, 去繼承PageAdapter, 至少實現下面四個方法 :

 

destroyItem(View container, int position, Object object) :

作用 :刪除container中指定位置position的頁面;

參數 : container 就是容器, 這裏指的是ViewPager對象, position就是刪除的頁面索引;

 

int getCount() :

作用 :獲取ViewPager頁面的個數;

返回值 : ViewPager頁面個數;

 

Object instantiateItem(View container, int position) :

作用 :在給定的位置創建頁面, PageAdapter負責向指定的position位置添加View頁面;

參數 : container容器就是ViewPager, position指的是ViewPager的索引;

返回值 : 返回代表新的一頁的對象;

 

boolean isViewFromObject(View view, Object object) :

作用 :決定instantiateItem()方法返回的Object對象是不是需要顯示的頁面關聯, 這個方法必須要有;

參數 : view 要關聯的頁面, object instantiateItem()方法返回的對象;

返回值 : 是否要關聯顯示頁面與 instantiateItem()返回值;

 

爲PageAdapter關聯數據源 : 可以將一個數組或者集合與PageAdapter關聯,集合的索引與ViewPager的索引對應, destroyItem()方法中刪除集合中對應索引的元素對象, instantiateItem 添加對應索引的元素對象;

 

PageAdapter 代碼示例 :

 

    private final class AdvAdapter extends PagerAdapter {  
        private List views = null;  
  
        /**
         * 初始化數據源, 即View數組
         */
        public AdvAdapter(List views) {  
            this.views = views;  
        }  
        
        /**
         * 從ViewPager中刪除集合中對應索引的View對象
         */
        @Override  
        public void destroyItem(View container, int position, Object object) {  
            ((ViewPager) container).removeView(views.get(position));  
        }  
  
        /**
         * 獲取ViewPager的個數
         */
        @Override  
        public int getCount() {  
            return views.size();  
        }  
  
        /**
         * 從View集合中獲取對應索引的元素, 並添加到ViewPager中
         */
        @Override  
        public Object instantiateItem(View container, int position) {  
            ((ViewPager) container).addView(views.get(position), 0);  
            return views.get(position);  
        }  
  
        /**
         * 是否將顯示的ViewPager頁面與instantiateItem返回的對象進行關聯
         * 這個方法是必須實現的
         */
        @Override  
        public boolean isViewFromObject(View view, Object object) {  
            return view == object;  
        }  
    }


創建PageAdapter代碼 :

 

 

 

	private void initPageAdapter() {
		pageViews = new ArrayList();
		
		ImageView img1 = new ImageView(this);  
        img1.setBackgroundResource(R.drawable.view_add_1);  
        pageViews.add(img1);  
        
        ImageView img2 = new ImageView(this);  
        img2.setBackgroundResource(R.drawable.view_add_2);  
        pageViews.add(img2); 
        
        ImageView img3 = new ImageView(this);  
        img3.setBackgroundResource(R.drawable.view_add_3);  
        pageViews.add(img3); 
        
        ImageView img4 = new ImageView(this);  
        img4.setBackgroundResource(R.drawable.view_add_4);  
        pageViews.add(img4); 
        
        ImageView img5 = new ImageView(this);  
        img5.setBackgroundResource(R.drawable.view_add_5);  
        pageViews.add(img5); 
        
        ImageView img6 = new ImageView(this);  
        img6.setBackgroundResource(R.drawable.view_add_6);  
        pageViews.add(img6);  
        
        adapter = new AdPageAdapter(pageViews);
	}


 

2. 小圓點導航策略

 

圓點存放策略 : 所有的小圓點都放在一個ViewGroup中, 有兩種圓點, 一種是當前顯示的, 一種是沒激活的, 這裏我們將一組圓點分別放入ImageView中, 並且將這些ImageView組裝起來放到ViewGroup中即可;

 

圓點導航初始化 : 最初默認顯示第一個頁面, 第一個圓點激活, 根據ViewPager個數初始化圓點的個數, 組裝圓點的時候, 第一個圓點狀態激活;

代碼如下 :

 

	private void initCirclePoint(){
		ViewGroup group = (ViewGroup) findViewById(R.id.viewGroup); 
        imageViews = new ImageView[pageViews.size()];  
        //廣告欄的小圓點圖標
        for (int i = 0; i < pageViews.size(); i++) {  
        	//創建一個ImageView, 並設置寬高. 將該對象放入到數組中
        	imageView = new ImageView(this);  
            imageView.setLayoutParams(new LayoutParams(20,20));  
            imageViews[i] = imageView;  
            
            //初始值, 默認第0個選中
            if (i == 0) {  
                imageViews[i]  
                        .setBackgroundResource(R.drawable.point_focused);  
            } else {  
                imageViews[i]  
                        .setBackgroundResource(R.drawable.point_unfocused);  
            }  
            //將小圓點放入到佈局中
            group.addView(imageViews[i]);  
        } 
	}



 

ViewPager頁面改變時圓點導航隨之改變 : 獲取ViewPager當前顯示頁面索引,重新組裝ViewGroup中的圓點排列順序, 這個方法在ViewPager頁面改變監聽器中實現;

代碼如下 :

 

	/**
	 *	ViewPager 頁面改變監聽器 
	 */
    private final class AdPageChangeListener implements OnPageChangeListener {  
    	
    	/**
    	 * 頁面滾動狀態發生改變的時候觸發
    	 */
        @Override  
        public void onPageScrollStateChanged(int arg0) {  
        }  
  
        /**
         * 頁面滾動的時候觸發
         */
        @Override  
        public void onPageScrolled(int arg0, float arg1, int arg2) {  
        }  
  
        /**
         * 頁面選中的時候觸發
         */
        @Override  
        public void onPageSelected(int arg0) {  
        	//獲取當前顯示的頁面是哪個頁面
            atomicInteger.getAndSet(arg0);  
            //重新設置原點佈局集合
            for (int i = 0; i < imageViews.length; i++) {  
                imageViews[arg0]  
                        .setBackgroundResource(R.drawable.point_focused);  
                if (arg0 != i) {  
                    imageViews[i]  
                            .setBackgroundResource(R.drawable.point_unfocused);  
                }  
            }  
        }  
    }



 

3. 自動翻頁導航策略

 

線程中處理自動翻頁 : 啓動一個線程, 獲取當前頁面顯示索引, 計算出下一個顯示位置, 顯示下一個頁面;

.

相關代碼 :

線程代碼 :

 

    	new Thread(new Runnable() {  
            @Override  
            public void run() {  
                while (true) {  
                    if (isContinue) {  
                        viewHandler.sendEmptyMessage(atomicInteger.get());  
                        atomicOption();  
                    }  
                }  
            }  
        }).start();


handler代碼 :

 

 

    private void atomicOption() {  
        atomicInteger.incrementAndGet();  
        if (atomicInteger.get() > imageViews.length - 1) {  
        	atomicInteger.getAndAdd(-5);  
        }  
        try {  
            Thread.sleep(3000);  
        } catch (InterruptedException e) {  
              
        }  
    } 
	
    /*
     * 每隔固定時間切換廣告欄圖片
     */
    private final Handler viewHandler = new Handler() {  
  
        @Override  
        public void handleMessage(Message msg) {  
        	adViewPager.setCurrentItem(msg.what);  
            super.handleMessage(msg);  
        }  
  
    };



 

三. 程序主要代碼

 

主Activity源碼 :

 

package shuliang.han.myviewpager;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

	private ViewPager adViewPager;
	private LinearLayout pagerLayout;
	private List pageViews;
	private ImageView[] imageViews;
	private ImageView imageView;  
	private AdPageAdapter adapter;
	private AtomicInteger atomicInteger = new AtomicInteger(0);  
    private boolean isContinue = true; 
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		initViewPager();
	}

	private void initViewPager() {

	//從佈局文件中獲取ViewPager父容器
	pagerLayout = (LinearLayout) findViewById(R.id.view_pager_content);
	//創建ViewPager
    	adViewPager = new ViewPager(this);
    	
    	//獲取屏幕像素相關信息
    	DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
    	
        //根據屏幕信息設置ViewPager廣告容器的寬高
        adViewPager.setLayoutParams(new LayoutParams(dm.widthPixels, dm.heightPixels * 2 / 5));
        
        //將ViewPager容器設置到佈局文件父容器中
    	pagerLayout.addView(adViewPager);
    	
    	initPageAdapter();
    	
    	initCirclePoint();
    	
    	adViewPager.setAdapter(adapter);
    	adViewPager.setOnPageChangeListener(new AdPageChangeListener());
    	
    	new Thread(new Runnable() {  
            @Override  
            public void run() {  
                while (true) {  
                    if (isContinue) {  
                        viewHandler.sendEmptyMessage(atomicInteger.get());  
                        atomicOption();  
                    }  
                }  
            }  
        }).start();  
	}
	
	
    private void atomicOption() {  
        atomicInteger.incrementAndGet();  
        if (atomicInteger.get() > imageViews.length - 1) {  
        	atomicInteger.getAndAdd(-5);  
        }  
        try {  
            Thread.sleep(3000);  
        } catch (InterruptedException e) {  
              
        }  
    } 
	
    /*
     * 每隔固定時間切換廣告欄圖片
     */
    private final Handler viewHandler = new Handler() {  
  
        @Override  
        public void handleMessage(Message msg) {  
        	adViewPager.setCurrentItem(msg.what);  
            super.handleMessage(msg);  
        }  
  
    }; 
	
	private void initPageAdapter() {
		pageViews = new ArrayList();
		
		ImageView img1 = new ImageView(this);  
        img1.setBackgroundResource(R.drawable.view_add_1);  
        pageViews.add(img1);  
        
        ImageView img2 = new ImageView(this);  
        img2.setBackgroundResource(R.drawable.view_add_2);  
        pageViews.add(img2); 
        
        ImageView img3 = new ImageView(this);  
        img3.setBackgroundResource(R.drawable.view_add_3);  
        pageViews.add(img3); 
        
        ImageView img4 = new ImageView(this);  
        img4.setBackgroundResource(R.drawable.view_add_4);  
        pageViews.add(img4); 
        
        ImageView img5 = new ImageView(this);  
        img5.setBackgroundResource(R.drawable.view_add_5);  
        pageViews.add(img5); 
        
        ImageView img6 = new ImageView(this);  
        img6.setBackgroundResource(R.drawable.view_add_6);  
        pageViews.add(img6);  
        
        adapter = new AdPageAdapter(pageViews);
	}
	
	private void initCirclePoint(){
		ViewGroup group = (ViewGroup) findViewById(R.id.viewGroup); 
        imageViews = new ImageView[pageViews.size()];  
        //廣告欄的小圓點圖標
        for (int i = 0; i < pageViews.size(); i++) {  
        	//創建一個ImageView, 並設置寬高. 將該對象放入到數組中
        	imageView = new ImageView(this);  
            imageView.setLayoutParams(new LayoutParams(10,10));  
            imageViews[i] = imageView;  
            
            //初始值, 默認第0個選中
            if (i == 0) {  
                imageViews[i]  
                        .setBackgroundResource(R.drawable.point_focused);  
            } else {  
                imageViews[i]  
                        .setBackgroundResource(R.drawable.point_unfocused);  
            }  
            //將小圓點放入到佈局中
            group.addView(imageViews[i]);  
        } 
	}
	
	/**
	 *	ViewPager 頁面改變監聽器 
	 */
    private final class AdPageChangeListener implements OnPageChangeListener {  
    	
    	/**
    	 * 頁面滾動狀態發生改變的時候觸發
    	 */
        @Override  
        public void onPageScrollStateChanged(int arg0) {  
        }  
  
        /**
         * 頁面滾動的時候觸發
         */
        @Override  
        public void onPageScrolled(int arg0, float arg1, int arg2) {  
        }  
  
        /**
         * 頁面選中的時候觸發
         */
        @Override  
        public void onPageSelected(int arg0) {  
        	//獲取當前顯示的頁面是哪個頁面
            atomicInteger.getAndSet(arg0);  
            //重新設置原點佈局集合
            for (int i = 0; i < imageViews.length; i++) {  
                imageViews[arg0]  
                        .setBackgroundResource(R.drawable.point_focused);  
                if (arg0 != i) {  
                    imageViews[i]  
                            .setBackgroundResource(R.drawable.point_unfocused);  
                }  
            }  
        }  
    } 
	
	
    private final class AdPageAdapter extends PagerAdapter {  
        private List views = null;  
  
        /**
         * 初始化數據源, 即View數組
         */
        public AdPageAdapter(List views) {  
            this.views = views;  
        }  
        
        /**
         * 從ViewPager中刪除集合中對應索引的View對象
         */
        @Override  
        public void destroyItem(View container, int position, Object object) {  
            ((ViewPager) container).removeView(views.get(position));  
        }  
  
        /**
         * 獲取ViewPager的個數
         */
        @Override  
        public int getCount() {  
            return views.size();  
        }  
  
        /**
         * 從View集合中獲取對應索引的元素, 並添加到ViewPager中
         */
        @Override  
        public Object instantiateItem(View container, int position) {  
            ((ViewPager) container).addView(views.get(position), 0);  
            return views.get(position);  
        }  
  
        /**
         * 是否將顯示的ViewPager頁面與instantiateItem返回的對象進行關聯
         * 這個方法是必須實現的
         */
        @Override  
        public boolean isViewFromObject(View view, Object object) {  
            return view == object;  
        }  
    }
}



 

源碼下載地址 : http://download.csdn.net/detail/han1202012/6835401


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章