Android自定义view实现日历打卡签到

本文实例为大家分享了Android自定义view实现日历打卡签到的具体代码,供大家参考,具体内容如下

1.说明

自己写一个view实现每天签到的功能,设置背景图片

源码下载

2.效果图

3.主界面

package com.example.myapplication30;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    //参考网址:https://blog.csdn.net/MacaoPark/article/details/102069775
    private TextView mTvDaySum;
    private TextView mTvMonth;
    private SignView mCvCalendar;
    private List<SignEntity> data;
    private Calendar calendar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTvDaySum = findViewById(R.id.punch_tv_day_sum);
        mTvMonth = findViewById(R.id.punch_tv_month);
        mCvCalendar = findViewById(R.id.punch_cv_calendar);
    }

    @Override
    protected void onStart() {
        super.onStart();
        onReady();
    }

    @SuppressLint("SetTextI18n")
    private void onReady() {
          calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        //int date =  calendar.get(Calendar.DATE);
        int dayOfMonthToday = calendar.get(Calendar.DAY_OF_MONTH);
        List<SignDate> signDates = new ArrayList<>();
        signDates.add(new SignDate(2021, 5, 1, true));
        signDates.add(new SignDate(2021, 5, 2, true));
        signDates.add(new SignDate(2021, 5, 3, true));
        signDates.add(new SignDate(2021, 5, 4, true));
        signDates.add(new SignDate(2021, 5, 5, true));

        mTvDaySum.setText("本期连续登录\t"+signDates.size()+"\t天");
        mTvMonth.setText(year+"年"+getResources().getStringArray(R.array.month_array)[month]+"\t"+dayOfMonthToday+"日");

        data = new ArrayList<>();
        for (int i = 1; i <= dayOfMonthToday; i++) {
            SignEntity signEntity = new SignEntity();
            if (i == dayOfMonthToday) {
                signEntity.setDayType(2);
            } else {
                signEntity.setDayType(1);
            }
            for (int j = 0; j < signDates.size(); j++) {
                if (signDates.get(j).getDay() == i) {
                    signEntity.setDayType(0);
                    break;
                } else if (dayOfMonthToday == i) {
                    signEntity.setDayType(2);
                } else {
                    signEntity.setDayType(1);
                }
            }
            data.add(signEntity);
        }

        SignAdapter signAdapter = new SignAdapter(data);
        mCvCalendar.setAdapter(signAdapter);
    }

}

4.适配器

package com.example.myapplication30;

import java.util.List;

/**
 * SignAdapter
 * Created by E.M on 2016/4/21.
 */
public class SignAdapter extends CalendarAdapter {
    private List<SignEntity> data;

    public SignAdapter(List<SignEntity> data) {
        this.data = data;
    }

    @Override
    public SignView.DayType getType(int dayOfMonth) {
        return SignView.DayType.valueOf(data.get(dayOfMonth - 1).getDayType());
    }
}

5.自定义view

package com.example.myapplication30;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposeShader;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.Calendar;

/**
 * 签到日历控件
 * Created by E.M on 2016/4/20.
 */
public class SignView extends View {
    private static final String[] WEEK_MARK = {"一", "二", "三", "四", "五", "六", "日"};

    private static final int MAX_COLUMN = 7;
    /**
     * 周内
     */
    private static final int COLOR_MARKER_WEEKDAY = 0xFF999999;
    private static final int COLOR_MARKER_WEEKEND = 0xFF1B89CD;
    /**
     * 已签到背景色
     */
    //private static final int COLOR_BACKGROUND_HIGHLIGHT = 0xFFFF0000;
    /**
     * 未签到背景色
     */
    private static final int COLOR_BACKGROUND_NORMAL = 0xFF9C9C9C;
    /**
     * 等待签到背景色
     */
    private static final int COLOR_BACKGROUND_WAIT = 0xFFFE7471;
    /**
     * 已签到文字颜色
     */
    private static final int COLOR_TEXT_HIGHLIGHT = 0xFFFFFFFF;
    /**
     * 未签到文字颜色
     */
    private static final int COLOR_TEXT_NORMAL = 0xFF606060;
//    /**
//     * 不可用文字颜色
//     */
//    private static final int COLOR_TEXT_DISABLED = 0xFFD4D4D4;

    private static final int MARKER_TEXT_SIZE = 40;
    private static final int CELL_TEXT_SIZE = 40;

    private static final int VERTICAL_SPACE = 51;
    private static final int VERTICAL_MARGIN = 62;
    private static final int HORIZONTAL_MARGIN = 39;
    private static final int CELL_SIZE = 80;
    private static final int WAIT_LINE_SIZE = 14;

    private int dayOfMonthToday;
    private int markerTextY;
    private int verticalCellTop;
    private int sumDayOfMonth;
    private int daysOfFirstWeek;
    private int horizontalSpace;
    private int deltaTextCellY;
    private int deltaTextMarkerY;

    private int verticalSpace;
    private int verticalMargin;
    private int horizontalMargin;
    private int cellSize;
    private int waitLineSize;

    private Path waitPath;
    private Rect waitRect;
    private Paint paintWeekday;
    private Paint paintWeekend;
    private Paint paintTextNormal;
    private Paint paintTextHighlight;
    private Paint paintBackgroundWait;
    private Paint paintBackgroundNormal;
    private Paint paintBackgroundHighlight;
    private CalendarAdapter adapter;

    public SignView(Context context) {
        this(context, null);
    }

    public SignView(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public SignView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initResolution();
        initPaint();
        initData();
    }

    private void initResolution() {
//        resolutionUtil = ResolutionUtil.getInstance();
//        verticalSpace = resolutionUtil.formatVertical(VERTICAL_SPACE);
//        verticalMargin = resolutionUtil.formatVertical(VERTICAL_MARGIN);
//        horizontalMargin = resolutionUtil.formatHorizontal(HORIZONTAL_MARGIN);
//        cellSize = resolutionUtil.formatVertical(CELL_SIZE);
//        waitLineSize = resolutionUtil.formatVertical(WAIT_LINE_SIZE);
        verticalSpace = VERTICAL_SPACE;
        verticalMargin = VERTICAL_MARGIN;
        horizontalMargin = HORIZONTAL_MARGIN;
        cellSize = CELL_SIZE;
        waitLineSize = WAIT_LINE_SIZE;

    }

    private void initPaint() {
//        int markerTextSize = resolutionUtil.formatVertical(MARKER_TEXT_SIZE);
//        int cellTextSize = resolutionUtil.formatVertical(CELL_TEXT_SIZE);
        int markerTextSize = MARKER_TEXT_SIZE;
        int cellTextSize = CELL_TEXT_SIZE;

        paintWeekday = new Paint();
        paintWeekday.setAntiAlias(true);
        paintWeekday.setColor(COLOR_MARKER_WEEKDAY);
        paintWeekday.setTextSize(markerTextSize);
        paintWeekday.setTextAlign(Paint.Align.CENTER);

        paintWeekend = new Paint();
        paintWeekend.setAntiAlias(true);
        paintWeekend.setColor(COLOR_MARKER_WEEKEND);
        paintWeekend.setTextSize(markerTextSize);
        paintWeekend.setTextAlign(Paint.Align.CENTER);

        paintTextNormal = new Paint();
        paintTextNormal.setAntiAlias(true);
        paintTextNormal.setColor(COLOR_TEXT_NORMAL);
        paintTextNormal.setTextSize(cellTextSize);
        paintTextNormal.setTextAlign(Paint.Align.CENTER);

        paintTextHighlight = new Paint();
        paintTextHighlight.setAntiAlias(true);
        paintTextHighlight.setColor(COLOR_TEXT_HIGHLIGHT);
        paintTextHighlight.setTextSize(cellTextSize);
        paintTextHighlight.setTextAlign(Paint.Align.CENTER);

        paintBackgroundWait = new Paint();
        paintBackgroundWait.setAntiAlias(true);
        paintBackgroundWait.setColor(COLOR_BACKGROUND_WAIT);
        paintBackgroundWait.setStrokeWidth(2);
        paintBackgroundWait.setStyle(Paint.Style.STROKE);

        paintBackgroundNormal = new Paint();
        paintBackgroundNormal.setAntiAlias(true);
        paintBackgroundNormal.setColor(COLOR_BACKGROUND_NORMAL);
        paintBackgroundNormal.setStrokeWidth(2);
        paintBackgroundNormal.setStyle(Paint.Style.STROKE);

        paintBackgroundHighlight = new Paint();
        paintBackgroundHighlight.setAntiAlias(true);
        paintBackgroundHighlight.setStrokeWidth(2);
        paintBackgroundHighlight.setStyle(Paint.Style.FILL);
        //颜色
        //paintBackgroundHighlight.setColor(COLOR_BACKGROUND_HIGHLIGHT);
        //多种颜色数组
        //int[] colors = {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW,Color.MAGENTA};
        //float[] position = {0f, 0.2f, 0.4f, 0.6f, 1.0f};
        //Shader shader1 = new LinearGradient(100,850,600,850,colors,position,Shader.TileMode.CLAMP);
        //paintBackgroundHighlight.setShader(shader1);
        //设置背景图片
       /* Bitmap placeholder = BitmapFactory.decodeResource(getResources(), R.mipmap.small);
        Shader shader1 = new BitmapShader(placeholder, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        paintBackgroundHighlight.setShader(shader1);*/

    }

    private void initData() {
        Paint.FontMetricsInt fmiMarker = paintWeekday.getFontMetricsInt();
        deltaTextMarkerY = -(fmiMarker.bottom - fmiMarker.top) / 2 - fmiMarker.top;
        markerTextY = verticalMargin + cellSize / 2;

        Paint.FontMetricsInt fmiCell = paintTextNormal.getFontMetricsInt();
        deltaTextCellY = -(fmiCell.bottom - fmiCell.top) / 2 - fmiCell.top;
        verticalCellTop = verticalMargin + cellSize;

        Calendar calendarToday = Calendar.getInstance();
        dayOfMonthToday = calendarToday.get(Calendar.DAY_OF_MONTH);
        int dayOfWeek;
        sumDayOfMonth = calendarToday.getActualMaximum(Calendar.DAY_OF_MONTH);

        Calendar calendarFirstDay = Calendar.getInstance();
        calendarFirstDay.set(Calendar.DAY_OF_MONTH, 1);
        dayOfWeek = calendarFirstDay.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == Calendar.SUNDAY) {
            dayOfWeek = 7;
        } else {
            dayOfWeek = dayOfWeek - 1;
        }
        daysOfFirstWeek = MAX_COLUMN - dayOfWeek + 1;
    }

    private void createWaitBackground(int topX, int topY) {
        waitPath = new Path();
        waitPath.moveTo(topX, topY + waitLineSize);
        waitPath.lineTo(topX, topY);
        waitPath.lineTo(topX + waitLineSize, topY);

        waitPath.moveTo(topX + cellSize - waitLineSize, topY + cellSize);
        waitPath.lineTo(topX + cellSize, topY + cellSize);
        waitPath.lineTo(topX + cellSize, topY + cellSize - waitLineSize);

        waitRect = new Rect(topX, topY, topX + cellSize, topY + cellSize);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        horizontalSpace = (w - MAX_COLUMN * cellSize - horizontalMargin * 2) / (MAX_COLUMN - 1);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        drawWeekMark(canvas);
        drawCellsBackground(canvas);
        drawCells(canvas);
    }

    private void drawWeekMark(Canvas canvas) {
        int y = markerTextY + deltaTextMarkerY;
        for (int i = 0; i < 7; i++) {
            int x = horizontalMargin + i * (horizontalSpace + cellSize)
                    + cellSize / 2;
            if (i < 5) {
                canvas.drawText(WEEK_MARK[i], x, y, paintWeekday);
            } else {
                canvas.drawText(WEEK_MARK[i], x, y, paintWeekend);
            }
        }
    }

    private void drawCellsBackground(Canvas canvas) {
        for (int i = 1; i <= dayOfMonthToday; i++) {
            drawCellBackground(canvas, i, getColumnIndex(i), getRowIndex(i));
        }
    }

    /**
     * 根据行列序号绘制日期背景
     *
     * @param canvas     画布
     * @param dayOfMonth 日期
     * @param column     列序号
     * @param row        行序号
     */
    private void drawCellBackground(Canvas canvas, int dayOfMonth, int column, int row) {
        int x = horizontalMargin + column * (horizontalSpace + cellSize)
                + cellSize / 2;
        int y = verticalCellTop + verticalSpace * (row + 1) + cellSize * row + cellSize / 2;
        if (adapter != null) {
            DayType dayType = adapter.getType(dayOfMonth);
            switch (dayType) {
                case WAITING:
                    if (waitPath == null) {
                        createWaitBackground(x - cellSize / 2, y - cellSize / 2);
                    }
                    canvas.drawPath(waitPath, paintBackgroundWait);
                    break;
                case SIGNED:
                 //     canvas.drawCircle(x, y, cellSize/2, paintBackgroundHighlight);
                //  canvas.drawRect(x - 60, y - 60, x + 60, y + 60, paintBackgroundHighlight);// 正方形
                   // Bitmap placeholder = BitmapFactory.decodeResource(getResources(), R.mipmap.purtest);
                 //   canvas.drawBitmap(placeholder,);wCircle(x, y, cellSize/2, paintBackgroundHighlight);
                    canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.small3),x-40, y-40 , paintBackgroundHighlight);
                    break;
                default:
                    canvas.drawCircle(x, y, cellSize / 2, paintBackgroundNormal);
                    break;
            }
        } else {
            canvas.drawCircle(x, y, cellSize / 2, paintBackgroundNormal);
        }
    }

    private void drawCells(Canvas canvas) {
        for (int i = 1; i <= sumDayOfMonth; i++) {
            drawCell(canvas, i, getColumnIndex(i), getRowIndex(i));
        }
    }

    /**
     * 根据行列序号绘制日期
     *
     * @param canvas     画布
     * @param dayOfMonth 日期
     * @param column     列序号
     * @param row        行序号
     */
    private void drawCell(Canvas canvas, int dayOfMonth, int column, int row) {
        int x = horizontalMargin + column * (horizontalSpace + cellSize)
                + cellSize / 2;
        int y = verticalCellTop + verticalSpace * (row + 1) + cellSize * row + cellSize / 2
                + deltaTextCellY;
        if (adapter != null && dayOfMonth <= dayOfMonthToday) {
            DayType dayType = adapter.getType(dayOfMonth);
            Paint paint;
            switch (dayType) {
                case SIGNED:
                    paint = paintTextHighlight;
                    break;
                default:
                    paint = paintTextNormal;
                    break;
            }
            canvas.drawText(String.valueOf(dayOfMonth), x, y, paint);
        } else {
            canvas.drawText(String.valueOf(dayOfMonth), x, y, paintTextNormal);
        }
    }

    /**
     * 获取列序号
     *
     * @param dayOfMonth 日期
     * @return 列序号
     */
    private int getColumnIndex(int dayOfMonth) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == Calendar.SUNDAY) {
            dayOfWeek = 6;
        } else {
            dayOfWeek = dayOfWeek - 2;
        }
        return dayOfWeek;
    }

    /**
     * 获取行序号
     *
     * @param dayOfMonth 日期
     * @return 行序号
     */
    private int getRowIndex(int dayOfMonth) {
        float weight = (dayOfMonth - daysOfFirstWeek) / (MAX_COLUMN * 1f);
        double rowIndexDouble = Math.abs(Math.ceil(weight));
        return (int) rowIndexDouble;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            float x = event.getX();
            float y = event.getY();
            if (waitPath != null) {
                if (adapter.getType(dayOfMonthToday).equals(DayType.WAITING)) {
                    if (x >= waitRect.left && y >= waitRect.top && x <= waitRect.right && y <= waitRect.bottom) {
                        if (onTodayClickListener != null) {
                            onTodayClickListener.onTodayClick();
                        }
                    }
                }
            }
        }
        return true;
    }

    public void setAdapter(CalendarAdapter adapter) {
        this.adapter = adapter;
        this.invalidate();
    }

    public int getDayOfMonthToday() {
        return dayOfMonthToday;
    }

    public void notifyDataSetChanged() {
        invalidate();
    }

    private OnTodayClickListener onTodayClickListener;

    public void setOnTodayClickListener(OnTodayClickListener onTodayClickListener) {
        this.onTodayClickListener = onTodayClickListener;
    }

    public interface OnTodayClickListener {
        void onTodayClick();
    }

    public enum DayType {
        /**
         * 已签到状态,时间已过
         */
        SIGNED(0),
        /**
         * 未签到状态,时间已过
         */
        UNSIGNED(1),
        /**
         * 等待状态,即当日还未签到
         */
        WAITING(2),
        /**
         * 不可达到状态,未到时间
         */
        UNREACHABLE(3),
        /**
         * 不可用状态,非当前月份
         */
        DISABLED(4);

        private int value;

        DayType(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public static DayType valueOf(int value) {
            switch (value) {
                case 0:
                    return SIGNED;
                case 1:
                    return UNSIGNED;
                case 2:
                    return WAITING;
                case 3:
                    return UNREACHABLE;
                case 4:
                    return DISABLED;
                default:
                    return DISABLED;
            }
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android 百度地图定位实现仿钉钉签到打卡功能的完整代码

    导语 本章根据百度地图API,实现仿钉钉打卡功能.用到了基础地图.覆盖物.定位图层.陀螺仪方法.悬浮信息弹框. 百度地图API地址  :Android 地图SDK 请先注册注册百度账号和获取密钥,并实现地图显示出来.(注意:密钥.权限要设置) 另外,我得说明本章所下载官方Demo 和 导入的jar包和so文件.自定义下载即可,如下图: 接下来,一起看实现效果. 源码Git地址:BaiduMapApp 效果图 实现代码·三步骤 第一步:基础地图和方向传感器 类先实现方向传感器 implements

  • Android实现带签到赢积分功能的日历

    Android实现点击签到按钮直接签到,弹出dialog,先上效果图 demo是利用gridview实现的,现附上布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent&qu

  • Android积分签到上移消失动画效果

    还记得以前在某云的时候,有次需求是一个积分签到,要求点击签到按钮然后有一个动画效果,比如+30积分然后慢慢往上移动在消失.那会不会做就想着改下需求,直接去掉了动画效果,而今时隔很久又遇到同样的问题,比较蛋疼的是我清楚记得当时做过这个功能,但是自己没有做出来,当然现在做还是不会.自己当年省写的代码含泪也要补上.这次吸取教训,实现这个效果. 大致思路:动画部分,由一个垂直的平移和一个透明度变化的两个动画组成.然后通过AnimationSet将两个动画添加到集合,然后开始播放动画. 更新UI部分,用的

  • Android 实现钉钉自动打卡功能

    提前准备 首先我们需要一直不用的Android手机,插上公司的电源.下载安装钉钉并设置为极速打卡. 自动打开 我们只需要启动一个服务,定时打开钉钉应用后再返回即可. 防止熄屏 这华为手机并没有永不息屏的选项,所以我们需要设置一下防止自动息屏. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 设置不自动息屏 getWindow().setFla

  • Android简单实现app每月签到功能

    本文实例为大家分享了Android实现app每月签到功能的具体代码,供大家参考,具体内容如下 先上一张效果图: 其中这些签到的效果图是在网上找的,然后重要用到的控件就是 GridvVew 了, 代码很简单,只有3个代码文件: MainActivity.class 文件 package zhanghuan.cn.checkdesign; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import

  • Android可签到日历控件的实现方法

    最近在公司的功能需求中,需要实现可以签到的日历,签到后在签到过的日期做标志.本功能参考了网上一些大神的日历控件,在此基础上进行修改,已满足本公司的需求,现已完成,记录一下. 布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_wi

  • Android基于AccessibilityService制作的钉钉自动签到程序代码

    前两天公司开始宣布要使用阿里钉钉来签到啦!!!~~这就意味着,我必须老老实实每天按时签到上班下班了,这真是一个悲伤的消息,可是!!!!那么机智(lan)的我,怎么可能就这么屈服!!!阿里钉钉签到,说到底不就是手机软件签到吗?我就是干移动开发的,做一个小应用每天自动签到不就行了:) 说干就干,首先分析一下,阿里钉钉的签到流程: 打开阿里钉钉->广告页停留2S左右->进入主页->点击"工作"tab->点击"签到"模块->进入签到页面(可能会

  • Android自定义按周签到打卡功能实例代码

    前言 之前实现过<Android可签到的日历控件>的功能,跟这篇一样都是实现签到打卡功能,这篇实现的是按月进行打卡做标识,本篇内容实现的按周进行签到打卡. 实现签到规则如下: 1.连续签到7天,即可获得额外积分奖励. 2.连续签到记录在第8天开始时将清零重新计算. 3.如果中断签到,连续签到记录也将清零. 实现步骤: 1.效果图 2.自定义签到打卡View 3.主程序逻辑处理 4.主界面 5.签到bean 6.总结 实现过程: 1.效果图 2.自定义签到打卡View /** * descrip

  • Android自定义view实现日历打卡签到

    本文实例为大家分享了Android自定义view实现日历打卡签到的具体代码,供大家参考,具体内容如下 1.说明 自己写一个view实现每天签到的功能,设置背景图片 源码下载 2.效果图 3.主界面 package com.example.myapplication30; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.os.Bundle;

  • android自定义view之实现日历界面实例

    现在网上有很多自定义view实现日历的demo,今天讲一讲如何自己实现这个自定义view. 看一下最终效果图: 在这个自定义view中,我使用了各种奇技淫巧的方法来实现这个日历,真是费尽心思.废话少说,开始进坑. 界面分析 头部是一个textview,显示年份和月份,然后下边一行是星期几,这两行可以固定住,不随月份切换而进出屏幕. 再下边就是我们自定义view 的主角,每个月的天数.目前规定是星期日为每星期第一天.上个月的天数填充满第一行,下个月的前几天填充完最后一行,颜色设置为灰色,本月日期中

  • Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又称减幅振动.衰减振动.[1] 不论是弹簧振子还是单摆由于外界的摩擦和介质阻力总是存在,在振动过程中要不断克服外界阻力做功,消耗能量,振幅就会逐渐减小,经过一段时间,振动就会完全停下来.这种振幅随时间减小的振动称为阻尼振动.因为振幅与振动的能量有关,阻尼振动也就是能量不断减少的振动.阻尼振动是非简谐运

  • Android 自定义View 密码框实例代码

    暴露您view中所有影响可见外观的属性或者行为. •通过XML添加和设置样式 •通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 效果图展示: 支持的样式 可以通过XML定义影响外边和行为的属性如下 边框圆角值,边框颜色,分割线颜色,边框宽度,密码长度,密码大小,密码颜色 <declare-styleable name="PasswordInputView"> <attr name="borde

  • Android自定义View详解

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 [ 3.重写onMesure ] 4.重写onDraw 我把3用[]标出了,所以说3不一

  • Android自定义View中attrs.xml的实例详解

    Android自定义View中attrs.xml的实例详解 我们在自定义View的时候通常需要先完成attrs.xml文件 在values中定义一个attrs.xml 然后添加相关属性 这一篇先详细介绍一下attrs.xml的属性. <?xml version="1.0" encoding="utf-8"?> <resources> //自定义属性名,定义公共属性 <attr name="titleText" for

  • Android自定义View 仿QQ侧滑菜单的实现代码

    先看看QQ的侧滑效果 分析一下 先上原理图(不知道能否表达的清楚 ==) -首先这里使用了 Android 的HorizontalScrollView 水平滑动布局作为容器,当然我们需要继承它自定义一个侧滑视图 - 这个容器里面有一个父布局(一般用LinerLayout,本demo用的是),这个父布局里面有且只有两个子控件(布局),初始状态菜单页的位置在Y轴上存在偏移这样可以就可以形成主页叠在菜单页的上方的视觉效果:然后在滑动的过程程中 逐渐修正偏移,最后菜单页和主页并排排列.原理搞清了实现起来

  • Android自定义View绘制随机生成图片验证码

    本篇文章讲的是Android自定义View之随机生成图片验证码,开发中我们会经常需要随机生成图片验证码,但是这个是其次,主要还是想总结一些自定义View的开发过程以及一些需要注意的地方. 按照惯例先看看效果图: 一.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 3.重写onMesure 4.重写onDraw 其中onMesure方法不一定要重写,但大部分情况下还是需要重写的 二.View 的几个构造函数 1.public CustomV

  • Android自定义View绘制的方法及过程(二)

    上一篇<Android 自定义View(一) Paint.Rect.Canvas介绍>讲了最基础的如何自定义一个View,以及View用到的一些工具类.下面讲下View绘制的方法及过程 public class MyView extends View { private String TAG = "--------MyView"; private int width, height; public MyView(Context context, AttributeSet a

  • Android自定义View实现等级滑动条的实例

     Android自定义View实现等级滑动条的实例 实现效果图: 思路: 首先绘制直线,然后等分直线绘制点: 绘制点的时候把X值存到集合中. 然后绘制背景图片,以及图片上的数字. 点击事件down的时候,换小图片为大图片.move的时候跟随手指移动. up的时候根据此时的X计算最近的集合中的点,然后自动吸附回去. 1,自定义属性 <?xml version="1.0" encoding="utf-8"?> <resources> <de

随机推荐