日历控件
来源:互联网 发布:超级指南针软件 编辑:程序博客网 时间:2024/05/17 09:12
用了两种方式实现日历控件
先来看看效果图
第一种就是用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; }}
0 0
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- 日历控件
- oracle中sql语句的优化
- 第四周项目4:用递归方法求解
- 魅族手机listview适配问题
- hdu 2566统计硬币
- jbd 之 handle
- 日历控件
- tomcat server.xml配置
- 冲激函数的深度问题
- 十个利用矩阵乘法解决的经典题目
- 解决No module named _sqlite3的问题
- POJ3111 K Best(二分 最大化平均值)
- 关于c#的webbrows控件自动填写表单并获取提交后的网页内容
- 小游戏
- eclipse安装SVN插件