慣例:先上圖後說話,謝謝各位夥伴的支援! 有你們是我的福分!

每日一言:猶豫一千次不如實踐一次。
你将學到以下知識點:
繼承系統控件
組合系統控件
自定義繪制
添加Attribute
添加事件
-------------代碼來啦---------
一.自定義 NewCalender 月曆
public class NewCalendar extends LinearLayout {
private ImageView iv_left;
private ImageView iv_Right;
private TextView tv_Date;
private GridView gridView;
private Calendar curDate = Calendar.getInstance();
private String displayFormat;
public NewCalendarListener calendarListener;
public NewCalendar(Context context) {
super(context);
}
public NewCalendar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initControl(context, attrs);
}
public NewCalendar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initControl(context, attrs);
}
private void initControl(Context context, AttributeSet attr) {
bindControl(context);
bindControlEvent();
TypedArray ta = getContext().obtainStyledAttributes(attr, R.styleable.NewCalendar);
try {
String format = ta.getString(R.styleable.NewCalendar_dateFormat);
displayFormat = format;
if (displayFormat == null) {
displayFormat = "MMM yyyy";
}
} finally {
ta.recycle();
}
renderCalendar();
}
/**
* 初始化控件
*
* @param context
*/
private void bindControl(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.calendar_view, this);
iv_left = (ImageView) findViewById(R.id.btnPre);
iv_Right = (ImageView) findViewById(R.id.btnNext);
tv_Date = (TextView) findViewById(R.id.txtData);
gridView = (GridView) findViewById(R.id.calendar_grid);
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
if (calendarListener == null) {
return false;
} else {
calendarListener.onItemLongPress((Date) adapterView.getItemAtPosition(i));
return true;
}
}
});
}
/**
* 綁定事件
*/
private void bindControlEvent() {
iv_left.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
curDate.add(Calendar.MONTH, -1);
renderCalendar();
}
});
iv_Right.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
curDate.add(Calendar.MONTH, +1);
renderCalendar();
}
});
}
/**
* 渲染月曆
*/
private void renderCalendar() {
//格式化日期
SimpleDateFormat sdf = new SimpleDateFormat(displayFormat);
tv_Date.setText(sdf.format(curDate.getTime()));
//總共多少個cell
ArrayList<Date> cells = new ArrayList<>();
//月曆克隆
Calendar calendar = (Calendar) curDate.clone();
calendar.set(Calendar.DAY_OF_MONTH, 1);
int preDays = calendar.get(Calendar.DAY_OF_WEEK) - 1;
calendar.add(Calendar.DAY_OF_MONTH, -preDays);
int maxCellCount = 6 * 7;
while (cells.size() < maxCellCount) {
cells.add(calendar.getTime());
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
gridView.setAdapter(new CalendarAdapter(getContext(), cells));
}
/**
* 月曆顯示擴充卡
*/
private class CalendarAdapter extends ArrayAdapter {
LayoutInflater inflate;
public CalendarAdapter(@NonNull Context context, ArrayList<Date> days) {
super(context, R.layout.calendar_text_day, days);
inflate = LayoutInflater.from(context);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Date date = (Date) getItem(position);
if (convertView == null) {
convertView = inflate.inflate(R.layout.calendar_text_day, parent, false);
}
int day = date.getDate();
((Calendar_day_textView) convertView).setText(String.valueOf(day));
//是否是當月
Date now = new Date();
boolean isTheSameMonth = false;
if (now.getMonth() == date.getMonth()) {
isTheSameMonth = true;
}
if (isTheSameMonth) {
((Calendar_day_textView) convertView).setTextColor(Color.parseColor("#000000"));
} else {
((Calendar_day_textView) convertView).setTextColor(Color.parseColor("#666666"));
}
if (now.getDate() == date.getDate() && now.getMonth() == date.getMonth() && now.getYear() == date.getYear()) {
((Calendar_day_textView) convertView).setTextColor(Color.parseColor("#ff0000"));
((Calendar_day_textView) convertView).isToday = true;
}
return convertView;
}
}
public interface NewCalendarListener {
void onItemLongPress(Date date);
}
}
二.自定義每個日期的控件 Calendar_day_textView
public class Calendar_day_textView extends AppCompatTextView {
//是否是今天
public boolean isToday = false;
private Paint paint = new Paint();
public Calendar_day_textView(Context context) {
super(context);
}
public Calendar_day_textView(Context context, AttributeSet attrs) {
super(context, attrs);
initControl();
}
public Calendar_day_textView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initControl();
}
/**
* 除使用畫筆
*/
private void initControl() {
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.parseColor("#ff0000"));
paint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isToday) {
canvas.translate(getWidth() / 2, getHeight() / 2);
canvas.drawCircle(0, 0, getWidth() / 2, paint);
}
}
}
三.自定義布局需要顯示的地方
<com.example.jiaxufei.firstgitproject.NewCalendar
android:id="@+id/new_calendar"
xmlns:NewCalendarNS="http://schemas.android.com/apk/res/com.example.jiaxufei.firstgitproject"
android:layout_width="match_parent"
android:layout_height="match_parent"
NewCalendarNS:dateFormat="yyyy MMMM"></com.example.jiaxufei.firstgitproject.NewCalendar>
四.月曆檔案xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="30dp">
<ImageView
android:id="@+id/btnPre"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:src="@mipmap/jiantouleft" />
<ImageView
android:id="@+id/btnNext"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:src="@mipmap/jiantouright" />
<TextView
android:id="@+id/txtData"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/btnNext"
android:layout_toRightOf="@id/btnPre"
android:gravity="center"
android:text=" Jun 2017" />
</RelativeLayout>
<LinearLayout
android:layout_marginTop="15dp"
android:id="@+id/calendar_week_header"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:text="星期日" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:text="星期一" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:text="星期二" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:text="星期三" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:text="星期四" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:text="星期五" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:text="星期六" />
</LinearLayout>
<GridView
android:id="@+id/calendar_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="7"></GridView>
</LinearLayout>
五.自定義的月曆item
<?xml version="1.0" encoding="utf-8"?>
<com.example.jiaxufei.firstgitproject.Calendar_day_textView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="30dp"
android:id="@+id/tv_calendar_day"
android:textSize="20dp"
android:gravity="center"
android:layout_height="30dp"/>
六.用到的attrs檔案
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="NewCalendar">
<attr name="dateFormat" format="string" />
</declare-styleable>
</resources>
歡迎大家一起讨論學習。QQ:732258496。 Android 技術QQ群:478720016