Android 사용자 정의 컨트롤 로 다 중 선택 가능 한 과정 달력 CalendarView 구현
12950 단어 Android일력CalendarView
개발 환경
IDE 버 전:Android Studio 2.0
물리 기기 버 전:Win 7 플래그 십 버 전(64 비트)
머리말
최근 프로젝트 에 서 는 한 과정 에서 선택 한 달력 View 를 사 용 했 습 니 다.그래서 인터넷 에서 사용자 정의 달력 View 를 검색 한 결과 대체적으로 단일 선택 으로 프로젝트 의 수 요 를 만족 시 키 지 못 했 습 니 다.그래서 스스로 바퀴 를 다시 만 들 고 선택 할 수 있 는 사용자 정의 달력 View 를 썼 습 니 다.맨 뒤에 GitHub 주소 가 나 옵 니 다.
코드 구현
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();
}
}
}
사용 절차1.사용자 정의 달력 보기 초기 화:
CalendarView mCalendarView = (CalendarView) findViewById(R.id.calendarView);
2.선택 할 수 있 는 일수 데이터 초기 화:
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.사용자 정의 달력 View 에 설정:
//
mCalendarView.setOptionalDate(mDatas);
설정 클릭 감청
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);
}
}
});
클릭 하지 않 고 데이터 전시 만 하면 설정 할 수 있 습 니 다.
//
mCalendarView.setSelectedDates(mDatas);
//
mCalendarView.setClickable(false);
원본 다운로드:GitHub 주소:https://github.com/Airsaid/CalendarView환영 스타~!
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.