仿微信运动步数折线统计图

来源:互联网 发布:遗传算法密码学 编辑:程序博客网 时间:2024/05/16 03:01
完整代码如下import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.DashPathEffect;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PathEffect;import android.graphics.RectF;import android.graphics.Shader;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.view.animation.AnimationUtils;import com.ast.smartlighter.R;import com.ast.smartlighter.utils.UIUtils;import java.util.ArrayList;import java.util.List;//仿微信运动步数折线分布图public class WXSportStatistics extends View implements OnTouchListener {    float mHigh = 0;    float Width = 0;    List<String> listValue = new ArrayList<String>();    List<RectF> listRectF = new ArrayList<RectF>();    List<String> listDAY = new ArrayList<String>();    boolean isKcal = false;    Float MaxValue = 0f;    private Paint paintbg;    private Paint paintCircle;    private Paint paintLine;    private Paint paint;    private Paint paintText;    private Paint paintText2;    private Path path;    Shader mShader;    int color_w = Color.argb(200, 255, 255, 255);    int CircleR = 5;    //4fd4d0    int bottomH = 0;//距离底部高度,给文字显示用的    int topH = 0;//距离顶部部高度,给选中后的文字显示用的    Context context;    public int select = -1;    public int selectbottom = -1;    public WXSportStatistics(Context context, AttributeSet attrs) {        super(context, attrs);        CircleR = UIUtils.dip2px(context, 3);        bottomH = UIUtils.dip2px(context, 12);        topH = UIUtils.dip2px(context, 16);        this.context = context;        initView();    }    public WXSportStatistics(Context context) {        super(context);        CircleR = UIUtils.dip2px(context, 3);        bottomH = UIUtils.dip2px(context, 12);        topH = UIUtils.dip2px(context, 16);        this.context = context;        initView();    }    private void initView() {        setOnTouchListener(this);        mHigh = getHeight();        Width = getWidth();        paint = new Paint();        paint.setAntiAlias(true);        paint.setStrokeWidth(2);        paint.setColor(Color.rgb(255, 255, 255));        paint.setStyle(Paint.Style.FILL);        paintText = new Paint();        paintText.setAntiAlias(true);        paintText.setStrokeWidth(4);        paintText.setColor(getResources().getColor(R.color.white));//Color.rgb(255, 255, 255));        paintText.setStyle(Paint.Style.FILL);        paintText.setTextSize(16);        paintText2 = new Paint();        paintText2.setAntiAlias(true);        paintText2.setStrokeWidth(4);        paintText2.setColor(Color.WHITE);//.rgb(33, 35, 59));        paintText2.setStyle(Paint.Style.FILL);        paintText2.setTextSize(20);        paintLine = new Paint();        paintLine.setAntiAlias(true);        paintLine.setStrokeWidth(1);        paintLine.setColor(Color.rgb(255, 255, 255));        paintLine.setStyle(Paint.Style.STROKE);        PathEffect effects = new DashPathEffect(new float[]{6, 4, 6, 4}, 1);        paintLine.setPathEffect(effects);        paintbg = new Paint();        paintbg.setAntiAlias(true);        paintbg.setStrokeWidth(0);        paintbg.setColor(Color.rgb(255, 255, 255));        paintbg.setStyle(Paint.Style.FILL);        paintCircle = new Paint();        paintCircle.setAntiAlias(true);        paintCircle.setStrokeWidth(2);        paintCircle.setStyle(Paint.Style.FILL);        paintCircle.setColor(getResources().getColor(R.color.white));        path = new Path();        mShader = new LinearGradient(0, 0, 0, getHeight(), new int[]{color_w,                getResources().getColor(R.color.transparency)}, null, Shader.TileMode.CLAMP);        paintbg.setShader(mShader);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        float High = mHigh - bottomH;        if (listValue != null && listValue.size() != 0 && listDAY != null && listDAY.size() != 0) {            for (int i = 0; i < listValue.size(); i++) {                float h = High - High * Float.parseFloat(listValue.get(i)) / MaxValue;                h = h + topH;                float w = (float) (Width / listValue.size() * (i + 0.5));                if (High * Float.parseFloat(listValue.get(i)) / MaxValue < CircleR) {                    h = High - CircleR - 1;                }                if (h < CircleR) {                    h = CircleR + 1;                }                if (h > High - CircleR) {                    h = High - CircleR + 1;                }                if (MaxValue == 0)                    h = High - CircleR - 1;                if (i == 0) {                    path.moveTo(w, h);                } else if (i == listValue.size() - 1) {                    path.lineTo(w, h);                    path.lineTo(w, High);                    path.lineTo((float) (Width / listValue.size() * 0.5), High);                    path.lineTo((float) (Width / listValue.size() * 0.5),                            High - High * Float.parseFloat(listValue.get(0)) / MaxValue);                    path.close();                    canvas.drawPath(path, paintbg);                } else {                    path.lineTo(w, h);                }                if (i != listValue.size() - 1) {                    float stopY = High - High * Float.parseFloat(listValue.get(i + 1)) / MaxValue + topH;                    float stopX = (float) (Width / listValue.size() * (i + 1.5));                    if (High * Float.parseFloat(listValue.get(i + 1)) / MaxValue < CircleR) {                        stopY = High - CircleR - 1;                    }                    if (stopY < CircleR) {                        stopY = CircleR + 1;                    }                    if (MaxValue == 0)                        stopY = High - CircleR - 1;                    if (stopY > High - CircleR) {                        stopY = High - CircleR + 1;                    }                    canvas.drawLine(w, h, stopX, stopY, paint);                }            }            listRectF.clear();            for (int i = 0; i < listDAY.size(); i++) {                float w = (float) (Width / listValue.size() * (i + 0.5));                String day = listDAY.get(i);                if (listDAY.size() == 7) {                    paintText.setTextSize(UIUtils.dip2px(getContext(), 10));                    paintText2.setTextSize(UIUtils.dip2px(getContext(), 10));                    int width = getTextWidth(paintText, day);                    if (selectbottom == i) {                        canvas.drawText(day, w - width / 2, mHigh - 2, paintText2);                        selectbottom = -1;                    } else {                        canvas.drawText(day, w - width / 2, mHigh - 2, paintText);                    }                } else if (listDAY.size() == 12) {                    paintText.setTextSize(UIUtils.dip2px(getContext(), 10));                    paintText2.setTextSize(UIUtils.dip2px(getContext(), 10));                    int width = getTextWidth(paintText, day);                    if (selectbottom == i) {                        canvas.drawText(day, w - width / 2, mHigh - 2, paintText2);                        selectbottom = -1;                    } else {                        canvas.drawText(day, w - width / 2, mHigh - 2, paintText);                    }                } else if (listDAY.size() == 30) {                    paintText.setTextSize(UIUtils.dip2px(getContext(), 10));                    paintText2.setTextSize(UIUtils.dip2px(getContext(), 10));                    if (i == 0 || i == 7 || i == 15 || i == 22 || i == 29) {                        int width = getTextWidth(paintText, day);                        if (selectbottom == i) {                            if (i == 0) {                                canvas.drawText(day, w, mHigh - 2, paintText2);                            } else {                                canvas.drawText(day, w - width / 2, mHigh - 2, paintText2);                            }                            selectbottom = -1;                        } else {                            if (i == 0) {                                canvas.drawText(day, w, mHigh - 2, paintText);                            } else {                                canvas.drawText(day, w - width / 2, mHigh - 2, paintText);                            }                        }                    }                } else if (listDAY.size() == 31) {                    paintText.setTextSize(UIUtils.dip2px(getContext(), 10));                    paintText2.setTextSize(UIUtils.dip2px(getContext(), 10));                    if (i == 0 || i == 7 || i == 15 || i == 22 || i == 30) {                        int width = getTextWidth(paintText, day);                        if (selectbottom == i) {                            if (i == 0) {                                canvas.drawText(day, w, mHigh - 2, paintText2);                            } else {                                canvas.drawText(day, w - width / 2, mHigh - 2, paintText2);                            }                            selectbottom = -1;                        } else {                            if (i == 0) {                                canvas.drawText(day, w, mHigh - 2, paintText);                            } else {                                canvas.drawText(day, w - width / 2, mHigh - 2, paintText);                            }                        }                    }                } else if (listDAY.size() == 29) {                    paintText.setTextSize(UIUtils.dip2px(getContext(), 10));                    paintText2.setTextSize(UIUtils.dip2px(getContext(), 10));                    if (i == 0 || i == 7 || i == 15 || i == 22 || i == 28) {                        int width = getTextWidth(paintText, day);                        if (selectbottom == i) {                            if (i == 0) {                                canvas.drawText(day, w, mHigh - 2, paintText2);                            } else {                                canvas.drawText(day, w - width / 2, mHigh - 2, paintText2);                            }                            selectbottom = -1;                        } else {                            if (i == 0) {                                canvas.drawText(day, w, mHigh - 2, paintText);                            } else {                                canvas.drawText(day, w - width / 2, mHigh - 2, paintText);                            }                        }                    }                } else if (listDAY.size() == 28) {                    paintText.setTextSize(UIUtils.dip2px(getContext(), 10));                    paintText2.setTextSize(UIUtils.dip2px(getContext(), 10));                    if (i == 0 || i == 7 || i == 15 || i == 22 || i == 27) {                        int width = getTextWidth(paintText, day);                        if (selectbottom == i) {                            if (i == 0) {                                canvas.drawText(day, w, mHigh - 2, paintText2);                            } else {                                canvas.drawText(day, w - width / 2, mHigh - 2, paintText2);                            }                            selectbottom = -1;                        } else {                            if (i == 0) {                                canvas.drawText(day, w, mHigh - 2, paintText);                            } else {                                canvas.drawText(day, w - width / 2, mHigh - 2, paintText);                            }                        }                    }                }            }            for (int i = 0; i < listValue.size(); i++) {                float h = High - High * Float.parseFloat(listValue.get(i)) / MaxValue + topH;                float w = (float) (Width / listValue.size() * (i + 0.5));                if (High * Float.parseFloat(listValue.get(i)) / MaxValue < CircleR) {                    h = High - CircleR - 1;                }                if (h < CircleR) {                    h = CircleR + 1;                }                if (h > High - CircleR) {                    h = High - CircleR + 1;                }                if (MaxValue == 0)                    h = High - CircleR - 1;                canvas.drawCircle(w, h, CircleR, paint);                RectF f1 = new RectF();                float wrf = (float) (Width / listValue.size() / 2);                f1.set(w - wrf, 0, w + wrf, getHeight());                if (select == i) {                    int width = getTextWidth(paintText2, Float.parseFloat(listValue.get(i)) + "");                    int high = (int) getTextHigh(paintText2);                    if (w - width / 2 < 0) {                        canvas.drawText(Float.parseFloat(listValue.get(i)) + "", w, high, paintText2);                    } else if (w + width / 2 > Width) {                        canvas.drawText(Float.parseFloat(listValue.get(i)) + "", w - width, high, paintText2);                    } else {                        canvas.drawText(Float.parseFloat(listValue.get(i)) + "", w - width / 2, high,                                paintText2);                    }                    select = -1;                }                listRectF.add(f1);            }        }    }    Animation popup_enter_bottom;    Animation popup_out_bottom;    SelectItem mselectItem;    int vid = 0;    public void setValue(final List<String> listValue, final boolean cal, final boolean anim,                         final List<String> listDay, SelectItem mselectItem, int vid) {        this.mselectItem = mselectItem;        this.vid = vid;        this.listDAY = new ArrayList<String>();        ;        this.listDAY.addAll(listDay);        this.isKcal = cal;        if (this.listValue != null && this.listValue.size() != 0 && anim) {            popup_out_bottom = AnimationUtils.loadAnimation(getContext(), R.anim.sacle_bottom_out);            startAnimation(popup_out_bottom);            popup_out_bottom.setAnimationListener(new AnimationListener() {                @Override                public void onAnimationStart(Animation arg0) {                    // TODO Auto-generated method stub                }                @Override                public void onAnimationRepeat(Animation arg0) {                    // TODO Auto-generated method stub                }                @Override                public void onAnimationEnd(Animation arg0) {                    setVisibility(View.INVISIBLE);                    play(listValue, cal, anim, 10);                }            });        } else {            play(listValue, cal, anim, 600);        }    }    private void play(final List<String> listValue, final boolean cal, boolean anim, int time) {        this.listValue = new ArrayList<String>();        this.listValue.addAll(listValue);        MaxValue = 0f;        post(new Runnable() {            @Override            public void run() {                for (String a : listValue) {                    if (Float.parseFloat(a) > MaxValue)                        MaxValue = Float.parseFloat(a);                }                initView();                invalidate();            }        });        if (anim) {            setVisibility(View.INVISIBLE);            popup_enter_bottom = AnimationUtils.loadAnimation(getContext(), R.anim.sacle_bottom_in);            popup_enter_bottom.setAnimationListener(new AnimationListener() {                @Override                public void onAnimationStart(Animation arg0) {                    setVisibility(View.VISIBLE);                }                @Override                public void onAnimationRepeat(Animation arg0) {                    // TODO Auto-generated method stub                }                @Override                public void onAnimationEnd(Animation arg0) {                    // TODO Auto-generated method stub                }            });            postDelayed(new Runnable() {                @Override                public void run() {                    // TODO Auto-generated method stub                    startAnimation(popup_enter_bottom);                }            }, time);        }    }    @Override    public boolean onTouch(View arg0, MotionEvent event) {        if (event.getAction() == MotionEvent.ACTION_UP) {            float x = event.getX();            float y = event.getY();            for (int i = 0; i < listRectF.size(); i++) {                if (listRectF.get(i).contains(x, y)) {                    if (mselectItem != null) {                        select = i;                        selectbottom = i;                        mselectItem.onSelectItem(this.vid, i);                    }                    break;                }            }        }        return true;    }    public void ShowView() {        setValue(this.listValue, this.isKcal, false, this.listDAY, mselectItem, this.vid);    }    public interface SelectItem {        void onSelectItem(int vid, int item);    }    public int getTextWidth(Paint paint, String str) {        int iRet = 0;        if (str != null && str.length() > 0) {            int len = str.length();            float[] widths = new float[len];            paint.getTextWidths(str, widths);            for (int j = 0; j < len; j++) {                iRet += (int) Math.ceil(widths[j]);            }        }        return iRet;    }    public static float getTextHigh(Paint paint) {        Paint.FontMetrics fm = paint.getFontMetrics();        return fm.descent - fm.ascent;    }}用到的动画 
 R.anim.sacle_bottom_in
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >    <scale        android:duration="500"        android:fillAfter="false"        android:fromXScale="1.0"        android:fromYScale="0.0"        android:interpolator="@android:anim/accelerate_decelerate_interpolator"        android:pivotX="0%"        android:pivotY="100%"        android:toXScale="1.0"        android:toYScale="1.0" /></set>======================================================
 R.anim.sacle_bottom_out
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >    <scale        android:duration="300"        android:fillAfter="false"        android:fromXScale="1.0"        android:fromYScale="1.0"        android:interpolator="@android:anim/accelerate_decelerate_interpolator"        android:pivotX="0%"        android:pivotY="100%"        android:toXScale="1.0"        android:toYScale="0.0" /></set>

用到的工具类
import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.util.DisplayMetrics;import android.view.View;import android.view.inputmethod.InputMethodManager;import android.widget.EditText;import com.ast.smartlighter.MyApplication;import java.lang.reflect.Field;public class UIUtils {    /**     * 获取屏幕宽度     *     * @param activity     * @return     * @Description:     */    public static int getScreenWidth(Activity activity) {        if (activity == null) {            return 0;        }        DisplayMetrics dm = new DisplayMetrics();        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);        return dm.widthPixels;    }    /**     * 获取屏幕高度     *     * @param activity     * @return     * @Description:     */    public static int getScreenHeight(Activity activity) {        if (activity == null) {            return 0;        }        DisplayMetrics dm = new DisplayMetrics();        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);        return dm.heightPixels;    }    /**     * 获取状态栏高度     *     * @param activity     * @return     * @Description:     */    public static int getStatusBarHeight(Activity activity) {        int result = 0;        int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");        if (resourceId > 0) {            result = activity.getResources().getDimensionPixelSize(resourceId);        }        return result;    }    public static int getStatusBarHeight(Context context) {        Class<?> c = null;        Object obj = null;        Field field = null;        int x = 0, statusBarHeight = 0;        try {            c = Class.forName("com.android.internal.R$dimen");            obj = c.newInstance();            field = c.getField("status_bar_height");            x = Integer.parseInt(field.get(obj).toString());            statusBarHeight = context.getResources().getDimensionPixelSize(x);        } catch (Exception e1) {            e1.printStackTrace();        }        return statusBarHeight;    }    /**     * px值转换为dipdp值,保证尺寸大小不变     *     * @param pxValue     * @param scale   DisplayMetrics类中属性density     * @return     */    public static int px2dip(float pxValue) {        final float scale = MyApplication.getContext().getResources().getDisplayMetrics().density;        return (int) (pxValue / scale + 0.5f);    }    /**     * dipdp值转换为px值,保证尺寸大小不变     *     * @param dipValue     * @param scale    DisplayMetrics类中属性density     * @return     */    public static int dip2px(Context context, float dipValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dipValue * scale + 0.5f);    }    /**     * px值转换为sp值,保证文字大小不变     *     * @param pxValue     * @param fontScale DisplayMetrics类中属性scaledDensity     * @return     */    public static int px2sp(Context context, float pxValue) {        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;        return (int) (pxValue / fontScale + 0.5f);    }    /**     * sp值转换为px值,保证文字大小不变     *     * @param spValue     * @param fontScale DisplayMetrics类中属性scaledDensity     * @return     */    public static int sp2px(float spValue) {        final float fontScale = MyApplication.getContext().getResources().getDisplayMetrics().scaledDensity;        return (int) (spValue * fontScale + 0.5f);    }    public static View inflate(int layoutId) {        return View.inflate(MyApplication.getContext(), layoutId, null);    }    public static <T extends Object> T checkNull(String msg, T t) {        if (t == null) {            throw new NullPointerException(msg + " can not be null!");        }        return t;    }    public static <T extends Object> T checkNull(T t) {        return checkNull("params", t);    }    /**     * @param bitmap     原图     * @param edgeLength 希望得到的正方形部分的边长     * @return 缩放截取正中部分后的位图。     */    public static Bitmap centerSquareScaleBitmap(Bitmap bitmap, int edgeLength) {        if (null == bitmap || edgeLength <= 0) {            return null;        }        Bitmap result = bitmap;        int widthOrg = bitmap.getWidth();        int heightOrg = bitmap.getHeight();        if (widthOrg > edgeLength && heightOrg > edgeLength) {            //压缩到一个最小长度是edgeLengthbitmap            int longerEdge = (int) (edgeLength * Math.max(widthOrg, heightOrg) / Math.min(widthOrg, heightOrg));            int scaledWidth = widthOrg > heightOrg ? longerEdge : edgeLength;            int scaledHeight = widthOrg > heightOrg ? edgeLength : longerEdge;            Bitmap scaledBitmap;            try {                scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);            } catch (Exception e) {                return null;            }            //从图中截取正中间的正方形部分。            int xTopLeft = (scaledWidth - edgeLength) / 2;            int yTopLeft = (scaledHeight - edgeLength) / 2;            try {                result = Bitmap.createBitmap(scaledBitmap, xTopLeft, yTopLeft, edgeLength, edgeLength);                scaledBitmap.recycle();            } catch (Exception e) {                return null;            }        }        return result;    }    //此方法,如果显示则隐藏,如果隐藏则显示    public static void hintKbOne(Context context) {        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);        // 得到InputMethodManager的实例        if (imm.isActive()) {            // 如果开启            imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT,                    InputMethodManager.HIDE_NOT_ALWAYS);        }    }    //隐藏键盘    public static void hidekeybroad(Context context, EditText et) {        InputMethodManager imm2 = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);        if (imm2 != null) {            imm2.hideSoftInputFromWindow(et.getWindowToken(), 0);        }    }}


//在代码中使用
<com.ast.smartlighter.view.WXSportStatistics    android:id="@+id/wxsport"    android:layout_width="match_parent"    android:layout_height="match_parent" />
 
private void show(List<String> data, List<String> day) {   //设置数据源    wxsport.setValue(data, false, true, day, this, R.id.wxsport);}//每个点的点击事件@Overridepublic void onSelectItem(int vid, int item) {    switch (vid) {        case R.id.wxsport:            wxsport.select = item;            wxsport.selectbottom = item;            wxsport.ShowView();            break;        default:            break;    }}







 
原创粉丝点击