Android中广告条轮播(Banner)的实现
16lz
2021-01-25
在Android开发中经常用到广告条轮播控件。效果如下:
下面废话不多说,上代码:
控件的布局文件如下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="120dp"> <android.support.v4.view.ViewPager android:id="@+id/vp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentTop="true"/> <LinearLayout android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_title" android:layout_gravity="center_vertical" android:text="广告条" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" /> <LinearLayout android:id="@+id/ll_points" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"/> LinearLayout>RelativeLayout>
控件对应的java代码:
//自定义控件//1,封装//2,制作特效public class MyViewPager extends LinearLayout implements OnPageChangeListener, OnClickListener { private ViewPager vp; private String[] titles; private TextView tv_title; private LinearLayout ll_points; private int[] imgs; public MyViewPager(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { View.inflate(getContext(), R.layout.vp_main, this); initView(); } private void initView() { vp = (ViewPager) findViewById(R.id.vp); tv_title = (TextView) findViewById(R.id.tv_title); ll_points = (LinearLayout) findViewById(R.id.ll_points); } // 修改部分: // 1,将适配器修改为优化后的适配器 // 2,所有使用到初始化的ivs的地方全部删除掉 public void setDatas(int[] imgs, String[] titles) { this.imgs = imgs; this.titles = titles; for (int i = 0; i < imgs.length; i++) { // 添加点 View child = new View(getContext()); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20); params.leftMargin = 10; child.setLayoutParams(params); child.setBackgroundResource(R.drawable.point_selector); // 给点取个名字 child.setTag(i); child.setOnClickListener(this); ll_points.addView(child); } vp.setAdapter(new MyAdapter()); vp.setCurrentItem(1); tv_title.setText(titles[0]); // 默认让第0个点为红色 ll_points.getChildAt(0).setEnabled(false); // 每隔一段时间让ViewPager自动滚动(调用vp.setCurrentItem方法) } private Handler handler = new Handler(); // 在自定义控件创建的时候,添加监听 // 当前自定义控件与窗体进行绑定 @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); vp.addOnPageChangeListener(this); // 延迟执行参数1 handler.postDelayed(new MyRunnable(), 1000); } private boolean isScroll=true; private class MyRunnable implements Runnable { @Override public void run() { if (isScroll) { vp.setCurrentItem(vp.getCurrentItem()+1); handler.postDelayed(this, 1000); } } } // 在自定义控件销毁的时候,移除监听 @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); vp.removeOnPageChangeListener(this); isScroll=false; } private class MyAdapter extends PagerAdapter { private List caches;//定义缓存 public MyAdapter() { caches = new ArrayList<>(); } @Override public int getCount() { return titles.length + 2; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public Object instantiateItem(ViewGroup container, int position) { if (caches.isEmpty()) { ImageView iv = new ImageView(getContext()); caches.add(iv); } ImageView iv = caches.remove(0); if (position == 0) { iv.setImageResource(imgs[imgs.length - 1]); } else if (position == imgs.length + 1) { iv.setImageResource(imgs[0]); } else { iv.setImageResource(imgs[position - 1]); } container.addView(iv); return iv; } @Override public void destroyItem(ViewGroup container, int position, Object object) { ImageView iv = (ImageView) object; container.removeView(iv); caches.add(iv); } } // 页面滚动 @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } private int modifyPosition; private int position; private int prePosition = 1; // 页面被选择 @Override public void onPageSelected(int position) { // 记住修改位置 this.modifyPosition = position; // 记住实际位置 this.position = position; if (position == titles.length + 1) { modifyPosition = 1; } else if (position == 0) { modifyPosition = titles.length; } Log.i("test", "prePosition:" + prePosition + ", modifyPosition:" + modifyPosition); if (prePosition != modifyPosition) { tv_title.setText(titles[modifyPosition - 1]); // 让之前的点边白,让当前的点变红 ll_points.getChildAt(modifyPosition - 1).setEnabled(false); ll_points.getChildAt(prePosition - 1).setEnabled(true); prePosition = modifyPosition; } } // 页面滚动状态改变 @Override public void onPageScrollStateChanged(int state) { if (state == OnScrollListener.SCROLL_STATE_IDLE) { // 当滑动到最开始或最结尾的位置的时候,需要跳到修改后的位置 if (this.position == 0 || this.position == titles.length + 1) { // 参数2:顺滑的滚动,默认是true vp.setCurrentItem(modifyPosition, false); } } } @Override public void onClick(View v) { int tag = (int) v.getTag(); // 跳转到对应位置的页面 vp.setCurrentItem(tag); }}
point_selector对应的xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true" android:drawable="@drawable/point_white">item> <item android:state_enabled="false" android:drawable="@drawable/point_red"/>selector>
point_white xml:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval" > <solid android:color="@android:color/white" />shape>
point_red xml:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#f00" />shape>
更多相关文章
- 安全新手入坑——HTML标签
- Nginx系列教程(四)| 一文带你读懂Nginx的动静分离
- Android(安卓)BaseAdapter与ListView的使用
- Android(安卓)TouchDelegate 扩大点击区域
- 5. android 列表视图
- Activity以及用Intent实现页面跳转和数据传递
- android控件之EditText
- Android(安卓)软键盘弹出时把布局顶上去,控件乱套解决方法
- Android(安卓)Studio 提示错误 default activity not found