版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010356768/article/details/89462624
这一节要的效果如图
新建AnimationView
public class AnimationView extends View {
Bitmap[] bitmapArray = new Bitmap[4];
int currentIndex = 0;
int viewWidth, viewHeight;
int sleepTime = 1000;
boolean isRunning = true;
Thread thread;
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
bitmapArray[0] = BitmapFactory.decodeResource(getResources(), R.mipmap.logo1);
bitmapArray[1] = BitmapFactory.decodeResource(getResources(), R.mipmap.logo2);
bitmapArray[2] = BitmapFactory.decodeResource(getResources(), R.mipmap.logo3);
bitmapArray[3] = BitmapFactory.decodeResource(getResources(), R.mipmap.logo4);
thread = new Thread(new MyRunnable());
thread.start();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect(0, 0, viewWidth, viewHeight);
Paint paint = new Paint();
paint.setColor(Color.CYAN);
canvas.drawRect(rect, paint);
Bitmap bitmap = bitmapArray[currentIndex];
int imageX = (viewWidth - bitmap.getWidth()) / 2;
int imageY = (viewHeight - bitmap.getHeight()) / 2;
canvas.drawBitmap(bitmap, imageX, imageY, paint);
}
/////
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
viewWidth = w;
viewHeight = h;
super.onSizeChanged(w, h, oldw, oldh);
}
class MyRunnable implements Runnable {
@Override
public void run() {
while (isRunning) {
try {
currentIndex++;
if (currentIndex > (bitmapArray.length - 1)) {
currentIndex = 0;
}
//只能在主线程中调用invalidate()
//工作线程中调onDraw
postInvalidate();
Thread.currentThread().sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
在布局中使用
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/first_bg">
<com.example.xx.allrun.widget.AnimationView
android:id="@+id/animationView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
素材图片如下
增加自定义属性
res下增加attrs.xml,这里我们定义了2个属性,sleep_time用来控制休眠时间,是个浮点类型;images用来控制图片,是个引用类型
<resources>
<declare-styleable name="AnimationView">
<attr name="sleep_time" format="float"/>
<attr name="images" format="reference"/>
</declare-styleable>
</resources>
xml使用
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:AnimationView="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.xx.animationview.AnimationView
android:id="@+id/animationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
AnimationView:sleep_time="1000"/>
</LinearLayout>
这里用了我们刚才自定义的属性,就行android中自带的属性会有android:
前缀,我们自定义的属性要想使用自定义的前缀,需要增加声明。例如,我们使用AnimationView:
前缀,我们需要增加xmlns:AnimationView="http://schemas.android.com/apk/res-auto"
,这行代码
AnimationView的构造方法中可以拿到这些属性
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
//读取自定义属性
//attrs里放的是属性
//数组里放的是sleep_time和images属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AnimationView);
sleepTime = (int)typedArray.getFloat(R.styleable.AnimationView_sleep_time,0);
......
}
现在我们来用属性控制图片
res下新建arrays.xml
<resources>
<string-array name="animationImages">
<item>@mipmap/logo1</item>
<item>@mipmap/logo2</item>
<item>@mipmap/logo3</item>
<item>@mipmap/logo4</item>
</string-array>
</resources>
xml中使用
<com.xx.animationview.AnimationView
android:id="@+id/animationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
AnimationView:sleep_time="5000"
AnimationView:images="@array/animationImages"/>
AnimationView构造方法中读取图片属性,之前存放图片的 Bitmap[] bitmapArray 指定了大小为4,这里去掉这个限制,设置其大小为图片的个数
public class AnimationView extends View {
Bitmap[] bitmapArray;
......
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
......
//读取float和读取数组是不一样的
Resources resources = context.getResources();
TypedArray typedArrayImages = resources.obtainTypedArray(R.array.animationImages);
int length = typedArrayImages.length();
bitmapArray = new Bitmap[length];
for(int i=0;i<length;i++){
//从数组中读取图的Id
//第二个参数是默认值
int imageResId = typedArrayImages.getResourceId(i,0);
//创建Bitmap
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),imageResId);
bitmapArray[i] = bitmap;
}
......
}
}
设置控件宽高
现在控件是全屏的,现在设置控件大小为最大的图片宽高
扫描二维码关注公众号,回复:
6189712 查看本文章
布局中设置控件宽高为wrap_content
<com.xx.animationview.AnimationView
android:id="@+id/animationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
AnimationView:sleep_time="500"
AnimationView:images="@array/animationImages"/>
AnimationView中定义最大宽高,然后重写onMeasure方法
public class AnimationView extends View {
......
//图片最大宽高
int imageMaxWidth,imageMaxHeight;
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
......
for(int i=0;i<length;i++){
//从数组中读取图的Id
//第二个参数是默认值
int imageResId = typedArrayImages.getResourceId(i,0);
//创建Bitmap
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),imageResId);
//得图的最大宽高
if(bitmap.getWidth()>imageMaxWidth){
imageMaxWidth = bitmap.getWidth();
}
if(bitmap.getHeight()>imageMaxHeight){
imageMaxHeight = bitmap.getHeight();
}
bitmapArray[i] = bitmap;
}
thread = new Thread(new MyRunnable());
thread.start();
}
//设置控件的大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(imageMaxWidth,imageMaxHeight);
}
......
}