android?viewpager實(shí)現(xiàn)輪播效果
本文是基于ViewPager實(shí)現(xiàn)的無限自動(dòng)輪播banner,供大家參考,具體內(nèi)容如下

分為四步去實(shí)現(xiàn):
第一步是有限手動(dòng)輪播;
第二步是無限輪播;
第三步是自動(dòng)輪播;
第四步是指示器適配
第一步:有限手動(dòng)輪播實(shí)現(xiàn)
布局:
<androidx.viewpager.widget.ViewPager ? ? android:id="@+id/banner" ? ? android:layout_width="match_parent" ? ? android:layout_height="wrap_content" ? ? android:layout_marginStart="12dp" ? ? android:layout_marginEnd="12dp" />
adapter實(shí)現(xiàn):
public class BannerAdapter extends PagerAdapter {
? ??
? ? private List<String> bannerList;
?
? ? public BannerAdapter(List<String> bannerList) {
? ? ? ? this.bannerList = bannerList;
? ? }
?
? ? @Override
? ? public int getCount() {
? ? ? ? return bannerList.size();
? ? }
?
? ? @Override
? ? public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
? ? ? ? return view == object;
? ? }
?
? ? @NonNull
? ? @Override
? ? public Object instantiateItem(@NonNull ViewGroup container, int position) {
? ? ? ? ImageView bannerImageView = new ImageView(container.getContext());
? ? ? ? ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
? ? ? ? bannerImageView.setLayoutParams(lp);
? ? ? ? bannerImageView.setScaleType(ImageView.ScaleType.FIT_XY);
? ? ? ? Glide.with(container.getContext()).load(bannerList.get(position)).into(bannerImageView);
?
? ? ? ? container.addView(bannerImageView);
? ? ? ? return bannerImageView;
? ? }
?
? ? @Override
? ? public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
? ? ? ? container.removeView((View) object);
? ? }
}Activity中:
// scrollview中viewpager一定要設(shè)置高度,此處根據(jù)圖片的寬高比來設(shè)定高度 ? int bannerWidth = (Utils.getScreenWidth(getContext()) - Utils.dip2pixel(getContext(), 24)); LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) bannerView.getLayoutParams(); lp.width = LinearLayout.LayoutParams.MATCH_PARENT; lp.height = (int) (bannerWidth * 90f / 345); bannerView.setLayoutParams(lp); ? bannerView.setAdapter(new BannerAdapter(getUrlList()));
注意:ScrollView包裹ViewPager時(shí),ViewPager的高度一定要有確定值,否則內(nèi)容無法加載出來,可以在xml中指定,也可以代碼設(shè)定,但一定要有確定值。
第二步:無限輪播
無限輪播只需要在有限輪播的基礎(chǔ)上,做以下兩個(gè)改動(dòng)點(diǎn),修改getCount返回值且在加載數(shù)據(jù)時(shí)獲取正確的數(shù)據(jù)源即可
public class BannerAdapter extends PagerAdapter {
?
? ? private List<String> bannerList;
?
? ? public BannerAdapter(List<String> bannerList) {
? ? ? ? this.bannerList = bannerList;
? ? }
?
? ? @Override
? ? public int getCount() {
// ? ? ? ?return bannerList.size(); ?// before
? ? ? ? return Integer.MAX_VALUE; ? // now
? ? }
?
? ? @Override
? ? public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
? ? ? ? return view == object;
? ? }
?
? ? @NonNull
? ? @Override
? ? public Object instantiateItem(@NonNull ViewGroup container, int position) {
? ? ? ? ImageView bannerImageView = new ImageView(container.getContext());
? ? ? ? int realPosition = position % bannerList.size(); // 獲取要加載數(shù)據(jù)的真實(shí)位置
? ? ? ? ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
? ? ? ? bannerImageView.setLayoutParams(lp);
? ? ? ? bannerImageView.setScaleType(ImageView.ScaleType.FIT_XY);
// ? ? ? ?Glide.with(container.getContext()).load(bannerList.get(position)).into(bannerImageView); // before
? ? ? ? Glide.with(container.getContext()).load(bannerList.get(realPosition)).into(bannerImageView); // now
?
? ? ? ? container.addView(bannerImageView);
? ? ? ? return bannerImageView;
? ? }
?
? ? @Override
? ? public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
? ? ? ? container.removeView((View) object);
? ? }
}修改完發(fā)現(xiàn)banner只能向右無限輪播,第一次左滑滑不動(dòng),這個(gè)時(shí)候我們強(qiáng)制設(shè)置viewpager位置在中間就可以解決這個(gè)問題了
bannerView.setAdapter(new BannerAdapter(getUrlList())); bannerView.setCurrentItem(getUrlList().size() * 5);
第三步:自動(dòng)輪播
handler每隔輪播間隔發(fā)送消息,設(shè)置viewpager為下一個(gè)位置
private Runnable bannerRunnable = new Runnable() {
? ? ? ? @Override
? ? ? ? public void run() {
? ? ? ? ? ? bannerView.setCurrentItem(bannerView.getCurrentItem() + 1);
? ? ? ? ? ? mHandler.postDelayed(bannerRunnable, 3000);
? ? ? ? }
? ? };
?
bannerView.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
?
? ? ? ? ? ? }
?
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onPageSelected(int position) {
? ? ? ? ? ? ? ? // 手滑動(dòng)到某一位置,重新開始計(jì)時(shí)
? ? ? ? ? ? ? ? start();
? ? ? ? ? ? }
?
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onPageScrollStateChanged(int state) {
?
? ? ? ? ? ? }
? ? ? ? });
?
private void start() {
? ? ? ? mHandler.removeCallbacksAndMessages(null);
? ? ? ? mHandler.postDelayed(bannerRunnable, 3000);
? ? }第四步:添加指示器
指示器樣式及表現(xiàn)可以自己去根據(jù)需求實(shí)現(xiàn),以相對(duì)簡(jiǎn)單和常見的小圓圈指示器為例,添加和banner數(shù)量相同的小圓圈,小圓圈設(shè)置selector,在選中時(shí)為黑色選中樣式,在非選中時(shí)為灰色默認(rèn)樣式,根據(jù)當(dāng)前選中的banner的實(shí)際position,設(shè)置指示器的selected屬性,從而展示不同的樣式
private void initIndicator() {
? ? ? ? for (int i = 0; i < getUrlList().size(); i++) {
? ? ? ? ? ? View view = new View(getActivity());
? ? ? ? ? ? LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(Utils.dip2pixel(getActivity(), 6), Utils.dip2pixel(getActivity(), 6));
? ? ? ? ? ? lp.rightMargin = Utils.dip2pixel(getActivity(), 8);
? ? ? ? ? ? view.setLayoutParams(lp);
? ? ? ? ? ? view.setBackgroundResource(R.drawable.selector_indicator_view);
? ? ? ? ? ? view.setSelected(i == 0);
? ? ? ? ? ? llIndicatorView.addView(view);
? ? ? ? }
? ? }
?
?
private void initBannerView() {
? ? ? ? bannerView.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
?
? ? ? ? ? ? }
?
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onPageSelected(int position) {
? ? ? ? ? ? ? ? // 手滑動(dòng)到某一位置,重新開始計(jì)時(shí)
? ? ? ? ? ? ? ? realPosition = 0;
? ? ? ? ? ? ? ? realPosition = position % getUrlList().size();
? ? ? ? ? ? ? ? // 根據(jù)當(dāng)前滑動(dòng)到的banner設(shè)置指示器的狀態(tài)
? ? ? ? ? ? ? ? for (int i = 0; i < llIndicatorView.getChildCount(); i++) {
? ? ? ? ? ? ? ? ? ? llIndicatorView.getChildAt(i).setSelected(i == realPosition);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? start();
? ? ? ? ? ? }
?
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onPageScrollStateChanged(int state) {
?
? ? ? ? ? ? }
? ? ? ? });
? ? }附:Utils文件
public class Utils {
? ? public static void setFullScreen(Activity activity) {
? ? ? ? if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
? ? ? ? ? ? ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
? ? ? ? ? ? decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
? ? ? ? ? ? activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
? ? ? ? }
? ? }
?
? ? public static int dip2pixel(Context context, float n) {
? ? ? ? int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, n, context.getResources().getDisplayMetrics());
? ? ? ? return value;
? ? }
?
? ? /**
? ? ?* 獲取屏幕寬度
? ? ?* @param context
? ? ?* @return 屏幕寬度
? ? ?*/
? ? public static int getScreenWidth(Context context) {
? ? ? ? WindowManager wm = (WindowManager) context
? ? ? ? ? ? ? ? .getSystemService(Context.WINDOW_SERVICE);
? ? ? ? DisplayMetrics outMetrics = new DisplayMetrics();
? ? ? ? wm.getDefaultDisplay().getMetrics(outMetrics);
? ? ? ? return outMetrics.widthPixels;
? ? }
}以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)自動(dòng)變換大小的ViewPager
- Android使用ViewPager實(shí)現(xiàn)翻頁效果
- Android自定義View實(shí)現(xiàn)遙控器按鈕
- Android單選多選按鈕的使用方法
- Android實(shí)現(xiàn)單選按鈕
- Android 中使用RadioGroup和Fragment實(shí)現(xiàn)底部導(dǎo)航欄的功能
- Android基礎(chǔ)控件RadioGroup使用方法詳解
- Android RadioGroup多行顯示效果 解決單選問題
- Kotlin RadioGroup與ViewPager實(shí)現(xiàn)底層分頁按鈕方法
相關(guān)文章
Android中實(shí)現(xiàn)EditText圓角的方法
Android中實(shí)現(xiàn)EditText圓角的方法,需要的朋友可以參考一下2013-03-03
Android studio 下JNI編程實(shí)例并生成so庫的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android studio 下JNI編程實(shí)例并生成so庫,需要的朋友可以參考下2017-09-09
Flutter綜合部分頁面詳情頁實(shí)現(xiàn)過程示例
這篇文章主要為大家介紹了Flutter綜合部分頁面詳情頁實(shí)現(xiàn)過程步驟示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
Android TextView Marquee的應(yīng)用實(shí)例詳解
這篇文章主要介紹了Android TextView Marquee的應(yīng)用實(shí)例詳解的相關(guān)資料,這里說明使用方法及簡(jiǎn)單實(shí)例和注意實(shí)現(xiàn),需要的朋友可以參考下2017-08-08
Android開發(fā)人臉識(shí)別統(tǒng)計(jì)人臉數(shù)
這篇文章主要介紹了Android開發(fā)人臉識(shí)別統(tǒng)計(jì)人臉數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10

