您好,登錄后才能下訂單哦!
這篇文章主要介紹“Android如何封裝Banner控件”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Android如何封裝Banner控件”文章能幫助大家解決問題。
如上圖所示效果我們應(yīng)該都不陌生,這是一個(gè)簡(jiǎn)單的banner輪播效果,網(wǎng)上也有很多的開源項(xiàng)目,但有時(shí)候可能我們僅僅只需要一些簡(jiǎn)單的效果,并不需要其他過多的東西。這里簡(jiǎn)單的對(duì)banner進(jìn)行一下封裝,隨時(shí)調(diào)用和添加一些新的功能。
/** * Created by xiaolong on 2018/1/23. */ public class BannerView extends FrameLayout implements ViewPager.OnPageChangeListener{ private ViewPager viewPager; //網(wǎng)絡(luò)圖片地址 private List<String> imageUrls; //指示點(diǎn)的容器 private LinearLayout pointLayout; //當(dāng)前頁面位置 private int currentItem; //自動(dòng)播放時(shí)間 private int autoPlayTime = 2000; //是否自動(dòng)播放 private boolean isAutoPlay; //是否是一張圖片 private boolean isOneImage; //監(jiān)聽事件 private OnBannerItemClick onBannerItemClick; //這里利用handler實(shí)現(xiàn)循環(huán)播放 private Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { currentItem++; currentItem = currentItem % (imageUrls.size() + 2); viewPager.setCurrentItem(currentItem); handler.sendEmptyMessageDelayed(0,autoPlayTime); return false; } }); public BannerView(@NonNull Context context) { this(context,null); } public BannerView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public BannerView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs,R.styleable.BannerView,0,0); //默認(rèn)自動(dòng)播放 isAutoPlay = typedArray.getBoolean(R.styleable.BannerView_isAutoPlay,true); typedArray.recycle(); viewPager = new ViewPager(getContext()); pointLayout = new LinearLayout(getContext()); //添加監(jiān)聽事件 viewPager.addOnPageChangeListener(this); //利用布局屬性將指示器容器放置底部并居中 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; params.bottomMargin = 60; addView(viewPager); addView(pointLayout,params); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { currentItem = position; if (!isOneImage) { switchToPoint(toRealPosition(position)); } } @Override public void onPageScrollStateChanged(int state) { //根據(jù)滑動(dòng)松開后的狀態(tài),去判斷當(dāng)前的current 并跳轉(zhuǎn)到指定current if (state == ViewPager.SCROLL_STATE_IDLE) { int current = viewPager.getCurrentItem(); int lastReal = viewPager.getAdapter().getCount() - 2; if (current == 0) { viewPager.setCurrentItem(lastReal, false); } else if (current == lastReal + 1) { viewPager.setCurrentItem(1, false); } } } //配置viewpager適配器 private class BannerAdapter extends PagerAdapter { @Override public int getCount() { return imageUrls.size() + 2; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, final int position) { ImageView imageView = new ImageView(getContext()); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (onBannerItemClick != null) { onBannerItemClick.onItemClick(toRealPosition(position)); } } }); imageView.setScaleType(ImageView.ScaleType.FIT_XY); Glide.with(getContext()).load(imageUrls.get(toRealPosition(position))).into(imageView); container.addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } //添加網(wǎng)絡(luò)圖片 public void setImageUrls(List<String> imageUrls) { this.imageUrls = imageUrls; if (imageUrls.size() <= 1) { isOneImage = true; }else { isOneImage = false; } initViewPager(); } //加載viewPager private void initViewPager() { if (!isOneImage) { //添加指示點(diǎn) addPoints(); } BannerAdapter adapter = new BannerAdapter(); viewPager.setAdapter(adapter); //默認(rèn)當(dāng)前圖片 viewPager.setCurrentItem(1); //判斷是否自動(dòng)播放和是否是一張圖片的情況 if (isAutoPlay && !isOneImage) { handler.sendEmptyMessageDelayed(0,autoPlayTime); } } //添加指示點(diǎn) private void addPoints() { LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.setMargins(10, 10, 10, 10); ImageView imageView; int length = imageUrls.size(); for (int i = 0; i < length; i++) { imageView = new ImageView(getContext()); imageView.setLayoutParams(lp); imageView.setImageResource(R.drawable.select_point_bg); pointLayout.addView(imageView); } switchToPoint(0); } //切換指示器 private void switchToPoint(int currentPoint) { for (int i = 0; i < pointLayout.getChildCount(); i++) { pointLayout.getChildAt(i).setEnabled(false); } pointLayout.getChildAt(currentPoint).setEnabled(true); } //返回真實(shí)的位置 private int toRealPosition(int position) { int realPosition; if (imageUrls.size() > 0) { realPosition = (position - 1) % imageUrls.size(); if (realPosition < 0) realPosition += imageUrls.size(); }else{ realPosition = 0; } return realPosition; } public void setAutoPlay(boolean autoPlay) { isAutoPlay = autoPlay; } public void setOnBannerItemClick(OnBannerItemClick onBannerItemClick) { this.onBannerItemClick = onBannerItemClick; } //添加監(jiān)聽事件回調(diào) public interface OnBannerItemClick{ void onItemClick(int position); } }
//設(shè)置是否自動(dòng)播放 bannerView.setAutoPlay(true); //添加網(wǎng)絡(luò)圖片 bannerView.setImageUrls(data); //banner的點(diǎn)擊事件 bannerView.setOnBannerItemClick(new BannerView.OnBannerItemClick() { @Override public void onItemClick(int position) { Toast.makeText(MainActivity.this,"圖片" + position,Toast.LENGTH_LONG).show(); } });
這里我只考慮了使用網(wǎng)絡(luò)圖片進(jìn)行展示,使用本地圖片原理是一樣的,在里面多加個(gè)方法即可。此效果代碼不是很復(fù)雜,通俗易懂。唯一值得一說的是我在實(shí)現(xiàn)viewpager
無限滑動(dòng)時(shí)采用的是return imageUrls.size() + 2
的方法。這里我們添加兩條數(shù)據(jù)分別為第一條和最后一條。第一條代表著最后一張圖片而最后一條則代表著第一張圖片。
通過此圖我們應(yīng)該不難發(fā)現(xiàn),當(dāng)我們滑動(dòng)到第二個(gè)0的時(shí)候則跳轉(zhuǎn)到第一個(gè)0,滑動(dòng)到第一個(gè)2的時(shí)候則跳轉(zhuǎn)到第二個(gè)2。這里0代表第一張圖片,2代表第二張圖片。這樣就可以實(shí)現(xiàn)無限滑動(dòng)的效果了,可能有些人會(huì)覺得這樣做有些復(fù)雜還要判斷真實(shí)的位置不如直接將getConut()
返回一個(gè)最大值然后取其中間值即可。但這樣做其實(shí)代碼性能并不是很高。
關(guān)于“Android如何封裝Banner控件”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。