场景:改造下拉刷新头部效果,避免换下拉刷新框架,自定义view类似京东美团小人加载。根据后台返回指定加载不同的view。eg:随机顺序,指定顺序
自定义view几个常见的需要注意的方法
重写: onMeasure()
、onDraw(
)、和 onLayout()
方法
onMeasure()
方法中测量出自定义控件的宽和高并且调用setMeasuredDimension(width, height)方法将宽高配置好。
onLayout()
方法来确定自定义控件在布局中的位置。
onDraw()
方法来将自定义 view 绘制在布局中
重绘更新:invalidate和requestLayout。
requestLayout()
方法时,view 只会执行onMeasure
(先)及onLayout
(后)方法
invalidate ()
方法时,view 会调用onDraw()
方法
**invalidate
和postInvalidate
:
invalidate
方法只能用于UI线程中,
postInvalidate
在非UI线程中,可直接使用方法
自定义控件:播放动画
* 自定义控件:播放动画
*/
public class AnimationView extends View {
private Context mContext;
private int[] mViewIds = {R.array.animation1, R.array.animation2};
private Bitmap[] bitmaps = null;
/**
* 当前播的是第几张图
*/
private int currentIndex = 0;
private int viewWidth, viewHeight;
private boolean isRunning = true;
private Thread thread;
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
//读取xml中的属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.animation);
initTypeArrayResource(false);
thread = new Thread(new MyRunnable());
thread.start();
}
private Random random = new Random();
TypedArray typedArray = null;
int mCurrentIndex;
public void initTypeArrayResource(boolean flag) {
//1随机顺序 2指定顺序
if ("1".equals(App.getShowAnimationType())) {
mCurrentIndex = random.nextInt(mViewIds.length);
} else {
mCurrentIndex = App.getmCurrentRefreshHeadIndex() % mViewIds.length;
}
typedArray = mContext.getResources().obtainTypedArray(mViewIds[mCurrentIndex]);
bitmaps = new Bitmap[typedArray.length()-1];
for (int i = 0; i < typedArray.length(); i++) {
int imageResId = typedArray.getResourceId(i, 0);
bitmaps[i] = BitmapFactory.decodeResource(getResources(), imageResId);
}
if (flag) {
invalidate();
}
}
//Measure测量:测量控件的宽度,高度
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//测量模式
int mode = MeasureSpec.getMode(heightMeasureSpec);
//判断模式
//AT_MOST是一种测量模式:控件的大小可以和父容器一样大
if (mode == MeasureSpec.EXACTLY) {
int imageWidth = bitmaps[0].getWidth();
int imageHeight = bitmaps[0].getHeight();
//设置控件的大小是图片的大小
setMeasuredDimension(imageWidth - 30, imageHeight - 30);
}
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
if (currentIndex <= bitmaps.length) {
Bitmap bitmap = bitmaps[currentIndex];
if (bitmap != null) {
// 居中
int x = (viewWidth - bitmap.getWidth()) / 2;
int y = (viewHeight - bitmap.getHeight()) / 2;
canvas.drawBitmap(bitmap, x, y, paint);
}
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewHeight = h;
viewWidth = w;
}
class MyRunnable implements Runnable {
@Override
public void run() {
while (isRunning) {
try {
currentIndex++;
if (currentIndex >= bitmaps.length) {
currentIndex = 0;
}
// 调用onDraw
// invalidate()用在主线程
// 工作线程
postInvalidate();
Thread.currentThread().sleep(50);
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
}
要用到的请求头布局xml代码:
<RelativeLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/state_tv">
<com.hewoxinapp.gxmobile.view.AnimationView
android:id="@+id/animation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
**图片的数组----res--->values--->arrays.xml**
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="animation1">
<item>@drawable/dropdown_loading_00000</item>
<item>@drawable/dropdown_loading_00008</item>
<item>@drawable/dropdown_loading_00009</item>
<item>@drawable/dropdown_loading_00010</item>
</string-array>
<string-array name="animationImages2">
<item>@drawable/dropdown_loading_00000</item>
<item>@drawable/dropdown_loading_00008</item>
<item>@drawable/dropdown_loading_00009</item>
<item>@drawable/dropdown_loading_00010</item>
<item>@drawable/dropdown_loading_00011</item>
<item>@drawable/dropdown_loading_00012</item>
</string-array>
<string-array name="animationImages3">
<item>@drawable/loading_00000</item>
<item>@drawable/loading_00002</item>
<item>@drawable/loading_00004</item>
<item>@drawable/loading_00006</item>
<item>@drawable/loading_00008</item>
<item>@drawable/loading_00010</item>
<item>@drawable/loading_00012</item>
<item>@drawable/loading_00014</item>
<item>@drawable/loading_00016</item>
<item>@drawable/loading_00018</item>
</string-array>
</resources>
使用
App里面定义全局变量,每当刷新完设置+1,并调用AnimationView
的invalidate()
方法
App.setmCurrentRefreshHeadIndex(App.getmCurrentRefreshHeadIndex() + 1);
mAnimationView.initTypeArrayResource(true);
网友评论