Android實(shí)現(xiàn)BannerLayout圖文輪播功能
本文實(shí)例為大家分享了Android實(shí)現(xiàn)BannerLayout圖文輪播功能的具體代碼,供大家參考,具體內(nèi)容如下
實(shí)現(xiàn)效果圖:

(1)在biuld.gradle文件加入
compile 'com.ydevelop:bannerlayout:1.0.4'
(2)創(chuàng)建BannerLayout文件
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Interpolator;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class BannerLayout extends RelativeLayout {
private ViewPager mViewPager; // 輪播容器
// 指示器(圓點(diǎn))容器
private LinearLayout indicatorContainer;
private Drawable unSelectedDrawable;
private Drawable selectedDrawable;
private int WHAT_AUTO_PLAY = 1000;
private boolean isAutoPlay = true; // 自動輪播
private int itemCount;
private int selectedIndicatorColor = 0xffff0000;
private int unSelectedIndicatorColor = 0x88888888;
private int titleBGColor = 0X33000000;
private int titleColor = 0Xffffffff;
private Shape indicatorShape = Shape.oval;
private int selectedIndicatorHeight = 20;
private int selectedIndecatorWidth = 20;
private int unSelectedIndicatorHeight = 20;
private int unSelectedIndecatorWidth = 20;
private int autoPlayDuration = 4000;
private int scrollDuration = 900;
// 指示器中點(diǎn)和點(diǎn)之間的距離
private int indicatorSpace = 10;
// 指示器整體的設(shè)置
private int indicatorMargin = 20;
private static final int titlePadding = 20;
private int defaultImage;
private enum Shape {
// 矩形 或 圓形的指示器
rect, oval
}
private OnBannerItemClickListener mOnBannerItemClickListener;
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == WHAT_AUTO_PLAY) {
if (mViewPager != null) {
mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1, true);
mHandler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, autoPlayDuration);
}
}
return false;
}
});
public BannerLayout(Context context) {
super(context);
init(null, 0);
}
public BannerLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public BannerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr);
}
private void init(AttributeSet attrs, int defStyleAttr) {
TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.BannerLayoutStyle, defStyleAttr, 0);
selectedIndicatorColor = array.getColor(R.styleable.BannerLayoutStyle_selectedIndicatorColor, selectedIndicatorColor);
unSelectedIndicatorColor = array.getColor(R.styleable.BannerLayoutStyle_unSelectedIndicatorColor, unSelectedIndicatorColor);
titleBGColor = array.getColor(R.styleable.BannerLayoutStyle_titleBGColor, titleBGColor);
titleColor = array.getColor(R.styleable.BannerLayoutStyle_titleColor, titleColor);
int shape = array.getInt(R.styleable.BannerLayoutStyle_indicatorShape, Shape.oval.ordinal());
for (Shape shape1 : Shape.values()) {
if (shape1.ordinal() == shape) {
indicatorShape = shape1;
break;
}
}
selectedIndecatorWidth = (int) array.getDimension(R.styleable.BannerLayoutStyle_selectedIndicatorWidth, selectedIndecatorWidth);
selectedIndicatorHeight = (int) array.getDimension(R.styleable.BannerLayoutStyle_selectedIndicatorHeight, selectedIndicatorHeight);
unSelectedIndecatorWidth = (int) array.getDimension(R.styleable.BannerLayoutStyle_unSelectedIndicatorWidth, unSelectedIndecatorWidth);
unSelectedIndicatorHeight = (int) array.getDimension(R.styleable.BannerLayoutStyle_unSelectedIndicatorHeight, unSelectedIndicatorHeight);
indicatorSpace = (int) array.getDimension(R.styleable.BannerLayoutStyle_indicatorSpace, indicatorSpace);
indicatorMargin = (int) array.getDimension(R.styleable.BannerLayoutStyle_indicatorMargin, indicatorMargin);
autoPlayDuration = array.getInt(R.styleable.BannerLayoutStyle_autoPlayDuration, autoPlayDuration);
scrollDuration = array.getInt(R.styleable.BannerLayoutStyle_scrollDuration, scrollDuration);
isAutoPlay = array.getBoolean(R.styleable.BannerLayoutStyle_isAutoPlay, isAutoPlay);
defaultImage = array.getResourceId(R.styleable.BannerLayoutStyle_defaultImage, defaultImage);
array.recycle();
LayerDrawable unSelectedLayerDrawable;
LayerDrawable selectedLayerDrawable;
GradientDrawable unSelectedGradientDrawable = new GradientDrawable();
GradientDrawable selectedGradientDtawbale = new GradientDrawable();
switch (indicatorShape) {
case rect:
unSelectedGradientDrawable.setShape(GradientDrawable.RECTANGLE);
selectedGradientDtawbale.setShape(GradientDrawable.RECTANGLE);
break;
case oval:
unSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
selectedGradientDtawbale.setShape(GradientDrawable.OVAL);
break;
}
unSelectedGradientDrawable.setColor(unSelectedIndicatorColor);
unSelectedGradientDrawable.setSize(unSelectedIndecatorWidth, unSelectedIndicatorHeight);
unSelectedLayerDrawable = new LayerDrawable(new Drawable[]{unSelectedGradientDrawable});
unSelectedDrawable = unSelectedLayerDrawable;
selectedGradientDtawbale.setColor(selectedIndicatorColor);
selectedGradientDtawbale.setSize(selectedIndecatorWidth, selectedIndicatorHeight);
selectedLayerDrawable = new LayerDrawable(new Drawable[]{selectedGradientDtawbale});
selectedDrawable = selectedLayerDrawable;
}
/**
* 添加本地圖片
*
* @param viewRes 圖片id集合
* @param titles 標(biāo)題集合,可空
*/
public void setViewRes(List<Integer> viewRes, List<String> titles) {
List<View> views = new ArrayList<>();
itemCount = viewRes.size();
if (titles != null && titles.size() != viewRes.size()) {
throw new IllegalStateException("views.size() != titles.size()");
}
// 把數(shù)量拼湊到三個以上
if (itemCount < 1) {
throw new IllegalStateException("item count not equal zero");
} else if (itemCount < 2) {
views.add(getFrameLayoutView(viewRes.get(0), titles != null ? titles.get(0) : null, 0));
views.add(getFrameLayoutView(viewRes.get(0), titles != null ? titles.get(0) : null, 0));
views.add(getFrameLayoutView(viewRes.get(0), titles != null ? titles.get(0) : null, 0));
} else if (itemCount < 3) {
views.add(getFrameLayoutView(viewRes.get(0), titles != null ? titles.get(0) : null, 0));
views.add(getFrameLayoutView(viewRes.get(1), titles != null ? titles.get(1) : null, 1));
views.add(getFrameLayoutView(viewRes.get(0), titles != null ? titles.get(0) : null, 0));
views.add(getFrameLayoutView(viewRes.get(1), titles != null ? titles.get(1) : null, 1));
} else {
for (int i = 0; i < viewRes.size(); i++) {
views.add(getFrameLayoutView(viewRes.get(i), titles != null ? titles.get(i) : null, i));
}
}
setViews(views);
}
//添加網(wǎng)絡(luò)圖片路徑
public void setViewUrls(Context context,List<String> urls, List<String> titles) {
List<View> views = new ArrayList<>();
itemCount = urls.size();
Log.e("TAG",titles.size()+"---90---"+urls.size());
if (titles != null && titles.size() != itemCount) {
throw new IllegalStateException("views.size() != titles.size()");
}
//主要是解決當(dāng)item為小于3個的時候滑動有問題,這里將其拼湊成3個以上
if (itemCount < 1) {//當(dāng)item個數(shù)0
throw new IllegalStateException("item count not equal zero");
} else if (itemCount < 2) { //當(dāng)item個數(shù)為1
views.add(getFrameLayoutView(context,urls.get(0), titles != null ? titles.get(0) : null, 0));
views.add(getFrameLayoutView(context,urls.get(0), titles != null ? titles.get(0) : null, 0));
views.add(getFrameLayoutView(context,urls.get(0), titles != null ? titles.get(0) : null, 0));
} else if (itemCount < 3) {//當(dāng)item個數(shù)為2
views.add(getFrameLayoutView(context,urls.get(0), titles != null ? titles.get(0) : null, 0));
views.add(getFrameLayoutView(context,urls.get(1), titles != null ? titles.get(1) : null, 1));
views.add(getFrameLayoutView(context,urls.get(0), titles != null ? titles.get(0) : null, 0));
views.add(getFrameLayoutView(context,urls.get(1), titles != null ? titles.get(1) : null, 1));
} else {
for (int i = 0; i < urls.size(); i++) {
views.add(getFrameLayoutView(context,urls.get(i), titles != null ? titles.get(i) : null, i));
}
}
setViews(views);
}
private void setViews(final List<View> views) {
mViewPager = new ViewPager(getContext());
addView(mViewPager);
setSliderTransformDuration(scrollDuration);
//初始化indicatorContainer
indicatorContainer = new LinearLayout(getContext());
indicatorContainer.setGravity(Gravity.CENTER_VERTICAL);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// 設(shè)置 指示點(diǎn)的位置 ALIGN_PARENT_RIGHT表示居右 CENTER_HORIZONTAL表示居中
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
//設(shè)置margin
params.setMargins(indicatorMargin, indicatorMargin, indicatorMargin, indicatorMargin);
//添加指示器容器布局到SliderLayout
addView(indicatorContainer, params);
//初始化指示器,并添加到指示器容器布局
for (int i = 0; i < itemCount; i++) {
ImageView indicator = new ImageView(getContext());
indicator.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
indicator.setPadding(indicatorSpace, indicatorSpace, indicatorSpace, indicatorSpace);
indicator.setImageDrawable(unSelectedDrawable);
indicatorContainer.addView(indicator);
}
LoopPagerAdapter pagerAdapter = new LoopPagerAdapter(views);
mViewPager.setAdapter(pagerAdapter);
//設(shè)置當(dāng)前item到Integer.MAX_VALUE中間的一個值,看起來像無論是往前滑還是往后滑都是ok的
//如果不設(shè)置,用戶往左邊滑動的時候已經(jīng)劃不動了
int targetItemPosition = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % itemCount;
mViewPager.setCurrentItem(targetItemPosition);
switchIndicator(targetItemPosition % itemCount);
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
switchIndicator(position % itemCount);
}
});
startAutoPlay();
}
/**
* 開始自動輪播
*/
public void startAutoPlay() {
stopAutoPlay(); // 避免重復(fù)消息
if (isAutoPlay) {
mHandler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, autoPlayDuration);
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if (visibility == VISIBLE) {
startAutoPlay();
} else {
stopAutoPlay();
}
}
/**
* 停止自動輪播
*/
public void stopAutoPlay() {
if (isAutoPlay) {
mHandler.removeMessages(WHAT_AUTO_PLAY);
}
}
private void setSliderTransformDuration(int scrollDuration) {
try {
Field mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
FixedSpeedScroller fixedSpeedScroller = new FixedSpeedScroller(mViewPager.getContext(), null, scrollDuration);
mScroller.set(mViewPager, fixedSpeedScroller);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
stopAutoPlay();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
startAutoPlay();
break;
}
return super.dispatchTouchEvent(ev);
}
/**
* 切換指示器狀態(tài)
*
* @param currentPosition 當(dāng)前位置
*/
private void switchIndicator(int currentPosition) {
for (int i = 0; i < indicatorContainer.getChildCount(); i++) {
((ImageView) indicatorContainer.getChildAt(i)).setImageDrawable(i == currentPosition ? selectedDrawable : unSelectedDrawable);
}
}
public void setOnBannerItemClickListener(OnBannerItemClickListener onBannerItemClickListener) {
this.mOnBannerItemClickListener = onBannerItemClickListener;
}
@NonNull
private FrameLayout getFrameLayoutView(Context context, String url, String title, final int position) {
FrameLayout frameLayout = new FrameLayout(getContext());
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.CENTER;
ImageView imageView = new ImageView(getContext());
frameLayout.addView(imageView);
frameLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnBannerItemClickListener != null) {
mOnBannerItemClickListener.onItemClick(position);
}
}
});
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
if (defaultImage != 0){
Glide.with(getContext()).load(url).placeholder(defaultImage).centerCrop().into(imageView);
}else {
Glide.with(getContext()).load(url).centerCrop().into(imageView);
}
if (!TextUtils.isEmpty(title)) {
TextView textView = new TextView(getContext());
textView.setText(title);
textView.setTextColor(titleColor);
textView.setPadding(titlePadding, titlePadding, titlePadding, titlePadding);
textView.setBackgroundColor(titleBGColor);
textView.getPaint().setFakeBoldText(true);
layoutParams.gravity = Gravity.BOTTOM;
frameLayout.addView(textView, layoutParams);
}
return frameLayout;
}
@NonNull
private FrameLayout getFrameLayoutView(Integer res, String title, final int position) {
FrameLayout frameLayout = new FrameLayout(getContext());
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.CENTER;
ImageView imageView = new ImageView(getContext());
frameLayout.addView(imageView);
frameLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnBannerItemClickListener != null) {
mOnBannerItemClickListener.onItemClick(position);
}
}
});
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
Glide.with(getContext()).load(res).centerCrop().into(imageView);
if (!TextUtils.isEmpty(title)) {
TextView textView = new TextView(getContext());
textView.setText(title);
textView.setTextColor(titleColor);
textView.setPadding(titlePadding, titlePadding, titlePadding, titlePadding);
textView.setBackgroundColor(titleBGColor);
textView.getPaint().setFakeBoldText(true);
layoutParams.gravity = Gravity.BOTTOM;
frameLayout.addView(textView, layoutParams);
}
return frameLayout;
}
public interface OnBannerItemClickListener {
void onItemClick(int position);
}
public class LoopPagerAdapter extends PagerAdapter {
private List<View> views;
public LoopPagerAdapter(List<View> views) {
this.views = views;
}
@Override
public int getCount() {
//Integer.MAX_VALUE = 2147483647
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (views.size() > 0) {
//position % view.size()是指虛擬的position會在[0,view.size())之間循環(huán)
View view = views.get(position % views.size());
if (container.equals(view.getParent())) {
container.removeView(view);
}
container.addView(view);
return view;
}
return null;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
}
public class FixedSpeedScroller extends Scroller {
private int mDuration = 1000;
public FixedSpeedScroller(Context context) {
super(context);
}
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, (android.view.animation.Interpolator) interpolator);
}
public FixedSpeedScroller(Context context, Interpolator interpolator, int duration) {
this(context, interpolator);
mDuration = duration;
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
}
}
(3)MainAvtivity.java文件
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lenovo on 2018/4/23.
*/
public class MainActivity extends Activity {
private MyListView lv_zyb;
private ImageView iv_zybfh;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_zybfh=(ImageView) findViewById(R.id.iv_zybfh);
BannerLayout bannerLayout = (BannerLayout) findViewById(R.id.bannerzhuangyuanbang);
List<String> urls = new ArrayList<>();
urls.add("http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1404/02/c5/32731218_32731218_1396429876186.jpg");
urls.add("http://pic2.16pic.com/00/11/65/16pic_1165030_b.jpg");
urls.add("http://upload.17u.net/uploadpicbase/image/201708201147537103.jpg");
urls.add("http://img2.gzgov.gov.cn/gzsrmzf/dcgz/lyzx/rmjd/201709/W020170926622407643781.jpg");
urls.add("http://photocdn.sohu.com/20150324/Img410244363.jpg");
urls.add("http://pic4.40017.cn/scenery/destination/2017/01/10/11/SiTllI.jpg");
List<String> titleas = new ArrayList<>();
titleas.add("標(biāo)題一");
titleas.add("標(biāo)題二");
titleas.add("標(biāo)題三");
titleas.add("標(biāo)題四");
titleas.add("標(biāo)題五");
titleas.add("標(biāo)題六");
if (bannerLayout != null) {
bannerLayout.setViewUrls(this ,urls, titleas);
bannerLayout.setOnBannerItemClickListener(new BannerLayout.OnBannerItemClickListener() {
@Override
public void onItemClick(int position) {
Toast.makeText(ZhuangyuanbangActivity.this, "position:" + position, Toast.LENGTH_SHORT).show();
}
});
}
}
}
(4)activity_main.xml文件,必須加紅色這一句,否則app開頭的會報錯。還有紅色的是包名,記得修改為自己項目的包名。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <applwj.eduation.com.topeduation.BannerLayout android:id="@+id/bannerzhuangyuanbang" android:layout_width="match_parent" android:layout_height="210dp" app:scrollDuration="1000" app:autoPlayDuration="3000" app:unSelectedIndicatorHeight="10dp" app:unSelectedIndicatorWidth="10dp" app:selectedIndicatorHeight="10dp" app:selectedIndicatorWidth="10dp" app:unSelectedIndicatorColor="#99ffffff" app:selectedIndicatorColor="#000000" app:isAutoPlay="true" /> </LinearLayout>
demo下載:Android實(shí)現(xiàn)圖文輪播功能
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)圖片輪播效果的兩種方法
- Android實(shí)現(xiàn)圖片輪播效果
- Android實(shí)現(xiàn)Banner界面廣告圖片循環(huán)輪播(包括實(shí)現(xiàn)手動滑動循環(huán))
- Android 使用ViewPager自動滾動循環(huán)輪播效果
- Android實(shí)現(xiàn)圖片自動輪播并且支持手勢左右無限滑動
- Android使用ViewPager加載圖片和輪播視頻
- Android實(shí)現(xiàn)圖片文字輪播特效
- Android ViewPager實(shí)現(xiàn)圖片輪播效果
- Android實(shí)現(xiàn)廣告圖片輪播效果
- Android自動播放Banner圖片輪播效果
相關(guān)文章
簡單實(shí)現(xiàn)Android鬧鐘程序 附源碼
這篇文章主要幫助大家簡單實(shí)現(xiàn)Android鬧鐘程序,附源碼下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-07-07
Flutter之Timer實(shí)現(xiàn)短信驗證碼獲取60s倒計時功能的代碼
這篇文章主要介紹了Flutter之Timer實(shí)現(xiàn)短信驗證碼獲取60s倒計時功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
Android 實(shí)現(xiàn)電話來去自動錄音的功能
本文主要介紹Android 電話自動錄音功能的開發(fā),這里提供實(shí)現(xiàn)代碼和實(shí)現(xiàn)效果圖,有需要的小伙伴可以參考下2016-08-08
Android library native調(diào)試代碼遇到的問題解決
這篇文章主要介紹了Android library native 代碼不能調(diào)試解決方法匯總,android native開發(fā)會碰到native代碼無法調(diào)試問題,而app主工程中的native代碼是可以調(diào)試的2023-04-04
android實(shí)現(xiàn)一個圖片驗證碼倒計時功能
本文通過實(shí)例代碼給大家介紹了android實(shí)現(xiàn)一個圖片驗證碼倒計時功能,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2017-11-11
Android學(xué)習(xí)教程之下拉刷新實(shí)現(xiàn)代碼(11)
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)教程之下拉刷新實(shí)現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11
Android Studio實(shí)現(xiàn)帶邊框的圓形頭像
這篇文章主要為大家詳細(xì)介紹了Android Studio實(shí)現(xiàn)帶邊框的圓形頭像,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10

