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

分為四步去實現(xiàn):
第一步是有限手動輪播;
第二步是無限輪播;
第三步是自動輪播;
第四步是指示器適配
第一步:有限手動輪播實現(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實現(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時,ViewPager的高度一定要有確定值,否則內(nèi)容無法加載出來,可以在xml中指定,也可以代碼設(shè)定,但一定要有確定值。
第二步:無限輪播
無限輪播只需要在有限輪播的基礎(chǔ)上,做以下兩個改動點,修改getCount返回值且在加載數(shù)據(jù)時獲取正確的數(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ù)的真實位置
? ? ? ? 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只能向右無限輪播,第一次左滑滑不動,這個時候我們強制設(shè)置viewpager位置在中間就可以解決這個問題了
bannerView.setAdapter(new BannerAdapter(getUrlList())); bannerView.setCurrentItem(getUrlList().size() * 5);
第三步:自動輪播
handler每隔輪播間隔發(fā)送消息,設(shè)置viewpager為下一個位置
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) {
? ? ? ? ? ? ? ? // 手滑動到某一位置,重新開始計時
? ? ? ? ? ? ? ? start();
? ? ? ? ? ? }
?
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onPageScrollStateChanged(int state) {
?
? ? ? ? ? ? }
? ? ? ? });
?
private void start() {
? ? ? ? mHandler.removeCallbacksAndMessages(null);
? ? ? ? mHandler.postDelayed(bannerRunnable, 3000);
? ? }第四步:添加指示器
指示器樣式及表現(xiàn)可以自己去根據(jù)需求實現(xiàn),以相對簡單和常見的小圓圈指示器為例,添加和banner數(shù)量相同的小圓圈,小圓圈設(shè)置selector,在選中時為黑色選中樣式,在非選中時為灰色默認樣式,根據(jù)當前選中的banner的實際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) {
? ? ? ? ? ? ? ? // 手滑動到某一位置,重新開始計時
? ? ? ? ? ? ? ? realPosition = 0;
? ? ? ? ? ? ? ? realPosition = position % getUrlList().size();
? ? ? ? ? ? ? ? // 根據(jù)當前滑動到的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;
? ? }
}以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android studio 下JNI編程實例并生成so庫的實現(xiàn)代碼
這篇文章主要介紹了Android studio 下JNI編程實例并生成so庫,需要的朋友可以參考下2017-09-09
Android TextView Marquee的應(yīng)用實例詳解
這篇文章主要介紹了Android TextView Marquee的應(yīng)用實例詳解的相關(guān)資料,這里說明使用方法及簡單實例和注意實現(xiàn),需要的朋友可以參考下2017-08-08
Android開發(fā)人臉識別統(tǒng)計人臉數(shù)
這篇文章主要介紹了Android開發(fā)人臉識別統(tǒng)計人臉數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-10-10

