Android 广告轮播实现
- 最终效果
- 最简单的轮播效果
- 带小圆点(自定义控件)的轮播
工具:
Android studio
环境:
compileSdkVersion 28
com.android.tools.build:gradle:3.3.2
最终效果
最简单的轮播效果
以下实现轮播,但是不包含圆点
轮播效果用viewPager来实现,布局文件如下
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".EducationMainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</RelativeLayout>
新建一个Fragment,作为ViewPager里放的显示内容,新建的时候下图选项取消选择
这里的fragment主要包含一张广告图片,布局文件如下
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BannerFragment">
<!-- TODO: Update blank fragment layout -->
<ImageView
android:id="@+id/iv_Banner"
android:layout_width="match_parent"
android:layout_height="200dp" />
</FrameLayout>
fragment里面的实现代码
public class BannerFragment extends Fragment {
private int imgRes;
public BannerFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View inflate=inflater.inflate(R.layout.fragment_banner, container, false);
ImageView ivBanner=inflate.findViewById(R.id.iv_Banner);
ivBanner.setImageResource(imgRes);
return inflate;
}
public void setImage(int imgRes)
{
this.imgRes=imgRes;
}
}
Activity里面的实现代码,主要使用了ViewPager来实现轮播图,使用ViewPager需要为它添加适配器来控制ViewPager里面的view的数量
public class EducationMainActivity extends FragmentActivity {
//轮播图片
private int[] imgResID =new int []{
R.drawable.rot1,
R.drawable.rot2,
R.drawable.rot3,
R.drawable.rot4};
private ViewPager mviewPager;
private Handler mHandler=new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_education_main);
mviewPager=findViewById(R.id.viewPager);
//设置适配器
mviewPager.setAdapter(new MyFragmentAdpter((getSupportFragmentManager())));
autoScroll();
}
//自动滚动
private void autoScroll()
{
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
//获取当前的页面下标
int currentItem=mviewPager.getCurrentItem();
mviewPager.setCurrentItem(currentItem+1);
//重复调用该滚动方法,每三秒钟滚动一次
mHandler.postDelayed(this,3000);
}
},3000);
}
class MyFragmentAdpter extends FragmentPagerAdapter{
//构造方法
public MyFragmentAdpter(FragmentManager fm)
{
super(fm);
}
//返回fragment的视图
@Override
public Fragment getItem(int i) {
i %=imgResID.length;
BannerFragment fragment=new BannerFragment();
fragment.setImage(imgResID[i]);
return fragment;
}
@Override
public int getCount() {
//设置滚动的一个最大值
return Integer.MAX_VALUE;
}
}
}
至此,最简单的轮播图效果完成。
带小圆点(自定义控件)的轮播
在上面简单的轮播效果之上
自定义控件类Indicator,里面有基础注释
public class Indicator extends View {
//前景色的圆的画笔
private Paint mForePaint;
//背景颜色的画笔
private Paint mBgPaint;
//小圆点数量
private int mNumber = 4;
//小圆点半径
private int mRadius = 10;
//小圆点的默认背景色画笔颜色
private int mBgColor =Color.GRAY;
//小圆点的默认前景色画笔颜色
private int mForeColor=Color.GRAY;
/***
* 设置偏移量的方法
* @param position
* @param positionOffset
*/
public void setOffset(int position,float positionOffset) {
position %= mNumber;
mOffset = position * 3 * mRadius + positionOffset * 3 * mRadius;
//重绘
invalidate();
}
/**移动的偏移量**/
private float mOffset;
//代码里面用到的
public Indicator(Context context) {
super(context);
}
//xml布局里面用到的
public Indicator(Context context, AttributeSet attrs) {
super(context, attrs);
//获得布局文件中得到的小圆点的数量,半径,两种状态下的颜色颜色
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Indicator);
mNumber = typedArray.getInteger(R.styleable.Indicator_setNumber, mNumber);
mRadius=typedArray.getInteger(R.styleable.Indicator_Indicator_radius, mRadius);
mBgColor=typedArray.getColor(R.styleable.Indicator_Indicator_bgColor, mBgColor);
mForeColor=typedArray.getColor(R.styleable.Indicator_Indicator_foreColor, mForeColor);
initPaint();
}
private void initPaint() {
//画填充圆
mForePaint = new Paint();
//设置抗锯齿
mForePaint.setAntiAlias(true);
mForePaint.setStyle(Paint.Style.FILL);
mForePaint.setColor(mForeColor);
mForePaint.setStrokeWidth(2);
//画圆圈
mBgPaint = new Paint();
mBgPaint.setAntiAlias(true);
mBgPaint.setStyle(Paint.Style.STROKE);
mBgPaint.setColor(mBgColor);
mBgPaint.setStrokeWidth(2);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置绘制的圆点居中
int w=getWidth()/2- mNumber * mRadius * 3/2;
for (int i = 0; i < mNumber; i++) {
canvas.drawCircle(w + i * mRadius * 3,60,mRadius,mBgPaint);
}
canvas.drawCircle(w + mOffset,60,mRadius,mForePaint);
}
}
在Android-app-res-values文件夹下面新建一个用于传递参数的文件attrs.xml,内容如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Indicator">
<attr name="setNumber" format="integer" />
<attr name="Indicator_radius" format="integer" />
<attr name="Indicator_bgColor" format="color|reference" />
<attr name="Indicator_foreColor" format="color|reference" />
</declare-styleable>
</resources>
放轮播图的Activity页面布局变成如下
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".EducationMainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="200dp"/>
<com.example.education.Indicator
<--!小圆点的实现,可设置圆点数量,颜色等-->
app:setNumber="4"
app:Indicator_bgColor="#ffffff"
app:Indicator_foreColor="#ffffff"
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_alignBottom="@+id/viewPager"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
Activity里面的代码如下:
public class EducationMainActivity extends FragmentActivity {
//轮播图片,这里放自己的图片资源
private int[] imgResID =new int []{
R.drawable.rot1,
R.drawable.rot2,
R.drawable.rot3,
R.drawable.rot4};
private ViewPager mviewPager;
private Handler mHandler=new Handler();
//小圆点
private Indicator mIndicator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_education_main);
mviewPager=findViewById(R.id.viewPager);
//设置适配器
mviewPager.setAdapter(new MyFragmentAdpter((getSupportFragmentManager())));
//设置页面监听
mviewPager.setOnPageChangeListener(new MyPagerListner());
mIndicator =findViewById(R.id.indicator);
autoScroll();
}
//自动滚动
private void autoScroll()
{
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
//获取当前的页面下标
int currentItem=mviewPager.getCurrentItem();
mviewPager.setCurrentItem(currentItem+1);
//重复调用该滚动方法,每三秒钟滚动一次
mHandler.postDelayed(this,3000);
}
},3000);
}
class MyPagerListner implements ViewPager.OnPageChangeListener{
//ViewPager的滚动的
/***
*
* @param position
* @param positionOffset 偏移的百分比
* @param positionOffsetPixels 偏移量
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.e("onPageScrolled", "positionOffset<< "+positionOffset +" positionOffsetPixels<<<" + positionOffsetPixels);
mIndicator.setOffset(position,positionOffset);
}
//ViewPager选中
@Override
public void onPageSelected(int position) {
}
//ViewPager滑动状态改变
@Override
public void onPageScrollStateChanged(int state) {
}
}
class MyFragmentAdpter extends FragmentPagerAdapter{
//构造方法
public MyFragmentAdpter(FragmentManager fm)
{
super(fm);
}
//返回fragment的视图
@Override
public Fragment getItem(int i) {
i %=imgResID.length;
BannerFragment fragment=new BannerFragment();
fragment.setImage(imgResID[i]);
return fragment;
}
@Override
public int getCount() {
//设置滚动的一个最大值
return Integer.MAX_VALUE;
}
}
}
至此结束