Android封装Banner控件方法介绍
在Android开发中,轮播图是常见的功能之一。针对这一需求,我们可以通过封装一个Banner控件来实现。下面我们将详细介绍封装Banner控件的过程和方法。
1.需求分析
首先分析需求,我们需要实现一个Banner控件,该控件能够自动轮播、支持手动滑动切换图片,并且支持网络和本地图片加载。
2.技术选型
针对需求,我们可以选用以下技术来实现:
- ViewPager:用于多张图片滑动切换
- Handler:用于定时轮播
- Picasso/Glide:用于网络图片的异步加载
- ButterKnife:用于视图注入
3.实现步骤
3.1 创建Banner布局
首先在XML布局文件中创建Banner控件和指示器Indicator:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.view.ViewPager
android:id="@+id/banner_viewpager"
android:layout_width="match_parent"
android:layout_height="200dp"/>
<LinearLayout
android:id="@+id/banner_indicator"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_alignBottom="@id/banner_viewpager"
android:gravity="center"
android:orientation="horizontal"/>
</RelativeLayout>
3.2 封装Banner控件
创建BannerAdapter类,该类继承自ViewPager.Adapter,并实现数据绑定和视图重用的功能,代码如下:
public class BannerAdapter extends PagerAdapter {
private List<String> mList;
private List<ImageView> mViewList;
public BannerAdapter(List<String> list, List<ImageView> viewList) {
mList = list;
mViewList = viewList;
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
ImageView imageView = mViewList.get(position % mViewList.size());
container.addView(imageView);
return imageView;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
}
}
在MainActivity中创建Banner控件,并调用BannerAdapter来设置Banner轮播效果:
public class MainActivity extends AppCompatActivity {
@BindView(R.id.banner_viewpager)
ViewPager mBannerViewPager;
@BindView(R.id.banner_indicator)
LinearLayout mBannerIndicator;
private List<ImageView> mViewList = new ArrayList<>();
private List<String> mList = new ArrayList<>();
private int mCurrentPosition;
private Handler mHandler;
private Runnable mRunnable;
private BannerAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initData();
initAdapter();
mHandler = new Handler(Looper.getMainLooper());
mRunnable = () -> {
mCurrentPosition++;
mBannerViewPager.setCurrentItem(mCurrentPosition);
mHandler.postDelayed(mRunnable, 3000);
};
mHandler.postDelayed(mRunnable, 3000);
}
private void initData() {
mList.add("http://pic1.win4000.com/wallpaper/2018-01-18/5a60f95d9e2b4.jpg");
mList.add("http://pic27.nipic.com/20130126/12376691_210928672000_2.jpg");
mList.add("http://imgsrc.baidu.com/forum/pic/item/a973c60e7bec54e743920e9bbf389b504fc26a24.jpg");
for (int i = 0; i < mList.size(); i++) {
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
Picasso.get().load(mList.get(i)).into(imageView);
mViewList.add(imageView);
// 创建指示器
ImageView indicatorView = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
params.leftMargin = 20;
indicatorView.setLayoutParams(params);
indicatorView.setImageResource(R.drawable.banner_indicator_selector);
mBannerIndicator.addView(indicatorView);
}
}
private void initAdapter() {
mAdapter = new BannerAdapter(mList, mViewList);
mBannerViewPager.setAdapter(mAdapter);
mBannerViewPager.setCurrentItem(mViewList.size() * 10000);
mBannerViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mCurrentPosition = position;
for (int i = 0; i < mBannerIndicator.getChildCount(); i++) {
ImageView indicatorView = (ImageView) mBannerIndicator.getChildAt(i);
if (i == position % mBannerIndicator.getChildCount()) {
indicatorView.setSelected(true);
} else {
indicatorView.setSelected(false);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mRunnable);
}
}
至此,一个支持轮播、手动滑动切换、网络图片加载的Banner控件就完成了。
3.3 引入Glide来支持本地图片
引入Glide依赖:
implementation 'com.github.bumptech.glide:glide:4.10.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
重写BannerAdapter的instantiateItem方法,支持本地图片的异步加载:
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
ImageView imageView = mViewList.get(position % mViewList.size());
if (mList.get(position % mViewList.size()).startsWith("http")) {
Picasso.get().load(mList.get(position % mViewList.size())).into(imageView);
} else {
Glide.with(container.getContext()).load(mList.get(position % mViewList.size())).into(imageView);
}
container.addView(imageView);
return imageView;
}
至此,支持本地与网络图片加载的Banner控件就完成了。
4.示例说明
4.1 网络图片轮播
在initData方法中,创建mList时,添加网络图片地址即可实现网络图片轮播,如下所示:
mList.add("http://pic1.win4000.com/wallpaper/2018-01-18/5a60f95d9e2b4.jpg");
mList.add("http://pic27.nipic.com/20130126/12376691_210928672000_2.jpg");
mList.add("http://imgsrc.baidu.com/forum/pic/item/a973c60e7bec54e743920e9bbf389b504fc26a24.jpg");
4.2 本地图片轮播
在initData方法中,创建mList时,添加本地图片地址即可实现本地图片轮播,如下所示:
mList.add("file:///android_asset/banner_1.jpg");
mList.add("file:///android_asset/banner_2.jpg");
mList.add("file:///android_asset/banner_3.jpg");
5.总结
本文介绍了Android封装Banner控件的方法,通过ViewPager、Handler、Picasso/Glide等技术和BannerAdapter类的封装,实现了支持轮播、手动滑动切换、网络和本地图片加载的Banner控件。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android封装Banner控件方法介绍 - Python技术站