今天給大家專案中應用很廣泛的Banner輪播,每一個app都會用到這個,並且有時候會在多處去應用,這時候就在想了,把Banner輪播寫成自定義view,直接傳顯示資料,接受點選事件的回撥。在自己的實際專案中,可以根據自身的效果稍作修改,客官們,先上圖(這次全部選擇的是女神劉亦菲的照片)
各位客官,效果看了是否滿意呀,來分析一下流程:viewpager+自身的監聽方法+Handler實現滑動切換banner和banner輪播自身迴圈
顯示view的選擇
根據效果圖,我們選取FrameLayout為父佈局,裡面用ViewPager+LinearLayout(程式碼中再去設定選擇和未選擇的狀態)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
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="match_parent"
android:unselectedAlpha="1" />
<LinearLayout
android:id="@+id/layout_page"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dip" />
</FrameLayout>複製程式碼
將需要顯示的view新增到自定義view中去顯示,因為FrameLayout是父佈局,我們這裡也是繼承FrameLayout去自定義view
這裡在onFinishInflate()方法中去新增view,可以去了解一下onFinishInflate()的用法
@Override
protected void onFinishInflate() {
super.onFinishInflate();
View view = LayoutInflater.from(mContext).inflate(R.layout.banner_layout, null);
viewpager_banner = (ViewPager) view.findViewById(R.id.viewpager);
layout_page = (LinearLayout) view.findViewById(R.id.layout_page);
addView(view);
bannerModelList = new ArrayList<>();
bannerviewsList = new ArrayList<>();
}複製程式碼
根據假資料顯示內容
實際專案中,資料都是傳遞過來的,我們也採用info傳值過來的,然後根據資料進行顯示的相關設定,後期可根基自己專案的info去修改
/**
* Created by wujun on 2017/8/11.
* banner的實體類,根據自己的實際專案去定製
* @author madreain
* @desc
*/
public class BannerModel {
private int id;
private String imgurl;
public BannerModel() {
}
public BannerModel(int id, String imgurl) {
this.id = id;
this.imgurl = imgurl;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getImgurl() {
return imgurl;
}
public void setImgurl(String imgurl) {
this.imgurl = imgurl;
}
@Override
public String toString() {
return "BannerModel{" +
"id=" + id +
", imgurl='" + imgurl + '\'' +
'}';
}
}複製程式碼
資料有了,就要有資料設定的方法和拿資料做展示
繼承PagerAdapter去顯示banner輪播中的照片
layout_page.addview()去新增效果圖中的小圓點
addOnPageChangeListener()實現左右切換
/**
* 第一次設定資料的方法
*
* @param mbannerModelList
*/
public void setBannerModelList(List<BannerModel> mbannerModelList) {
this.bannerModelList = mbannerModelList;
// 本地
if (bannerModelList != null) {
if (bannerModelList.size() > 0) {
//本地儲存
bannerModelListSize = bannerModelList.size();
for (BannerModel bannerModel : bannerModelList) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
// + "!thumb" 縮圖
Glide.with(mContext).load(bannerModel.getImgurl()).into(imageView);
bannerviewsList.add(imageView);
}
}
}
//新增小圓點的圖片
if (bannerModelList != null) {
imageViews = new ImageView[bannerModelListSize];
for (int i = 0; i < bannerviewsList.size(); i++) {
imageView = new ImageView(mContext);
//設定小圓點imageview的引數
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(20, 20);
layoutParams.setMargins(10, 0, 10, 0);
// imageView.setLayoutParams(new ViewGroup.LayoutParams(20,20));//建立一個寬高均為20 的佈局
imageView.setLayoutParams(layoutParams);//建立一個寬高均為20 的佈局
imageView.setPadding(20, 0, 20, 0);
//預設選中的是第一張圖片,此時第一個小圓點是選中狀態,其他不是
if (i == 0) {
imageView.setBackgroundResource(R.drawable.shape_intro);
} else {
imageView.setBackgroundResource(R.drawable.shape_intro_nor);
}
//將imageviews新增到小圓點檢視組
layout_page.addView(imageView);
imageViews[i] = imageView;
}
bannerViewPagerAdapter = new BannerViewPagerAdapter(bannerviewsList);
viewpager_banner.setAdapter(bannerViewPagerAdapter);
viewpager_banner.addOnPageChangeListener(new GuidePageChangeListener());
// viewpager_banner.setOnPageChangeListener(new GuidePageChangeListener());
}
}複製程式碼
繼承PagerAdapter去顯示banner輪播中的照片
//照片輪播的介面卡
private class BannerViewPagerAdapter extends PagerAdapter {
private List<View> views;
private BannerViewPagerAdapter(List<View> views) {
this.views = views;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(views.get(position));
}
@Override
public void finishUpdate(ViewGroup container) {
}
@Override
public int getCount() {
if (views != null) {
return views.size();
}
return 0;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
container.addView(views.get(position));
//單獨的點選事件
views.get(position).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//todo這裡後面將點選進行介面回撥返回
}
});
return views.get(position);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}複製程式碼
addOnPageChangeListener()實現左右切換,實現OnPageChangeListener,來回切換,照片顯示改變,小圓點的選中與未選中也跟著改變
//viewpager 監聽 照片輪播
private class GuidePageChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int position) {
for (int i = 0; i < imageViews.length; i++) {
//設定index 防止下次自動播放順序出錯
index = viewpager_banner.getCurrentItem();
imageViews[position].setBackgroundResource(R.drawable.shape_intro);
//不是當前選中的page,其小圓點設定為未選中的狀態
if (position != i) {
imageViews[i].setBackgroundResource(R.drawable.shape_intro_nor);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
}複製程式碼
無限迴圈輪播
實際專案中的banner輪播是無限迴圈輪播的,這裡我們使用Handler來達到預期的效果
//自動播放
private final int AUTO_MSG = 1;
private final int HANDLE_MSG = AUTO_MSG + 1;
private static final int PHOTO_CHANGE_TIME = 2000;//定時變數
private int index = 0;
//照片輪播設定無限迴圈播放
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case AUTO_MSG:
//無線迴圈播放
if (index >= bannerModelListSize) {
index = 0;
}
viewpager_banner.setCurrentItem(index++);//收到訊息後設定當前要顯示的圖片
mHandler.sendEmptyMessageDelayed(AUTO_MSG, PHOTO_CHANGE_TIME);
break;
case HANDLE_MSG:
mHandler.sendEmptyMessageDelayed(AUTO_MSG, PHOTO_CHANGE_TIME);
break;
default:
break;
}
}
};複製程式碼
方法寫完了,什麼去觸發了,我這裡是在設定資料後呼叫,呼叫方法如下
//設定自動播放
mHandler.sendEmptyMessageDelayed(AUTO_MSG, PHOTO_CHANGE_TIME);複製程式碼
重新整理方法
實際專案中banner輪播是要有重新整理方法的,其實重新整理方法和設定資料方法類似
/**
* 重新整理的方法
*
* @param mbannerModelList
*/
public void refreshBannerModelList(List<BannerModel> mbannerModelList) {
this.bannerModelList = mbannerModelList;
if (bannerModelList.size() > 0) {
bannerModelListSize = bannerModelList.size();
//重新整理時上一次的資料要進行清除
if (bannerviewsList != null) {
bannerviewsList.clear();
} else {
bannerviewsList = new ArrayList<View>();
}
for (BannerModel bannerModel : bannerModelList) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
Glide.with(mContext).load(bannerModel.getImgurl()).into(imageView);
bannerviewsList.add(imageView);
}
}
//新增小圓點的圖片
if (bannerModelList != null) {
//照片輪播下方的小圓點重新整理時需要重新載入 並將上次的進行remove
if (layout_page != null) {
layout_page.removeAllViews();
}
//小圓點顯示的個數就是照片輪播的實體個數
imageViews = new ImageView[bannerModelListSize];
for (int i = 0; i < bannerviewsList.size(); i++) {
imageView = new ImageView(mContext);
//設定小圓點imageview的引數
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(20, 20);
layoutParams.setMargins(10, 0, 10, 0);
// imageView.setLayoutParams(new ViewGroup.LayoutParams(20,20));//建立一個寬高均為20 的佈局
imageView.setLayoutParams(layoutParams);//建立一個寬高均為20 的佈局
imageView.setPadding(20, 0, 20, 0);
//預設選中的是第一張圖片,此時第一個小圓點是選中狀態,其他不是
if (i == 0) {
imageView.setBackgroundResource(R.drawable.shape_intro);
} else {
imageView.setBackgroundResource(R.drawable.shape_intro_nor);
}
//將imageviews新增到小圓點檢視組
layout_page.addView(imageView);
imageViews[i] = imageView;
}
bannerViewPagerAdapter = new BannerViewPagerAdapter(bannerviewsList);
viewpager_banner.setAdapter(bannerViewPagerAdapter);
viewpager_banner.addOnPageChangeListener(new GuidePageChangeListener());
// viewpager_banner.setOnPageChangeListener(new GuidePageChangeListener());
}
}複製程式碼
點選事件回撥
我們將點選事件後的結果進行回撥,採用介面,設定相關監聽方法,在使用中直接拿到資料進行跳轉
private OnSelectItemClickstener onSelectItemClickstener;
/***
* bannerview點選監聽方法
* @param onSelectItemClickstener
*/
public void setsetSelectItemClickstener(OnSelectItemClickstener onSelectItemClickstener) {
this.onSelectItemClickstener = onSelectItemClickstener;
}
/**
* 接受回撥引數
*/
interface OnSelectItemClickstener {
void onSelectItem(int position, BannerModel bannerModel);
}複製程式碼
介面準備好了,在什麼時候去呼叫了,當然是在banner點選的時候去呼叫呀,上面註釋todo的地方去將介面進行回撥
//單獨的點選事件
views.get(position).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (onSelectItemClickstener != null) {
BannerModel bannerModel = bannerModelList.get(position);
onSelectItemClickstener.onSelectItem(position, bannerModel);
}
}
});複製程式碼
程式碼中使用
xml佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context="com.bannerview.MainActivity">
<com.bannerview.BannerView
android:id="@+id/bannerView"
android:layout_width="match_parent"
android:layout_height="200dp" />
<Button
android:id="@+id/btn"
android:text="重新整理"
android:layout_width="368dp"
android:layout_height="wrap_content" />
</LinearLayout>複製程式碼
java程式碼中使用,第一次設定資料,模擬重新整理資料,點選事件跳轉模擬
btn = (Button) findViewById(R.id.btn);
bannerView = (BannerView) findViewById(R.id.bannerView);
final List<BannerModel> bannerModelList = new ArrayList<>();
bannerModelList.add(new BannerModel(1, "http://bmob-cdn-10899.b0.upaiyun.com/2017/05/09/1add12e3407aa2ac80899838f5e5a097.jpg"));
bannerModelList.add(new BannerModel(2, "http://bmob-cdn-10899.b0.upaiyun.com/2017/05/09/34b6d85c406894f3803d949a78c4546e.jpg"));
bannerModelList.add(new BannerModel(3, "http://bmob-cdn-10899.b0.upaiyun.com/2017/05/09/1664c954400bf4d880fdd4d70b31ff2c.jpg"));
//第一次設定資料
bannerView.setBannerModelList(bannerModelList);
//模擬執行重新整理
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
bannerView.refreshBannerModelList(bannerModelList);
}
});
/**
* 點選事件的資料回撥
* 實際專案中根據資料挑戰到相應的介面
*/
bannerView.setsetSelectItemClickstener(new BannerView.OnSelectItemClickstener() {
@Override
public void onSelectItem(int position, BannerModel bannerModel) {
Toast.makeText(MainActivity.this, "第"+position +"個"+ bannerModel.toString(), Toast.LENGTH_SHORT).show();
}
});複製程式碼