本文共 8552 字,大约阅读时间需要 28 分钟。
轮播图是 Android 常用功能之一,效果大概是这样的:
之前我封装写了一个,基本达到了要求,是继承了 Fragment(当时脑袋肯定锈掉了),里面 Viewpager add Fragment,这次项目多处有轮播图,发现之前封装的不够用,简直漏洞百出:1、比如底部 point 的位置,之前固定在中间,现在可能要放在右下角,point 最好也能动态改图片;2、现在项目跟微信一样,底部 tab 切换,中间是 Fragment 替换,发现轮播图有问题,Fragment A 循环的 point 的 positoin 居然影响到了 Fragment B,照理,这是两个 BannerFragment,不会影响的啊,报以下错误:
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged!
经过排查,找到了原因,因为 Viewpager add Fragment 我全部放在一个类,因此:
public static List
这里 static 坏事了,之前一个 banner 没有暴露出来。3、继承了 Fragment,引用比较麻烦,Fragment 有两者引用方法,xml 和代码,两者方式 addData 却报错;4、banner 没有写点击回调。
综合以上问题,我进行了优化,继承 LinearLayout,当一个控件来引用,省去不必要的麻烦,底部 point 的位置可以设置:
pointLayout.setGravity(bannerPointGravity);
另外自定义了属性,动态设置 point 大小和图片,轮播图循环时间,也能代码设置,完整代码示例:
* 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() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { addPointLayout(position); } @Override public void onPageScrollStateChanged(int state) { } }); } public void start(List
其中自定义属性的attrs.xml:
xml
调用:
public class MainActivity extends AppCompatActivity { private BannerLayout bannerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bannerView = (BannerLayout) findViewById(R.id.bannerView); ListbannerList = 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); } @Override protected void onStop() { super.onStop(); bannerView.bannerShutdown(); }}
欢迎加入Android进阶交流群;701740775。进群可免费领取一份最新技术大纲和Android进阶资料。请备注csdn
转载地址:http://wggix.baihongyu.com/