一、闪退问题解决办法
在build.gradle(module:app)中的defaultConfig中加上
ndk {
abiFilters "armeabi-v7a"
}
二、CalendarView的使用
1、内容:a.标记日期,b.获取点击日期,c.设置月、年变化监听器,d.用RecyclerView的适配器绑定数据和视图
2.demo
三、实现步骤
1.首先在build.gradle(moudle.app)的dependencies中加入
implementation 'com.haibin:calendarview:3.6.9'
2.画图(即画一个自己想要的日历)
新建一个MeiZuMonthView的类继承MonthView;(用来显示月视图)
新建一个MeiZuWeekView的类继承WeekView;(用来显示周视图)
在onDrawSelected、onDrawScheme、onDrawText 这三个方法中分别画“选中后的样子”,“标记日期的样子”,“文字的样子”。
月视图:
package com.example.meetyou.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.example.meetyou.R;
import com.haibin.calendarview.Calendar;
import com.haibin.calendarview.MonthView;
public class MeiZuMonthView extends MonthView {
private Paint mTextPaint = new Paint();
/**
* 自定义魅族标记的圆形背景
*/
private Paint mSchemeBasicPaint = new Paint();
private float mRadius;
private float mRadio;
private int mPadding;
private float mSchemeBaseLine;
public MeiZuMonthView(Context context) {
super(context);
mTextPaint.setTextSize(dipToPx(context, 8));
mTextPaint.setColor(0xffffffff);
mTextPaint.setAntiAlias(true);
mTextPaint.setFakeBoldText(true);
mSchemeBasicPaint.setAntiAlias(true);
mSchemeBasicPaint.setStyle(Paint.Style.FILL);
mSchemeBasicPaint.setTextAlign(Paint.Align.CENTER);
mSchemeBasicPaint.setFakeBoldText(true);
mRadio = dipToPx(getContext(), 7);
mPadding = dipToPx(getContext(), 4);
Paint.FontMetrics metrics = mSchemeBasicPaint.getFontMetrics();
mSchemeBaseLine = mRadio - metrics.descent + (metrics.bottom - metrics.top) / 2 + dipToPx(getContext(), 1);
}
@Override
protected void onPreviewHook() {
mRadius = Math.min(mItemWidth,mItemHeight) / 5 * 2 ;
}
@Override
protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme) {
int cx = x + mItemWidth / 2;
int cy = y + mItemHeight / 2;
mSelectedPaint.setStyle(Paint.Style.FILL);
mSelectedPaint.setColor(getResources().getColor(R.color.colorSkin));
canvas.drawCircle(cx, cy ,
mRadius, mSelectedPaint);
return true;
}
@Override
protected void onDrawScheme(Canvas canvas, Calendar calendar, int x, int y) {
mSchemeBasicPaint.setColor(calendar.getSchemeColor());
canvas.drawCircle(x + mItemWidth - mPadding - mRadio / 2, y + mPadding + mRadio, mRadio, mSchemeBasicPaint);
canvas.drawText(calendar.getScheme(),
x + mItemWidth - mPadding - mRadio / 2 - getTextWidth(calendar.getScheme()) / 2,
y + mPadding + mSchemeBaseLine, mTextPaint);
}
private float getTextWidth(String text) {
return mTextPaint.measureText(text);
}
@Override
protected void onDrawText(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme, boolean isSelected) {
int cx = x + mItemWidth / 2;
int top = y - mItemHeight / 6;
boolean isInRange = isInRange(calendar);
if (isSelected) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
mSelectTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mSelectedLunarTextPaint);
} else if (hasScheme) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentMonth() && isInRange ? mSchemeTextPaint : mOtherMonthTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mCurMonthLunarTextPaint);
} else {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :
calendar.isCurrentMonth() && isInRange ? mCurMonthTextPaint : mOtherMonthTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10,
calendar.isCurrentDay() && isInRange ? mCurDayLunarTextPaint :
calendar.isCurrentMonth() ? mCurMonthLunarTextPaint : mOtherMonthLunarTextPaint);
}
}
private static int dipToPx(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
周视图
package com.example.meetyou.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.example.meetyou.R;
import com.haibin.calendarview.Calendar;
import com.haibin.calendarview.WeekView;
public class MeiZuWeekView extends WeekView {
private int mRadius;
public MeiZuWeekView(Context context) {
super(context);
}
@Override
protected void onPreviewHook() {
mRadius = Math.min(mItemWidth,mItemHeight) / 5 * 2;
}
@Override
protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, boolean hasScheme) {
int cx = x + mItemWidth / 2;
int cy = mItemHeight / 2;
mSelectedPaint.setStyle(Paint.Style.FILL);
mSelectedPaint.setColor(getResources().getColor(R.color.colorSkin));
canvas.drawCircle(cx,cy,mRadius,mSelectedPaint);
return true;
}
@Override
protected void onDrawScheme(Canvas canvas, Calendar calendar, int x) {
int cx = x + mItemWidth / 2;
int cy = mItemHeight / 2;
canvas.drawCircle(cx, cy, mRadius, mSchemePaint);
}
@Override
protected void onDrawText(Canvas canvas, Calendar calendar, int x, boolean hasScheme, boolean isSelected) {
int cx = x + mItemWidth / 2;
int top = - mItemHeight / 8;
if (hasScheme) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :
calendar.isCurrentMonth() ? mSchemeTextPaint : mSchemeTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10, mCurMonthLunarTextPaint);
} else {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :
calendar.isCurrentMonth() ? mCurMonthTextPaint : mCurMonthTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10, mCurMonthLunarTextPaint);
}
}
}
3.布局文件:fragment_calendar.xml
因为放了周视图所以得放一个CalendarLayout的控件,这样可以支持周视图和月视图的切换。
重点:
app:month_view="com.example.meetyou.widget.MeiZuMonthView"
app:week_view="com.example.meetyou.widget.MeiZuWeekView"
这两行就是用到了刚刚我们画的日历,写如那两个View的路径就好
路径如下:
整个布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_current_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/rectangle_solid_circle"
android:text="6"
android:textSize="20sp"
android:layout_marginTop="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"/>
<TextView
android:id="@+id/tv_month_day"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="month_day"/>
<TextView
android:id="@+id/tv_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="year"/>
<TextView
android:id="@+id/tv_current_day"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="currentday"/>
</LinearLayout>
<com.haibin.calendarview.CalendarLayout
android:id="@+id/calendar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:padding="10dp"
android:background="@drawable/rectangle_circle"
android:orientation="vertical"
app:default_status="expand"
app:calendar_show_mode="both_month_week_view"
app:calendar_content_view_id="@+id/recyclerView">
<com.haibin.calendarview.CalendarView
android:id="@+id/calendarView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rectangle_circle"
android:layout_marginBottom="5dp"
app:month_view="com.example.meetyou.widget.MeiZuMonthView"
app:week_view="com.example.meetyou.widget.MeiZuWeekView"
app:week_line_background="@color/colorDeepPink"
app:calendar_height="40dp"
app:current_month_text_color="@color/black"
app:min_year="2004"
app:scheme_text=""
app:scheme_text_color="@color/colorLightGreen"
app:scheme_theme_color="#333"
app:selected_text_color="#fff"
app:selected_theme_color="#333"
app:select_mode="range_mode"
app:week_background="@color/colorSkin"
app:month_view_show_mode="mode_only_current"
app:week_text_color="#111"
app:current_day_text_color="@color/colorGreen"
app:current_day_lunar_text_color="@color/colorGreen"
/>
<TextView
android:id="@+id/show_type_guide"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shopping_mall"
android:paddingLeft="20dp"
android:layout_marginBottom="5dp"
android:background="@drawable/rectangle_circle"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#d4d4d4" />
</com.haibin.calendarview.CalendarLayout>
</LinearLayout>
日历的基本显示完成了,接下来就是,标记日期的显示,以及点击日期的获取。
标记日期:
//需要用到可变map
val map= mutableMapOf<String,Calendar>();
map[getSchemaCalendar(mTodayYear,mTodayMonth,3, resources.getColor(R.color.colorYellow),"卵").toString()] =
getSchemaCalendar(mTodayYear,mTodayMonth,3, resources.getColor(R.color.colorYellow),"卵");
calendarView.setSchemeDate(map);
private fun getSchemaCalendar (year: Int, month: Int,
day: Int, color: Int, text: String): Calendar{
val calendar : Calendar = Calendar()
calendar.year = year;
calendar.month = month;
calendar.day = day;
calendar.schemeColor = color;
calendar.scheme = text;
calendar.addScheme(Calendar.Scheme());
return calendar;
}
点击获取日期:
@SuppressLint("SetTextI18n", "WrongConstant")
override fun onCalendarSelect(calendar: Calendar?, isClick: Boolean) {
tv_month_day.visibility = View.VISIBLE
tv_current_month.text = calendar!!.month.toString() + "月"
tv_month_day.text = calendar!!.month.toString() + "月" + calendar.day + "日"
tv_year.text = calendar.year.toString();
mYear = calendar.year
}
监听日期选中,年的变化,月的变化对应做出动作:
先implements:
class CalendarFragment : SimpleFragment(), View.OnClickListener,
CalendarView.OnCalendarSelectListener,CalendarView.OnYearChangeListener,CalendarView.OnMonthChangeListener
然后声明:
calendarView.setOnCalendarSelectListener(this)
calendarView.setOnYearChangeListener (this)
calendarView.setOnMonthChangeListener(this)
具体实现:
@SuppressLint("SetTextI18n", "WrongConstant")
override fun onCalendarSelect(calendar: Calendar?, isClick: Boolean) {
tv_month_day.visibility = View.VISIBLE
tv_current_month.text = calendar!!.month.toString() + "月"
tv_month_day.text = calendar!!.month.toString() + "月" + calendar.day + "日"
tv_year.text = calendar.year.toString();
mYear = calendar.year
}
override fun onYearChange(year: Int) {
tv_year.text = year.toString();
}
override fun onMonthChange(year: Int, month: Int) {
tv_current_month.text = month.toString()+"月";
tv_month_day.visibility = View.GONE;
}