Android自定义控件实现可多选课程日历CalendarView

可多选课程日历CalendarView的效果图

最新最全的 Android 开源项目合集 – Android –
掘金
awesome-github-android-ui
是由OpenDigg整理并维护的安卓UI相关开源项目库集合。我们会定期同步OpenDigg上的项目到这里,也欢迎各位提交项目给我们。
如果收录的项目有错…

图片 1

ImagePicker,Android 下的图片选择与裁剪 – Android –
掘金
img.png
项目地址:https://github.com/linchaolong/ImagePicker
ImagePi…

开发环境

2017 年初你绝对想尝试的 25 个新安卓库 – Android –
掘金
编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识、前端、后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过!
英文:25 New Android libraries which…

IDE版本:AndroidStudio2.0
物理机版本:Win7旗舰版(64位)

2017 年 1 月最火的五个 Android 开源项目 – Android –
掘金
原文地址(科学上网)Goodbye 2016, hello
2017!这是春节后的第一个工作周,大家还没从假期综合征中恢复过来吧。没关系,我们帮你搜集到一月份最好的5个Android类库,准备好花生、瓜子和饮料,来看看有什么吧!
1.C…

前言

人体诊断效果实现 – Android –
掘金
上两个版本健客医生项目新增一个症状自诊模块,用到了点击人体图获取相应部位从而关联相关症状,实现症状自诊功能。
之前觉得这个功能在以后的医疗app将会推广,于是将此如何实现开源出来,希望通过开源的力量能改善目前实现的方式。

最近的项目中用到了一个课程选择的日历View,于是在网上搜了搜自定义日历View,发现基本上都是单选的,不能够满足项目中的需求。于是自己重新造了个轮子,写了个可以被多选的自定义日历View。最后面会给出GitHub地址。

栗子——自定义EditText实现右下角计数控件 –
掘金
如果喜欢栗子系列可以关注哦~各种栗子正在赶来中…… 栗子惯例,先上GIF
栗子1.gif 栗子2.gif 核心代码(AnFQNumEditText自定义的组合控件)
先看调用(是不是很简单) xml <anfq.numedittext…

代码实现

笑谈 Android 图表 – MPAndroidChart – Android –
掘金
介绍 MPAndroidChart 图表使用常见问题…

package widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;

import com.arisaid.calendarview.R;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * Created by zhouyou on 2016/7/25.
 * Class desc:
 *
 * 自定义日历View,可多选
 */
public class CalendarView extends View {

  // 列的数量
  private static final int NUM_COLUMNS  =  7;
  // 行的数量
  private static final int NUM_ROWS    =  6;

  /**
   * 可选日期数据
   */
  private List<String> mOptionalDates;

  /**
   * 以选日期数据
   */
  private List<String> mSelectedDates = new ArrayList<>();

  // 背景颜色
  private int mBgColor = Color.parseColor("#F7F7F7");
  // 天数默认颜色
  private int mDayNormalColor = Color.parseColor("#0070F8");
  // 天数不可选颜色
  private int mDayNotOptColor = Color.parseColor("#CBCBCB");
  // 天数选择后颜色
  private int mDayPressedColor = Color.WHITE;
  // 天数字体大小
  private int mDayTextSize = 14;
  // 是否可以被点击状态
  private boolean mClickable = true;

  private DisplayMetrics mMetrics;
  private Paint mPaint;
  private int mCurYear;
  private int mCurMonth;
  private int mCurDate;

  private int mSelYear;
  private int mSelMonth;
  private int mSelDate;
  private int mColumnSize;
  private int mRowSize;
  private int[][] mDays;

  // 当月一共有多少天
  private int mMonthDays;
  // 当月第一天位于周几
  private int mWeekNumber;
  // 已选中背景Bitmap
  private Bitmap mBgOptBitmap;
  // 未选中背景Bitmap
  private Bitmap mBgNotOptBitmap;

  public CalendarView(Context context) {
    super(context);
    init();
  }

  public CalendarView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }

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

  private void init() {
    // 获取手机屏幕参数
    mMetrics = getResources().getDisplayMetrics();
    // 创建画笔
    mPaint = new Paint();
    // 获取当前日期
    Calendar calendar = Calendar.getInstance();
    mCurYear  =  calendar.get(Calendar.YEAR);
    mCurMonth  =  calendar.get(Calendar.MONTH);
    mCurDate  =  calendar.get(Calendar.DATE);
    setSelYTD(mCurYear, mCurMonth, mCurDate);

    // 获取背景Bitmap
    mBgOptBitmap  = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_bg_course_optional);
    mBgNotOptBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_bg_course_not_optional);
  }

  @Override
  public void invalidate() {
    // 避免程序过度绘制
    if(hasWindowFocus()) super.invalidate();
  }

  @Override
  protected void onDraw(Canvas canvas) {
    initSize();

    // 绘制背景
    mPaint.setColor(mBgColor);
    canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), mPaint);

    mDays = new int[6][7];
    // 设置绘制字体大小
    mPaint.setTextSize(mDayTextSize * mMetrics.scaledDensity);
    // 设置绘制字体颜色

    String dayStr;
    // 获取当月一共有多少天
    mMonthDays = DateUtils.getMonthDays(mSelYear, mSelMonth);
    // 获取当月第一天位于周几
    mWeekNumber = DateUtils.getFirstDayWeek(mSelYear, mSelMonth);

    for(int day = 0; day < mMonthDays; day++){
      dayStr = String.valueOf(day + 1);
      int column = (day + mWeekNumber - 1) % 7;
      int row   = (day + mWeekNumber - 1) / 7;
      mDays[row][column] = day + 1;
      int startX = (int) (mColumnSize * column + (mColumnSize - mPaint.measureText(dayStr)) / 2);
      int startY = (int) (mRowSize * row + mRowSize / 2 - (mPaint.ascent() + mPaint.descent()) / 2);

      // 判断当前天数是否可选
      if(mOptionalDates.contains(getSelData(mSelYear, mSelMonth, mDays[row][column]))){
        // 可选,继续判断是否是点击过的
        if(!mSelectedDates.contains(getSelData(mSelYear, mSelMonth, mDays[row][column]))){
          // 没有点击过,绘制默认背景
          canvas.drawBitmap(mBgNotOptBitmap, startX - 22, startY - 55, mPaint);
          mPaint.setColor(mDayNormalColor);
        }else{
          // 点击过,绘制点击过的背景
          canvas.drawBitmap(mBgOptBitmap, startX - 22, startY - 55, mPaint);
          mPaint.setColor(mDayPressedColor);
        }
        // 绘制天数
        canvas.drawText(dayStr, startX, startY - 10, mPaint);
      }else{
        mPaint.setColor(mDayNotOptColor);
        canvas.drawText(dayStr, startX, startY, mPaint);
      }
    }
  }

  private int downX = 0,downY = 0;

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    int eventCode = event.getAction();
    switch(eventCode){
      case MotionEvent.ACTION_DOWN:
        downX = (int) event.getX();
        downY = (int) event.getY();
        break;
      case MotionEvent.ACTION_MOVE:
        break;
      case MotionEvent.ACTION_UP:
        if(!mClickable) return true;

        int upX = (int) event.getX();
        int upY = (int) event.getY();
        if(Math.abs(upX - downX) < 10 && Math.abs(upY - downY) < 10){
          performClick();
          onClick((upX + downX) / 2, (upY + downY) / 2);
        }
        break;
    }
    return true;
  }

  /**
   * 点击事件
   */
  private void onClick(int x, int y){
    int row = y / mRowSize;
    int column = x / mColumnSize;
    setSelYTD(mSelYear, mSelMonth, mDays[row][column]);

    // 判断是否点击过
    boolean isSelected = mSelectedDates.contains(getSelData(mSelYear, mSelMonth, mSelDate));
    if(isSelected){
      mSelectedDates.remove(getSelData(mSelYear, mSelMonth, mSelDate));
    }else{
      mSelectedDates.add(getSelData(mSelYear, mSelMonth, mSelDate));
    }

    invalidate();
    if(mListener != null){
      // 执行回调
      mListener.onClickDateListener(mSelYear, (mSelMonth + 1), mSelDate);
    }
  }

  /**
   * 初始化列宽和高
   */
  private void initSize() {
    // 初始化每列的大小
    mColumnSize = getWidth() / NUM_COLUMNS;
    // 初始化每行的大小
    mRowSize = getHeight() / NUM_ROWS;
  }

  /**
   * 设置可选择日期
   * @param dates 日期数据
   */
  public void setOptionalDate(List<String> dates){
    this.mOptionalDates = dates;
  }

  /**
   * 设置年月日
   * @param year 年
   * @param month 月
   * @param date 日
   */
  public void setSelYTD(int year, int month, int date){
    this.mSelYear  =  year;
    this.mSelMonth =  month;
    this.mSelDate  =  date;
  }

  /**
   * 设置上一个月日历
   */
  public void setLastMonth(){
    int year  =  mSelYear;
    int month  =  mSelMonth;
    int day   =  mSelDate;
    // 如果是1月份,则变成12月份
    if(month == 0){
      year = mSelYear-1;
      month = 11;
    }else if(DateUtils.getMonthDays(year, month) == day){
      // 如果当前日期为该月最后一点,当向前推的时候,就需要改变选中的日期
      month = month-1;
      day = DateUtils.getMonthDays(year, month);
    }else{
      month = month-1;
    }
    setSelYTD(year,month,day);
    invalidate();
  }

  /**
   * 设置下一个日历
   */
  public void setNextMonth(){
    int year  =  mSelYear;
    int month  =  mSelMonth;
    int day   =  mSelDate;
    // 如果是12月份,则变成1月份
    if(month == 11){
      year = mSelYear+1;
      month = 0;
    }else if(DateUtils.getMonthDays(year, month) == day){
      // 如果当前日期为该月最后一点,当向前推的时候,就需要改变选中的日期
      month = month + 1;
      day = DateUtils.getMonthDays(year, month);
    }else{
      month = month + 1;
    }
    setSelYTD(year,month,day);
    invalidate();
  }

  /**
   * 获取当前展示的年和月份
   * @return 格式:2016-06
   */
  public String getDate(){
    String data;
    if((mSelMonth + 1) < 10){
      data = mSelYear + "-0" + (mSelMonth + 1);
    }else{
      data = mSelYear + "-" + (mSelMonth + 1);
    }
    return data;
  }

  /**
   * 获取当前展示的日期
   * @return 格式:20160606
   */
  private String getSelData(int year, int month, int date){
    String monty, day;
    month = (month + 1);

    // 判断月份是否有非0情况
    if((month) < 10) {
      monty = "0" + month;
    }else{
      monty = String.valueOf(month);
    }

    // 判断天数是否有非0情况
    if((date) < 10){
      day = "0" + (date);
    }else{
      day = String.valueOf(date);
    }
    return year + monty + day;
  }

  /**
   * 获取已选日期数据
   */
  public List<String> getSelectedDates(){
    return mSelectedDates;
  }

  /**
   * 设置已选日期数据
   */
  public void setSelectedDates(List<String> dates){
    this.mSelectedDates = dates;
  }

  /**
   * 设置日历是否可以点击
   */
  @Override
  public void setClickable(boolean clickable) {
    this.mClickable = clickable;
  }

  private OnClickListener mListener;

  public interface OnClickListener{
    void onClickDateListener(int year, int month, int day);
  }

  /**
   * 设置点击回调
   */
  public void setOnClickDate(OnClickListener listener){
    this.mListener = listener;
  }

  @Override
  protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    recyclerBitmap(mBgOptBitmap);
    recyclerBitmap(mBgNotOptBitmap);
  }

  /**
   * 释放Bitmap资源
   */
  private void recyclerBitmap(Bitmap bitmap) {
    if(bitmap != null && !bitmap.isRecycled()){
      bitmap.recycle();
    }
  }
}

Android、Web 开源项目分类整理 – Android –
掘金
分类整理平时收集的项目,便于查找。 Android 架构 Mosby A
Model-View-Presenter library for modern Android apps.
AndroidArchitectureCollection go…

使用步骤

史上最轻量级的新手引导库 – Android –
掘金
这是一款轻量级的新手引导库,能够快速为任何一个 View
创建一个遮罩层,支持单个页面,多个引导提示,支持为高亮区域设置不同的图形,支持圆形、椭圆形、矩形高亮形状,方便扩展。
废话不多说,有图有真相:项目地址HighLightGuideView device…

1、初始化自定义日历View:

炫酷的日历和 ListView 结合的开源控件,收藏一下,说不定哪天就能用上… –
Android –
掘金
A custom ListView combine with CalendarView which interactive each
other. just watch demo to get more detail. Demo Apk Downlo…

CalendarView mCalendarView = (CalendarView)
findViewById(R.id.calendarView);

几种常见 Dialog,直接拿去用!懒人必收 – Android –
掘金
前言
项目中经常使用到的几种Dialog,所以干脆封装起来了,方便以后使用,顺便分享给大家,话不多说,直接看效果。
样式一 NormalSelectionDialog 使用如下代码: NormalSelectionDialog
dialog…

2、初始化可以被选择的天数数据:

Android 自定义 view 实现波浪动画进度条 – Android –
掘金
最近在做项目时需要实现这样一种动画,类似于波浪形的进度动画,粗略的看了一下,发现好像类似于正余弦曲线实现的,但是Android
没有相关的API,所以需要我们动手画出来,所以现在在此记录一下学习过程,方便总结、学习。
效果图 代码地址 关于实现的具体…

List<String> mDatas = new ArrayList<>();
mDatas.add("20160801");
mDatas.add("20160802");
mDatas.add("20160803");
mDatas.add("20160816");
mDatas.add("20160817");
mDatas.add("20160826");
mDatas.add("20160910");
mDatas.add("20160911");
mDatas.add("20160912");

Android 自定义 ClearEditTextView – Android –
掘金
ClearEditTextView通过扩展EditText,添加了右边清除按钮、输入数据不合法时可左右抖动的功能。效果如下:
模拟登录 …

3、设置给自定义日历View:

探索日期滚轮控件的源码 –
掘金
欢迎Follow我的GitHub, 关注我的掘金. 在较高版本的Android SDK中,
已经修改默认的日期选择控件, 由滚轮样式变为日历样式. 对于出生日期的选择,
为了美观, 也为了便捷, 滚轮控件更有优势,
因此需要编写自定义的时间滚轮控件. 随手记…

// 设置可选日期
mCalendarView.setOptionalDate(mDatas);

漂亮的菜单弹出控件 BoomMenu – Android –
掘金
2.0.0 Comes Finally Approximately 8 months ago, I got an inspiration to
creating something that can boom and show menu, which I n…

设置点击监听

这交互炸了:饿了么是怎么让Image变成详情页的 –
掘金
晚上叫外卖,打开饿了么,发现推了一个版本,更新以后,点开了个鸡腿,哇,交互炫炸了。
本文同步自wing的地方酒馆
不过还是有槽点。我是无意中才发现可以左右滑动的。这。。。你不告诉我,我怎么知道左右可以滑。
https://github.com/githubwi…

mCalendarView.setOnClickDate(new CalendarView.OnClickListener() {
  @Override
  public void onClickDateListener(int year, int month, int day) {
    Toast.makeText(getApplication(), year + "年" + month + "月" + day + "天", Toast.LENGTH_SHORT).show();

    // 获取已选择日期
    List<String> dates = mCalendarView.getSelectedDates();
    for (String date : dates) {
      Log.e("test", "date: " + date);
    }

  }
});

年终福利 – 一款实用的图片控件 SImageView(第一弹) – Android –
掘金
一年快要过去了, 你的目标实现了么? 不管实现没有,
先来个小目标吧.比如造一个轮子? 说点题外话.
Coding中我们总是经历着这么几个过程. 学会使用: 不管是API也好, 开源库也好.
总是在最开始的学会去用. 了解实现原理: 可能会因为一些不兼容…

如果只需要进行数据展示,而不需要点击,可以设置:

直接拿去用!每个App都会用到的LoadingLayout –
掘金
前言
项目里都会遇到几种页面,分别为加载中、无网络、无数据、出错四种情况,经常要使用,所以封成库引用了,方便使用,顺便分享出来。先看一下效果:
原理比较简单,继承FrameLayout,在xml渲染完成后,加上加载中、无网络、无数据、出错四个页面,根据需要控制…

// 设置已选日期
mCalendarView.setSelectedDates(mDatas);
// 设置不可以被点击
mCalendarView.setClickable(false);

AndroidIOS 风格底部选择器(支持时间,日期,自定义) – Android –
掘金
先上图吧:
这是笔者最近一个项目一直再用的一个选择器库,自己也在其中做了修改,并决定持续维护下去。
先看使用方法: 日期选择: private void
showDateDialog(List<integer> date) { …

源码下载:

Android 自定义价格日历控件 – Android –
掘金
介绍
上个星期项目有一个日历价格的需求,类似一个商品在不同的日期价格可能会不同,由于时间给得特别紧所以打算找个合适的开源项目进行修改。参考了网上大多数是通过继承view直接draw一个monthView,然后通过listview来实现monthView的复用…

GitHub地址: 欢迎star~!

自定义 View 之 GradualView 文字渐变-颜色渐变-图像渐变 – Android –
掘金
话不多说上个动图解释框架的内容: 项目地址:
https://github.com/AndroidMsky/GradualView
记得在笔者X菱电梯的时候,有个需求,大概就是电梯开门,让一个白色的文字渐渐的变成蓝色并且展开,大概的意思就电梯到了几楼…

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

【Android 自定义 View 实战】之自定义评价打分控件
RatingBar,可以自定义星星大小和间距 – Android –
掘金
版权声明:本文为博主原创文章,未经博主允许不得转载。
在Android开发中,我们经常会用到对商家或者商品的评价,运用星星进行打分。然而在Android系统中自带的打分控件,Rati…

您可能感兴趣的文章:

  • Android可签到日历控件的实现方法
  • Android自定义日历滑动控件
  • Android
    一个日历控件的实现代码
  • Android实现自定义日历
  • android
    开发教程之日历项目实践(一)
  • java制作android
    日历代码分享
  • Android自定义日历控件实例详解
  • Android实现日历控件示例代码
  • Android自定义日历Calender代码实现
  • Android实现带签到赢积分功能的日历

Android 开源相册 TelegramGallery – Android –
掘金
今天给大家介绍的是一个相册的开源框架,很强悍,借官网的话说就是:快速,高效,低耗相册选择器,抽取自Telegram,支持单选,多选,预览,缩放,滑动取消预览,QQ选择特性,如果你正要开发相册功能,或者图片查看器等功能,绝对不要错过
https://…

Leave a Comment.