Android轮播图
来源:互联网 发布:linux c 调用sh脚本 编辑:程序博客网 时间:2024/06/14 09:44
漏洞百出
轮播图是 Android 常用功能之一,效果大概是这样的:
之前我封装写了一个,基本达到了要求,是继承了 Fragment(当时脑袋肯定锈掉了),里面 Viewpager add Fragment,这次项目多处有轮播图,发现之前封装的不够用,简直漏洞百出:
1、比如底部 point 的位置,之前固定在中间,现在可能要放在右下角,point 最好也能动态改图片;
2、现在项目跟微信一样,底部 tab 切换,中间是 Fragment 替换,发现轮播图有问题,Fragment A 循环的 point 的 positoin 居然影响到了 Fragment B,照理,这是两个 BannerFragment,不会影响的啊,报以下错误:
1
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged!
经过排查,找到了原因,因为 Viewpager add Fragment 我全部放在一个类,因此:
1
public static List<Object> bannerList = new ArrayList<>();
这里 static 坏事了,之前一个 banner 没有暴露出来。
3、继承了 Fragment,引用比较麻烦,Fragment 有两者引用方法,xml 和代码,两者方式 addData 却报错;
4、banner 没有写点击回调。
再次封装
综合以上问题,我进行了优化,继承 LinearLayout,当一个控件来引用,省去不必要的麻烦,底部 point 的位置可以设置:
1
pointLayout.setGravity(bannerPointGravity);
另外自定义了属性,动态设置 point 大小和图片,轮播图循环时间,也能代码设置,完整代码示例:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
/*** Created by WuXiaolong on 2017/8/24.* 个人博客:http://wuxiaolong.me*/public class BannerLayout extends LinearLayout {private ViewPager viewPager;private LinearLayout pointLayout;private ScheduledExecutorService scheduler;private int mPosition = 0;private int mBannerCount = 1;private Context context;private Activity activity;private int bannerPointSize;private int bannerPointGravity;private int bannerPointDrawableSelected, bannerPointDrawableUnselected;private int bannerDelaySecond;public BannerLayout(Context context) {this(context, null);}public BannerLayout(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public BannerLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initView(context, attrs);}private void initView(Context context, AttributeSet attrs) {this.context = context;activity = (Activity) context;TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BannerLayout);bannerPointSize = typedArray.getDimensionPixelSize(R.styleable.BannerLayout_bannerPointSize, 10);bannerPointGravity = typedArray.getInt(R.styleable.BannerLayout_bannerPointGravity, Gravity.CENTER);bannerDelaySecond = typedArray.getInt(R.styleable.BannerLayout_bannerDelaySecond, 5);bannerPointDrawableSelected = typedArray.getResourceId(R.styleable.BannerLayout_bannerPointDrawableSelected, R.mipmap.point01);bannerPointDrawableUnselected = typedArray.getResourceId(R.styleable.BannerLayout_bannerPointDrawableUnselected, R.mipmap.point02);typedArray.recycle();View view = View.inflate(context, R.layout.banner_view_pager, null);addView(view);viewPager = (ViewPager) view.findViewById(R.id.viewPager);pointLayout = (LinearLayout) view.findViewById(R.id.pointLayout);pointLayout.setGravity(bannerPointGravity);viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}public void onPageSelected(int position) {addPointLayout(position);}public void onPageScrollStateChanged(int state) {}});}public void start(List<Object> bannerList) {bannerShutdown();mBannerCount = bannerList.size();BannerPagerAdapter bannerPagerAdapter = new BannerPagerAdapter(context, bannerList);viewPager.setAdapter(bannerPagerAdapter);addPointLayout(0);startScheduler();}private void addPointLayout(int position) {pointLayout.removeAllViews();for (int i = 0; i < mBannerCount; i++) {ImageView imageView = new ImageView(context);LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(bannerPointSize, bannerPointSize);layoutParams.setMargins(10, 0, 0, 0);imageView.setLayoutParams(layoutParams);if (position == i) {imageView.setImageResource(bannerPointDrawableSelected);} else {imageView.setImageResource(bannerPointDrawableUnselected);}pointLayout.addView(imageView);}}private void startScheduler() {scheduler = Executors.newSingleThreadScheduledExecutor();scheduler.scheduleAtFixedRate(new Runnable() {public void run() {mPosition = viewPager.getCurrentItem();if (mPosition < mBannerCount - 1) {mPosition++;} else {mPosition = 0;}activity.runOnUiThread(new Runnable() {public void run() {viewPager.setCurrentItem(mPosition);}});}}, 1, bannerDelaySecond, TimeUnit.SECONDS);}public void bannerShutdown() {if (scheduler != null)scheduler.shutdown();}private class BannerPagerAdapter extends PagerAdapter {private List<Object> bannerList = new ArrayList<>();private Context context;BannerPagerAdapter(Context context, List<Object> bannerList) {this.context = context;this.bannerList.clear();this.bannerList.addAll(bannerList);}public int getCount() {return bannerList.size();}public boolean isViewFromObject(View view, Object object) {return view == object;}public Object instantiateItem(ViewGroup container, final int position) {ImageView imageView = new ImageView(context);imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);Object object = bannerList.get(position);//这里我封装了 Glide 4.0 的工具类,用于显示图片ImageLoaderUtil.load(context, object, imageView);container.addView(imageView);return imageView;}public void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View) object);}}public int dp2px(float var0) {float var1 = context.getResources().getDisplayMetrics().density;return (int) (var0 * var1 + 0.5F);}public void setBannerPointSize(int bannerPointSize) {this.bannerPointSize = dp2px(bannerPointSize);}public void setBannerPointGravity(int bannerPointGravity) {this.bannerPointGravity = bannerPointGravity;pointLayout.setGravity(bannerPointGravity);}public void setBannerPointDrawableSelected(int bannerPointDrawableSelected) {this.bannerPointDrawableSelected = bannerPointDrawableSelected;}public void setBannerPointDrawableUnselected(int bannerPointDrawableUnselected) {this.bannerPointDrawableUnselected = bannerPointDrawableUnselected;}public void setBannerDelaySecond(int bannerDelaySecond) {this.bannerDelaySecond = bannerDelaySecond;}}
其中自定义属性的attrs.xml:
1234567891011121314151617181920
<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="BannerLayout"><!--轮播图点的大小--><attr name="bannerPointSize" format="dimension" /><!--轮播图点的位置,分别有左中右--><attr name="bannerPointGravity" format="enum"><enum name="left" value="3" /><enum name="center" value="17" /><enum name="right" value="5" /></attr><!--轮播图点选中的图片--><attr name="bannerPointDrawableSelected" format="reference" /><!--轮播图点未选中的图片--><attr name="bannerPointDrawableUnselected" format="reference" /><!--轮播图循环时间,单位秒--><attr name="bannerDelaySecond" format="integer" /></declare-styleable></resources>
使用说明
xml
123456789
<com.wuxiaolong.bannersample.BannerLayoutandroid:id="@+id/bannerView"android:layout_width="match_parent"android:layout_height="198dp"app:bannerDelaySecond="3"app:bannerPointDrawableSelected="@drawable/gray_radius"app:bannerPointDrawableUnselected="@drawable/white_radius"app:bannerPointGravity="right"app:bannerPointSize="10dp" />
调用:
123456789101112131415161718192021222324252627
public class MainActivity extends AppCompatActivity {private BannerLayout bannerView;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bannerView = (BannerLayout) findViewById(R.id.bannerView);List<Object> bannerList = new ArrayList<>();bannerList.add(R.mipmap.horizontal_default);bannerList.add("http://pic1.win4000.com/wallpaper/5/598161750eddb.jpg");bannerList.add("http://pic1.win4000.com/wallpaper/4/597efb5b6aae8.jpg");bannerView.setBannerPointSize(10);bannerView.setBannerPointGravity(Gravity.CENTER);bannerView.setBannerPointDrawableSelected(R.drawable.gray_radius);bannerView.setBannerPointDrawableUnselected(R.mipmap.point01);bannerView.setBannerDelaySecond(5);//banner 设置方法完毕时最后调用 start 方法bannerView.start(bannerList);}protected void onStop() {super.onStop();bannerView.bannerShutdown();}}
最后
完整源码分享了我的知识星球(原名:小密圈),如果以上还满足不了你的需求,可以使用 GitHub上的库 banner,它丰富了 pointLayout,可能是文字,它还依赖了ViewPagerTransforms,因此 ViewPager 切换有各种炫酷效果,不过我觉得有些多余。
- android 轮播图
- android轮播图
- android 轮播图
- android 轮播图
- android 轮播图
- Android轮播图
- Android ViewPager 轮播图
- Android中的轮播图
- android实现轮播图
- Android自定义轮播图控件
- Android轮播图-----viewPager
- Android 轮播图---ViewFlipper
- Android 自定义一个轮播图
- Android 自动广告轮播图
- Android 广告轮播图
- Android-轮播图实现封装
- Android轮播图原理
- Android轮播图实现
- 二分图定理及常见模型
- Ubuntu 如何使用终端安装’add-apt-repository’?
- CodeForces 233 D.Table(dp+组合数学)
- 汇编语言--学习笔记--基础知识
- LaTex数学公式符号整理
- Android轮播图
- ubi文件系统制作指令分析
- 事件绑定
- java创建SFTP通道实现文件的上传与下载
- 原生IOS-Framework封装步骤
- 关系运算符==,===和!=,!==的区别
- 简单的弹出框DEMO
- mongodb基于java开发
- 175. Combine Two Tables