android自定义loding view(中)

github:https://github.com/1181631922/OrliteDemo


下面先上图:


暂时完成了一部分吧,支持loading图形和loading字颜色的改变,算法需要优化,内存不会溢出,但是感觉不好,下面上代码

view:

package com.fanyafeng.orlitedemo.myview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.fanyafeng.orlitedemo.util.MyUtils;

/**
 * Created by 365rili on 16/4/20.
 */
public class CircleLoadingView extends View {

    private Paint circleContour;
    private double durSpace = 0;

    private CharSequence message;
    private StaticLayout messageLayout;
    private static TextPaint textPaint;

    private int circleContourColor;
    private int messageColor;

    public int getCircleContourColor() {
        return circleContourColor;
    }

    public void setCircleContourColor(int circleContourColor) {
        this.circleContourColor = circleContourColor;
        invalidate();
    }

    public int getMessageColor() {
        return messageColor;
    }

    public void setMessageColor(int messageColor) {
        this.messageColor = messageColor;
        setMessage(getMessage());
    }

    public CharSequence getMessage() {
        return message;
    }

    public void setMessage(CharSequence message) {
        this.message = message;
        if (message != null && !message.equals("")) {
            textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            if (getMessageColor() != 0) {
                textPaint.setColor(getMessageColor());
            } else {
                textPaint.setColor(Color.parseColor("#3498DB"));
            }
            textPaint.setTextSize(14 * MyUtils.getDensity(getContext()));
            textPaint.setStyle(Paint.Style.FILL);
            messageLayout = new StaticLayout(message, textPaint, MyUtils.getScreenWidth(getContext()) / 4, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
            invalidate();
        }

    }

    public CircleLoadingView(Context context) {
        super(context);
    }

    public CircleLoadingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        circleContour = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    public CircleLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float circleContourStrokeWidth = 5;
        circleContour.setAntiAlias(true);
        if (getCircleContourColor() != 0) {
            circleContour.setColor(getCircleContourColor());
        } else {
            circleContour.setColor(Color.parseColor("#3498DB"));
        }
//        circleContour.setStyle(Paint.Style.STROKE);
        circleContour.setStrokeWidth(circleContourStrokeWidth);


        float startX = getLeft();
        float endX = getRight();
//        Log.d("TAG","得到的endX的数值:"+endX);
        float startY = getTop();
        float endY = getBottom();
        float height = getHeight();
        float width = getWidth();
//        轮廓的半径
        float circleContourRadius = (endY > endX ? (endX - startX) / 2 - circleContourStrokeWidth / 2 : (endY - startY) / 2 - circleContourStrokeWidth / 2);
        float circleCountourX;
        float circleCountourY;
        if (endX > endY) {
            circleCountourX = width / 2;
            circleCountourY = height / 2;
        } else {
            circleCountourX = circleCountourY = width / 2;
        }

//        canvas.drawCircle(circleCountourX, circleCountourY, circleContourRadius, circleContour);

//        画一条垂直的线
//        canvas.drawLine(circleCountourX, circleCountourY, circleCountourX, circleCountourY - circleContourRadius, circleContour);

//        根据公式推导,每个间隔所占的角度为:11.25度,最小的圆的度数为7.5度,每个圆以7.5度等差增长,一共需要画8个圆
//        第一个:sin3.75*第一个大圆的半径   sin7.5  sin11.25 sin15 sin18.75 sin22.5 sin26.25 sin30
//        内接大圆的直径为外接大圆半径的三分之二
        float radius = circleContourRadius / 3;
//        loading圆们距离圆心的距离
        float circleLength = 2 * radius;
//        每一度所对应的数值
        double everyRadiusLength = 2 * Math.PI / 360;

//        Log.d("TAG", "圆心距离:" + circleLength + "每一度的距离:" + everyRadiusLength);

//      每个间隔的角度
        double spaceAngle = 11.25;

        //      画最后一个要旋转的圆(大圆)
//      canvas.drawCircle(circleCountourX, circleCountourY - radius * 2, (float) eighthRadius, circleContour);
        double eighthAngle = durSpace + 30;
        double eighthX = circleCountourX - circleLength * Math.sin(eighthAngle * everyRadiusLength);
        double eighthY = circleCountourY - circleLength * Math.cos(eighthAngle * everyRadiusLength);
        double eighthRadius = circleLength * Math.sin(30 * everyRadiusLength);
        canvas.drawCircle((float) eighthX, (float) eighthY, (float) eighthRadius, circleContour);

        double seventhAngle = durSpace + 30 * 2 + spaceAngle + 26.25;
        double seventhX = circleCountourX - circleLength * Math.sin(seventhAngle * everyRadiusLength);
        double seventhY = circleCountourY - circleLength * Math.cos(seventhAngle * everyRadiusLength);
        double seventhRadius = circleLength * Math.sin(26.25 * everyRadiusLength);
        canvas.drawCircle((float) seventhX, (float) seventhY, (float) seventhRadius, circleContour);

        double sixthAngle = durSpace + 30 * 2 + spaceAngle + 26.25 * 2 + spaceAngle + 22.5;
        double sixthX = circleCountourX - circleLength * Math.sin(sixthAngle * everyRadiusLength);
        double sixthY = circleCountourY - circleLength * Math.cos(sixthAngle * everyRadiusLength);
        double sixthRadius = circleLength * Math.sin(22.5 * everyRadiusLength);
        canvas.drawCircle((float) sixthX, (float) sixthY, (float) sixthRadius, circleContour);

        double fifthAngle = durSpace + 30 * 2 + spaceAngle + 26.25 * 2 + spaceAngle + 22.5 * 2 + spaceAngle + 18.75;
        double fifthX = circleCountourX - circleLength * Math.sin(fifthAngle * everyRadiusLength);
        double fifthY = circleCountourY - circleLength * Math.cos(fifthAngle * everyRadiusLength);
        double fifthRadius = circleLength * Math.sin(18.75 * everyRadiusLength);
        canvas.drawCircle((float) fifthX, (float) fifthY, (float) fifthRadius, circleContour);

        double forthAngle = durSpace + 30 * 2 + spaceAngle + 26.25 * 2 + spaceAngle + 22.5 * 2 + spaceAngle + 18.75 * 2 + spaceAngle + 15;
        double forthX = circleCountourX - circleLength * Math.sin(forthAngle * everyRadiusLength);
        double forthY = circleCountourY - circleLength * Math.cos(forthAngle * everyRadiusLength);
        double forthRadius = circleLength * Math.sin(15 * everyRadiusLength);
        canvas.drawCircle((float) forthX, (float) forthY, (float) forthRadius, circleContour);

        double thirdAngle = durSpace + 30 * 2 + spaceAngle + 26.25 * 2 + spaceAngle + 22.5 * 2 + spaceAngle + 18.75 * 2 + spaceAngle + 15 * 2 + spaceAngle + 11.25;
        double thirdX = circleCountourX - circleLength * Math.sin(thirdAngle * everyRadiusLength);
        double thirdY = circleCountourY - circleLength * Math.cos(thirdAngle * everyRadiusLength);
        double thirdRadius = circleLength * Math.sin(11.25 * everyRadiusLength);
        canvas.drawCircle((float) thirdX, (float) thirdY, (float) thirdRadius, circleContour);

        double secondAngle = durSpace + 30 * 2 + spaceAngle + 26.25 * 2 + spaceAngle + 22.5 * 2 + spaceAngle + 18.75 * 2 + spaceAngle + 15 * 2 + spaceAngle + 11.25 * 2 + spaceAngle + 7.5;
        double secondX = circleCountourX - circleLength * Math.sin(secondAngle * everyRadiusLength);
        double secondY = circleCountourY - circleLength * Math.cos(secondAngle * everyRadiusLength);
        double secondRadius = circleLength * Math.sin(7.5 * everyRadiusLength);
        canvas.drawCircle((float) secondX, (float) secondY, (float) secondRadius, circleContour);

//      求出第一个圆的x和y的位置
        double firstAngle = durSpace + 30 * 2 + spaceAngle + 26.25 * 2 + spaceAngle + 22.5 * 2 + spaceAngle + 18.75 * 2 + spaceAngle + 15 * 2 + spaceAngle + 11.25 * 2 + spaceAngle + 7.5 * 2 + spaceAngle + 3.75;
        double firstX = circleCountourX - circleLength * Math.sin(firstAngle * everyRadiusLength);
        double firstY = circleCountourY - circleLength * Math.cos(firstAngle * everyRadiusLength);
        double firstRadius = circleLength * Math.sin(3.75 * everyRadiusLength);
        canvas.drawCircle((float) firstX, (float) firstY, (float) firstRadius, circleContour);

//        Log.d("TAG", "第一个圆半径:" + firstRadius + "第二个圆半径:" + secondRadius + "第三个圆半径:" + thirdRadius + "第四个圆半径:" + forthRadius);
//        Log.d("TAG", "第五个圆半径:" + fifthRadius + "第六个圆半径:" + sixthRadius + "第七个圆半径:" + seventhRadius + "第八个圆半径:" + eighthRadius);
//        同心圆
//        canvas.drawCircle(circleCountourX, circleCountourY, circleLength, circleContour);
        canvas.save();
        canvas.translate(0, 2 * circleContourRadius + 50);
        messageLayout.draw(canvas);
        canvas.restore();

        postDelayed(refresh, 37);
    }

    private Runnable refresh = new Runnable() {
        @Override
        public void run() {
            durSpace -= 3;
            invalidate();
        }
    };
}
activity:

package com.fanyafeng.orlitedemo.activity;

import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;

import com.fanyafeng.orlitedemo.R;
import com.fanyafeng.orlitedemo.myview.CircleLoadingView;

public class CircleLoadingActivity extends AppCompatActivity {
    private CircleLoadingView view_circle_loading;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_circle_loading);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        initView();
        initData();
    }

    private void initView() {
        view_circle_loading = (CircleLoadingView) findViewById(R.id.view_circle_loading);
    }

    private void initData() {
        view_circle_loading.setMessage("加载中...");
//        view_circle_loading.setCircleContourColor(Color.BLUE);
//        view_circle_loading.setMessageColor(Color.BLUE);
    }

}

xml没有改,因为用的as2.0+gradle2.0所以动态图直接用的app热更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值