美文网首页
自定义帧动画下拉刷新请求头view实战

自定义帧动画下拉刷新请求头view实战

作者: 全球顶尖伪极客 | 来源:发表于2018-01-30 17:39 被阅读0次

场景:改造下拉刷新头部效果,避免换下拉刷新框架,自定义view类似京东美团小人加载。根据后台返回指定加载不同的view。eg:随机顺序,指定顺序

自定义view几个常见的需要注意的方法

重写: onMeasure()onDraw()、和 onLayout()方法

onMeasure()方法中测量出自定义控件的宽和高并且调用setMeasuredDimension(width, height)方法将宽高配置好。

onLayout()方法来确定自定义控件在布局中的位置。

onDraw()方法来将自定义 view 绘制在布局中

重绘更新:invalidate和requestLayout。

requestLayout() 方法时,view 只会执行 onMeasure(先)及 onLayout(后)方法

invalidate ()方法时,view 会调用onDraw()方法

**invalidatepostInvalidate
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,并调用AnimationViewinvalidate()方法

App.setmCurrentRefreshHeadIndex(App.getmCurrentRefreshHeadIndex() + 1);
mAnimationView.initTypeArrayResource(true);

相关文章

网友评论

      本文标题:自定义帧动画下拉刷新请求头view实战

      本文链接:https://www.haomeiwen.com/subject/jficzxtx.html