国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android自定義控件實(shí)現(xiàn)可多選課程日歷CalendarView

2019-12-12 02:51:10
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

可多選課程日歷CalendarView的效果圖

開發(fā)環(huán)境

IDE版本:AndroidStudio2.0
物理機(jī)版本:Win7旗艦版(64位)

前言

最近的項(xiàng)目中用到了一個(gè)課程選擇的日歷View,于是在網(wǎng)上搜了搜自定義日歷View,發(fā)現(xiàn)基本上都是單選的,不能夠滿足項(xiàng)目中的需求。于是自己重新造了個(gè)輪子,寫了個(gè)可以被多選的自定義日歷View。最后面會(huì)給出GitHub地址。

代碼實(shí)現(xiàn)

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 {  // 列的數(shù)量  private static final int NUM_COLUMNS  =  7;  // 行的數(shù)量  private static final int NUM_ROWS    =  6;  /**   * 可選日期數(shù)據(jù)   */  private List<String> mOptionalDates;  /**   * 以選日期數(shù)據(jù)   */  private List<String> mSelectedDates = new ArrayList<>();  // 背景顏色  private int mBgColor = Color.parseColor("#F7F7F7");  // 天數(shù)默認(rèn)顏色  private int mDayNormalColor = Color.parseColor("#0070F8");  // 天數(shù)不可選顏色  private int mDayNotOptColor = Color.parseColor("#CBCBCB");  // 天數(shù)選擇后顏色  private int mDayPressedColor = Color.WHITE;  // 天數(shù)字體大小  private int mDayTextSize = 14;  // 是否可以被點(diǎn)擊狀態(tài)  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;  // 當(dāng)月一共有多少天  private int mMonthDays;  // 當(dāng)月第一天位于周幾  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() {    // 獲取手機(jī)屏幕參數(shù)    mMetrics = getResources().getDisplayMetrics();    // 創(chuàng)建畫筆    mPaint = new Paint();    // 獲取當(dāng)前日期    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];    // 設(shè)置繪制字體大小    mPaint.setTextSize(mDayTextSize * mMetrics.scaledDensity);    // 設(shè)置繪制字體顏色    String dayStr;    // 獲取當(dāng)月一共有多少天    mMonthDays = DateUtils.getMonthDays(mSelYear, mSelMonth);    // 獲取當(dāng)月第一天位于周幾    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);      // 判斷當(dāng)前天數(shù)是否可選      if(mOptionalDates.contains(getSelData(mSelYear, mSelMonth, mDays[row][column]))){        // 可選,繼續(xù)判斷是否是點(diǎn)擊過的        if(!mSelectedDates.contains(getSelData(mSelYear, mSelMonth, mDays[row][column]))){          // 沒有點(diǎn)擊過,繪制默認(rèn)背景          canvas.drawBitmap(mBgNotOptBitmap, startX - 22, startY - 55, mPaint);          mPaint.setColor(mDayNormalColor);        }else{          // 點(diǎn)擊過,繪制點(diǎn)擊過的背景          canvas.drawBitmap(mBgOptBitmap, startX - 22, startY - 55, mPaint);          mPaint.setColor(mDayPressedColor);        }        // 繪制天數(shù)        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;  }  /**   * 點(diǎn)擊事件   */  private void onClick(int x, int y){    int row = y / mRowSize;    int column = x / mColumnSize;    setSelYTD(mSelYear, mSelMonth, mDays[row][column]);    // 判斷是否點(diǎn)擊過    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){      // 執(zhí)行回調(diào)      mListener.onClickDateListener(mSelYear, (mSelMonth + 1), mSelDate);    }  }  /**   * 初始化列寬和高   */  private void initSize() {    // 初始化每列的大小    mColumnSize = getWidth() / NUM_COLUMNS;    // 初始化每行的大小    mRowSize = getHeight() / NUM_ROWS;  }  /**   * 設(shè)置可選擇日期   * @param dates 日期數(shù)據(jù)   */  public void setOptionalDate(List<String> dates){    this.mOptionalDates = dates;  }  /**   * 設(shè)置年月日   * @param year 年   * @param month 月   * @param date 日   */  public void setSelYTD(int year, int month, int date){    this.mSelYear  =  year;    this.mSelMonth =  month;    this.mSelDate  =  date;  }  /**   * 設(shè)置上一個(gè)月日歷   */  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){      // 如果當(dāng)前日期為該月最后一點(diǎn),當(dāng)向前推的時(shí)候,就需要改變選中的日期      month = month-1;      day = DateUtils.getMonthDays(year, month);    }else{      month = month-1;    }    setSelYTD(year,month,day);    invalidate();  }  /**   * 設(shè)置下一個(gè)日歷   */  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){      // 如果當(dāng)前日期為該月最后一點(diǎn),當(dāng)向前推的時(shí)候,就需要改變選中的日期      month = month + 1;      day = DateUtils.getMonthDays(year, month);    }else{      month = month + 1;    }    setSelYTD(year,month,day);    invalidate();  }  /**   * 獲取當(dāng)前展示的年和月份   * @return 格式:2016-06   */  public String getDate(){    String data;    if((mSelMonth + 1) < 10){      data = mSelYear + "-0" + (mSelMonth + 1);    }else{      data = mSelYear + "-" + (mSelMonth + 1);    }    return data;  }  /**   * 獲取當(dāng)前展示的日期   * @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);    }    // 判斷天數(shù)是否有非0情況    if((date) < 10){      day = "0" + (date);    }else{      day = String.valueOf(date);    }    return year + monty + day;  }  /**   * 獲取已選日期數(shù)據(jù)   */  public List<String> getSelectedDates(){    return mSelectedDates;  }  /**   * 設(shè)置已選日期數(shù)據(jù)   */  public void setSelectedDates(List<String> dates){    this.mSelectedDates = dates;  }  /**   * 設(shè)置日歷是否可以點(diǎn)擊   */  @Override  public void setClickable(boolean clickable) {    this.mClickable = clickable;  }  private OnClickListener mListener;  public interface OnClickListener{    void onClickDateListener(int year, int month, int day);  }  /**   * 設(shè)置點(diǎn)擊回調(diào)   */  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();    }  }}

使用步驟

1、初始化自定義日歷View:

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

2、初始化可以被選擇的天數(shù)數(shù)據(jù):

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");

3、設(shè)置給自定義日歷View:

// 設(shè)置可選日期mCalendarView.setOptionalDate(mDatas);

設(shè)置點(diǎn)擊監(jiān)聽

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);    }  }});

如果只需要進(jìn)行數(shù)據(jù)展示,而不需要點(diǎn)擊,可以設(shè)置:

// 設(shè)置已選日期mCalendarView.setSelectedDates(mDatas);// 設(shè)置不可以被點(diǎn)擊mCalendarView.setClickable(false);

源碼下載:

GitHub地址:https://github.com/Airsaid/CalendarView 歡迎star~!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 安国市| 赤峰市| 鲁山县| 涟水县| 故城县| 金沙县| 葫芦岛市| 安阳市| 乐昌市| 西畴县| 永仁县| 宣武区| 临西县| 江川县| 小金县| 樟树市| 江陵县| 泰州市| 五原县| 荥阳市| 凤翔县| 锡林浩特市| 寿宁县| 临桂县| 武清区| 罗城| 静海县| 论坛| 迭部县| 孟村| 哈巴河县| 大名县| 莎车县| 腾冲县| 繁昌县| 大厂| 亚东县| 儋州市| 井冈山市| 金沙县| 平原县|