您的位置:首页 > 其它

日历控件

2016-03-28 19:56 387 查看
用了两种方式实现日历控件

先来看看效果图



第一种就是用gridview简单点

class CalendarAdapter extends BaseAdapter {

AbsListView.LayoutParams params;
Context context;
Calendar today;
Calendar calendar;
List<String> list;
int select = -1;

public CalendarAdapter(Context context, int year, int month) {
this.context = context;
int width = context.getResources().getDisplayMetrics().widthPixels;
params = new AbsListView.LayoutParams(-1, width / 7);//让每个块的高度等于屏幕宽的1/7,宽度就自动平分了
today = Calendar.getInstance();//今天日期
calendar = Calendar.getInstance();
calendar.set(year, month - 1, 1);//这月的一号
int sc = calendar.get(Calendar.DAY_OF_WEEK);//一号是周几
list = new ArrayList<String>();
for (int i = 0; i < sc - 1; i++) {
list.add("");
}//然后把一号前的数据都设为空串
int count = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
for (int i = 0; i < count; i++) {
list.add(i + 1 + "");
}
}

private long getTime(int position) {
return getCalendar(position).getTimeInMillis();
}

//获取点击的日期
private Calendar getCalendar(int position) {
int day = Integer.valueOf(getItem(position));
calendar.set(Calendar.DAY_OF_MONTH, day);
return calendar;
}

//判断是今天前,今天还是今天以后
private int isToday(int position) {
if (getTime(position) > today.getTimeInMillis()) {
return 1;
} else if (getTime(position) < today.getTimeInMillis()) {
return -1;
} else {
return 0;
}
}

private void select(int position) {
this.select = position;
notifyDataSetChanged();
}

public int getCount() {
if (list == null) {
return 0;
}
return list.size();
}

public String getItem(int position) {
return list.get(position);
}

public long getItemId(int position) {
return position;
}
//是不是周末
private boolean isWeekday(int position) {
if (position % 7 == 0 || position % 7 == 6) {
return true;
}
return false;
}

public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
textView.setGravity(Gravity.CENTER);
textView.setText(list.get(position));
textView.setTextSize(18);
textView.setLayoutParams(params);
if (list.get(position).equals("")) {
return textView;
}
if (isToday(position) < 0) {
textView.setTextColor(0xff999999);
} else {
if (isToday(position) == 0) {
textView.setTextColor(0xff333333);
textView.setText("今天");
} else {
textView.setTextColor(0xff666666);
}
if (isWeekday(position)) {
textView.setTextColor(0xffffa417);
}
if (select == position) {
textView.setTextColor(0xffffffff);
textView.setBackgroundResource(R.drawable.circle_blue_bg);
}
}
return textView;
}

}


然后就写item点击事件选择日期等。

不过感觉这样写逼格不够高,就直接继承view画一个月历

private int year;
private int month;
private Calendar calendar;
private Calendar today;
private List<Position> list;

private Paint paint;
private int width;
private float perWidth;//每块的宽高

private int textSize = 30;
private int textColor = 0xff000000;
private int textColorSelect = 0xffffffff;
private int selectRectColor = 0xff04ade5;
private int weekendTextColor = 0xffffa417;

private float touchSlop;//手指移动距离小于这个判定它触发点击事件
private float startX = 0;
private float startY = 0;
private double distance = 0;//手指移动距离
private Position selectPosition; //选中的位置
private OnDayClickListener onDayClickListener;//日点击事件

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

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

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

private void init() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setTextSize(textSize);
calendar = Calendar.getInstance();
today = Calendar.getInstance();
touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}

public void setData(int year, int month) {
LogUtil.i(year + "-" + month);
this.year = year;
this.month = month;
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);//本月一共多少天
if (list == null) {
list = new ArrayList<>();
} else {
list.clear();
}
for (int i = 1; i <= maxDay; i++) {
calendar.set(Calendar.DAY_OF_MONTH, i);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);//当天是周几
int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);//是第几周
list.add(new Position(dayOfWeek - 1, weekOfMonth + 1, i, dayOfWeek, calendar.getTimeInMillis()));//position记录每天是第几行第几列,是几号,还有具体时间,第0行放了日期,第一行放了周,所以weekOfMonth+1
}
}

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = textSize * 20;//wrap时计算一个大致的宽度
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
calendar.set(Calendar.DAY_OF_MONTH, maxDay);//计算最后一天是本月的第几周,就知道一共该有多少行,来计算高度
int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
height = width / 7 * (weekOfMonth + 2);//多加两行显示日期和周
}
perWidth = width * 1.0f / 7;
setMeasuredDimension(width, height);
}

protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawDate(canvas);
drawWeek(canvas);
drawSelect(canvas);
drawDay(canvas);
selectPosition = null;
}

//第一行画xxxx年xx月
private void drawDate(Canvas canvas) {
paint.setColor(textColor);
String time = TimeUtil.getFormatTime(calendar.getTime(), "yyyy-MM");
float x = width / 2 - paint.measureText(time) / 2;
float y = perWidth * 0.5f - (paint.ascent() + paint.descent()) / 2;
canvas.drawText(time, x, y, paint);
}

private void drawWeek(Canvas canvas) {
String[] weeks = new String[]{"日", "一", "二", "三", "四", "五", "六"};
paint.setColor(textColor);
float x, y;
for (int i = 0; i < weeks.length; i++) {
x = perWidth * (i + 0.5f) - paint.measureText(weeks[i]) / 2;
y = perWidth * 1.5f - (paint.ascent() + paint.descent()) / 2;
canvas.drawText(weeks[i], x, y, paint);
}
}

//画天
private void drawDay(Canvas canvas) {
float x, y;
String string;
for (Position position : list) {
paint.setColor(textColor);
if (selectPosition != null && position.time == selectPosition.time) {
paint.setColor(textColorSelect);//选中那天换个颜色
}
if (position.week == 1 || position.week == 7) {
paint.setColor(weekendTextColor);//周末变色
}
string = String.valueOf(position.time);
if (position.time == today.getTimeInMillis()) {
string = "今天";
}
x = perWidth * (position.x + 0.5f) - paint.measureText(string) / 2;
y = perWidth * (position.y + 0.5f) - (paint.ascent() + paint.descent()) / 2;
canvas.drawText(string, x, y, paint);
}
}

//选中的块画了个背景圆
private void drawSelect(Canvas canvas) {
if (selectPosition == null) {
return;
}
int x = selectPosition.x;
int y = selectPosition.y;
RectF rect = new RectF((x + 0.3f) * perWidth, (y + 0.3f) * perWidth, (x + 0.7f) * perWidth, (y + 0.7f) * perWidth);
paint.setColor(selectRectColor);
canvas.drawRoundRect(rect, perWidth / 2, perWidth / 2, paint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();//手势起始位置
int x = (int) (startX / perWidth);
int y = (int) (startY / perWidth);
selectPosition = getValue(x, y);
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (selectPosition != null) {
distance = Math.sqrt((event.getX() - startX) * (event.getX() - startX) + (event.getY() - startY) * (event.getY() - startY));//手指移动距离
if (distance < touchSlop) {
LogUtil.i(year + "-" + month + "-" + selectPosition.day);
if (onDayClickListener != null) {
onDayClickListener.onClick(year, month, selectPosition.day);//回调监听
}
invalidate();
}
distance = 0;
}
break;
}
return true;
}

//触摸在了哪块
private Position getValue(int x, int y) {
for (Position position :
list) {
if (position.x == x && position.y == y) {
return position;
}
}
return null;
}

public void setOnDayClickListener(OnDayClickListener onDayClickListener) {
this.onDayClickListener = onDayClickListener;
}

public interface OnDayClickListener {
void onClick(int year, int month, int day);
}

private class Position {
int x;
int y;
int day;
int week;
long time;

public Position(int x, int y, int day, int week, long tiem) {
this.x = x;
this.y = y;
this.day = day;
this.week = week;
this.time = time;
}
}


画完一个月后放在viewpager里就可以了

public OnDayClickListener onDayClickListener;
private int currentYear;
private int currentMonth;
//日历的范围
private int minDateYear = 1900;
private int minDateMonth = 1;
private int maxDateYear = 2100;
private int maxDateMonth = 12;

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

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

private void init() {
Calendar now = Calendar.getInstance();
currentYear = now.get(Calendar.YEAR);
currentMonth = now.get(Calendar.MONTH) + 1;
setAdapter(new CalendarAdapter());
setCurrent(currentYear,currentMonth);//默认设置为当前月
}

//计算xxxx年 xx 月是在第几个位置并设置
public void setCurrent(int year,int month){
int p = year * 12 + month - minDateYear * 12 - minDateMonth;
setCurrentItem(p);
}
//设置年月范围
public void setRange(Calendar minDate, Calendar maxDate) {
if (maxDate.getTimeInMillis() < minDate.getTimeInMillis()) {
return;
}
this.minDateYear = minDate.get(Calendar.YEAR);
this.minDateMonth = minDate.get(Calendar.MONTH) + 1;
this.maxDateYear = maxDate.get(Calendar.YEAR);
this.maxDateMonth = maxDate.get(Calendar.MONTH) + 1;
}

public void setOnDayClickListener(OnDayClickListener onDayClickListener) {
this.onDayClickListener = onDayClickListener;
}
//某天的点击事件
public interface OnDayClickListener {
void onClick(int year, int month, int day);
}

class CalendarAdapter extends PagerAdapter {

private RItemCalendarView.OnDayClickListener onItemClickListener = new RItemCalendarView.OnDayClickListener() {
@Override
public void onClick(int year, int month, int day) {
if (onDayClickListener != null) {
onDayClickListener.onClick(year, month, day);
}
}
};

@Override
public int getCount() {
return maxDateYear * 12 + maxDateMonth - minDateYear * 12 - minDateMonth + 1;
}

@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
RItemCalendarView view = new RItemCalendarView(getContext());
view.setData(getYear(position), getMonth(position));
view.setOnDayClickListener(onItemClickListener);
container.addView(view);
return view;
}
//第position个位置是哪年
private int getYear(int position) {
int t = minDateYear * 12 + minDateMonth + position;
if (t % 12 == 0) {
return t / 12 - 1;
}
return t / 12;
}
//第position个位置是几月
private int getMonth(int position) {
int t = minDateMonth + position;
if (t % 12 == 0) {
return 12;
}
return t % 12;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: