在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<ImageView> 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>