Merge pull request ' 添加日历的控制类和视图类并在MainActivity中调用' (#10) from p86231950/ShowMe:master into master
commit
67117366ba
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="16" />
|
||||
<bytecodeTargetLevel target="11" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,152 @@
|
||||
package com.idealist.calendarview;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
@CoordinatorLayout.DefaultBehavior(CalendarPagerBehavior.class)
|
||||
public class CalendarPager extends ViewPager {
|
||||
|
||||
private CalendarAttr attr;
|
||||
|
||||
private OnPageChangeListener mOnPageChangeListener;
|
||||
|
||||
public static int CURRENT_DAY_INDEX = 1000;
|
||||
|
||||
private int mCurrPosition = CURRENT_DAY_INDEX;
|
||||
|
||||
private int pageScrollState = ViewPager.SCROLL_STATE_IDLE;
|
||||
|
||||
public CalendarPager(Context context) {
|
||||
super(context, null);
|
||||
}
|
||||
|
||||
public CalendarPager(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initPager();
|
||||
}
|
||||
|
||||
private void initPager() {
|
||||
ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
mCurrPosition = position;
|
||||
if (mOnPageChangeListener != null) {
|
||||
CalendarViewAdapter adapter = (CalendarViewAdapter) getAdapter();
|
||||
assert adapter != null;
|
||||
adapter.updateViewByScrollHorizontally(position);
|
||||
mOnPageChangeListener.onPageSelected(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
pageScrollState = state;
|
||||
}
|
||||
};
|
||||
addOnPageChangeListener(pageChangeListener);
|
||||
}
|
||||
|
||||
public void setAttr(CalendarAttr attr) {
|
||||
this.attr = attr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdapter(@Nullable PagerAdapter adapter) {
|
||||
super.setAdapter(adapter);
|
||||
setCurrentItem(1000);
|
||||
mCurrPosition = 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (attr != null && attr.getCalendarType() == State.VIEW_FULL) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
return;
|
||||
}
|
||||
int height = 0xffffff;
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
View child = getChildAt(i);
|
||||
child.measure(widthMeasureSpec,
|
||||
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
|
||||
int h = child.getMeasuredHeight();
|
||||
height = Math.min(h, height);
|
||||
}
|
||||
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
public void setmOnPageChangeListener(OnPageChangeListener mOnPageChangeListener) {
|
||||
this.mOnPageChangeListener = mOnPageChangeListener;
|
||||
}
|
||||
|
||||
public void selectOtherMonth(int offset) {
|
||||
CalendarViewAdapter adapter = (CalendarViewAdapter) getAdapter();
|
||||
adapter.saveSelectedDate();
|
||||
adapter.updateDayInViewState(mCurrPosition + offset);
|
||||
setCurrentItem(mCurrPosition + offset);
|
||||
}
|
||||
|
||||
public int getViewHeight() {
|
||||
return attr.getViewHeight();
|
||||
}
|
||||
|
||||
public int getItemHeight() {
|
||||
return attr.getItemHeight();
|
||||
}
|
||||
|
||||
public int getScrollLevel() {
|
||||
return attr.getScrollLevel();
|
||||
}
|
||||
|
||||
public void setScrollLevel(int scrollLevel) {
|
||||
attr.setScrollLevel(scrollLevel);
|
||||
}
|
||||
|
||||
public int getPageScrollState() {
|
||||
return pageScrollState;
|
||||
}
|
||||
|
||||
public void setPageScrollState(int pageScrollState) {
|
||||
this.pageScrollState = pageScrollState;
|
||||
}
|
||||
|
||||
public CalendarAttr getAttr() {
|
||||
return attr;
|
||||
}
|
||||
|
||||
public int getmCurrPosition() {
|
||||
return mCurrPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 月视图到周视图可向上滑动距离距离
|
||||
*a
|
||||
* @return 距离
|
||||
*/
|
||||
public int getTopMovableDistance() {
|
||||
CalendarViewAdapter adapter = (CalendarViewAdapter) getAdapter();
|
||||
assert adapter != null;
|
||||
return attr.getItemHeight() * (CalendarUtils.getWeekOfMonth(adapter.getSelectDay()) - 1);
|
||||
}
|
||||
|
||||
public interface OnPageChangeListener {
|
||||
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
|
||||
|
||||
void onPageSelected(int position);
|
||||
|
||||
void onPageScrollStateChanged(int state);
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package com.idealist.calendarview;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import static android.content.ContentValues.TAG;
|
||||
|
||||
public class CalendarPagerBehavior extends CoordinatorLayout.Behavior<CalendarPager> {
|
||||
private int mTop = 0;
|
||||
private int touchSlop = 1;
|
||||
|
||||
@Override
|
||||
public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull CalendarPager child, @NonNull View dependency) {
|
||||
return dependency instanceof RecyclerView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLayoutChild(@NonNull CoordinatorLayout parent, @NonNull CalendarPager child, int layoutDirection) {
|
||||
parent.onLayoutChild(child, layoutDirection);
|
||||
child.offsetTopAndBottom(mTop);
|
||||
return true;
|
||||
}
|
||||
|
||||
private int confirm = 0;
|
||||
private float downX, downY, lastY, lastTop;
|
||||
private boolean isVerticalScroll;
|
||||
private boolean directionUpa;
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(@NonNull CoordinatorLayout parent, @NonNull CalendarPager child, @NonNull MotionEvent ev) {
|
||||
if (downY > lastTop) {
|
||||
return false;
|
||||
}
|
||||
Log.i(TAG, "onTouchEvent: onTouchEvent");
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (isVerticalScroll) {
|
||||
directionUpa = ev.getY() < lastY;
|
||||
if (child.getScrollLevel() == State.LEVEL_TOP) {
|
||||
CalendarAttr.setRecTop(State.DEFAULT_ITEM_HEIGHT + (int) (ev.getY() - downY));
|
||||
CalendarUtils.scroll(parent.getChildAt(1), (int) (lastY - ev.getY()),
|
||||
State.DEFAULT_ITEM_HEIGHT, State.DEFAULT_ITEM_HEIGHT * 6);
|
||||
} else if (child.getScrollLevel() == State.LEVEL_MEDIUM) {
|
||||
CalendarAttr.setRecTop(State.DEFAULT_ITEM_HEIGHT * 6 + (int) (ev.getY() - downY));
|
||||
if (directionUpa) {
|
||||
CalendarUtils.scroll(parent.getChildAt(1), (int) (lastY - ev.getY()),
|
||||
State.DEFAULT_ITEM_HEIGHT, State.DEFAULT_ITEM_HEIGHT * 6);
|
||||
} else {
|
||||
CalendarUtils.scroll(parent.getChildAt(1), (int) (lastY - ev.getY()),
|
||||
State.DEFAULT_ITEM_HEIGHT * 6, State.DEFAULT_ITEM_HEIGHT_FULL * 6);
|
||||
}
|
||||
} else {
|
||||
CalendarAttr.setRecTop(child.getViewHeight() + (int) (ev.getY() - downY));
|
||||
CalendarUtils.scroll(parent.getChildAt(1), (int) (lastY - ev.getY()),
|
||||
State.DEFAULT_ITEM_HEIGHT * 6, State.DEFAULT_ITEM_HEIGHT_FULL * 6);
|
||||
}
|
||||
lastY = ev.getY();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (isVerticalScroll) {
|
||||
CalendarViewAdapter adapter = (CalendarViewAdapter) child.getAdapter();
|
||||
if (adapter != null) {
|
||||
if (directionUpa) {
|
||||
if (adapter.getCalendarType() == State.VIEW_MONTH) {
|
||||
child.setScrollLevel(State.LEVEL_TOP);
|
||||
adapter.changeCalendarType(State.VIEW_WEEK);
|
||||
CalendarUtils.scrollTo(parent, (RecyclerView) parent.getChildAt(1),
|
||||
State.DEFAULT_ITEM_HEIGHT, 300);
|
||||
} else if (adapter.getCalendarType() == State.VIEW_FULL) {
|
||||
child.setScrollLevel(State.LEVEL_MEDIUM);
|
||||
adapter.changeCalendarType(State.VIEW_MONTH);
|
||||
CalendarUtils.scrollTo(parent, (RecyclerView) parent.getChildAt(1),
|
||||
State.DEFAULT_ITEM_HEIGHT * 6, 300);
|
||||
}
|
||||
} else {
|
||||
if (adapter.getCalendarType() == State.VIEW_WEEK) {
|
||||
child.setScrollLevel(State.LEVEL_MEDIUM);
|
||||
adapter.changeCalendarType(State.VIEW_MONTH);
|
||||
CalendarUtils.scrollTo(parent, (RecyclerView) parent.getChildAt(1),
|
||||
State.DEFAULT_ITEM_HEIGHT * 6, 300);
|
||||
} else if (adapter.getCalendarType() == State.VIEW_MONTH) {
|
||||
child.setScrollLevel(State.LEVEL_BOTTOM);
|
||||
adapter.changeCalendarType(State.VIEW_FULL);
|
||||
CalendarUtils.scrollTo(parent, (RecyclerView) parent.getChildAt(1),
|
||||
State.DEFAULT_ITEM_HEIGHT_FULL * 6, 300);
|
||||
}
|
||||
}
|
||||
}
|
||||
isVerticalScroll = false;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
isVerticalScroll = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(@NonNull CoordinatorLayout parent, @NonNull CalendarPager child, @NonNull MotionEvent ev) {
|
||||
Log.i(TAG, "onInterceptTouchEvent: Try to intercept!" + isVerticalScroll);
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
downX = ev.getX();
|
||||
downY = ev.getY();
|
||||
lastTop = CalendarAttr.getRecTop();
|
||||
lastY = downY;
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (downY > lastTop) {
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(ev.getY() - downY) > 25 && Math.abs(ev.getX() - downX) <= 25 && !isVerticalScroll) {
|
||||
isVerticalScroll = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (isVerticalScroll) {
|
||||
isVerticalScroll = false;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return isVerticalScroll;
|
||||
}
|
||||
|
||||
private int dependencyViewTop = -1;
|
||||
|
||||
@Override
|
||||
public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull CalendarPager child, @NonNull View dependency) {
|
||||
Log.i(TAG, "onDependentViewChanged: !");
|
||||
CalendarViewAdapter adapter = (CalendarViewAdapter) child.getAdapter();
|
||||
|
||||
if (dependencyViewTop != -1) {
|
||||
int dy = dependency.getTop() - dependencyViewTop;
|
||||
int top = child.getTop();
|
||||
|
||||
if (dy > touchSlop) {
|
||||
assert adapter != null;
|
||||
adapter.changeCalendarType(State.VIEW_MONTH);
|
||||
} else if (dy < -touchSlop) {
|
||||
assert adapter != null;
|
||||
adapter.changeCalendarType(State.VIEW_WEEK);
|
||||
}
|
||||
|
||||
if (dy > -top)
|
||||
dy = -top;
|
||||
|
||||
if (dy < -top - child.getTopMovableDistance()) {
|
||||
dy = -top - child.getTopMovableDistance();
|
||||
}
|
||||
|
||||
child.offsetTopAndBottom(dy);
|
||||
// adapter.changeCalendarType(State.VIEW_WEEK);
|
||||
}
|
||||
|
||||
if (dependencyViewTop > child.getItemHeight() - 24
|
||||
&& dependencyViewTop < child.getItemHeight() + 24
|
||||
&& mTop > -touchSlop - child.getTopMovableDistance()
|
||||
&& mTop < touchSlop - child.getTopMovableDistance()) {
|
||||
child.setScrollLevel(State.LEVEL_TOP);
|
||||
adapter.changeCalendarType(State.VIEW_WEEK);
|
||||
}
|
||||
if (dependencyViewTop > child.getViewHeight() - 24
|
||||
&& dependencyViewTop < child.getViewHeight() + 24
|
||||
&& mTop < touchSlop
|
||||
&& mTop > -touchSlop) {
|
||||
child.setScrollLevel(State.LEVEL_MEDIUM);
|
||||
adapter.changeCalendarType(State.VIEW_MONTH);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,272 @@
|
||||
package com.idealist.calendarview;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.idealist.calendarview.interf.OnSelectDateListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CalendarView extends View implements View.OnLongClickListener {
|
||||
|
||||
private CalendarViewAdapter adapter;
|
||||
|
||||
private CalendarAttr attr;
|
||||
|
||||
private int mItemHeight;
|
||||
|
||||
private int mItemWidth;
|
||||
|
||||
private int mViewHeight;
|
||||
|
||||
private int mBaseLine;
|
||||
|
||||
private boolean isClick;
|
||||
|
||||
private boolean isScroll;
|
||||
|
||||
private int mTextSize;
|
||||
|
||||
private int mCurrItem;
|
||||
|
||||
private int mRowCount;
|
||||
|
||||
MotionEvent event;
|
||||
|
||||
/**
|
||||
* 点击坐标
|
||||
*/
|
||||
private float mX, mY;
|
||||
|
||||
private List<CalendarDay> items = new ArrayList<>();
|
||||
|
||||
private CalendarDay seedDay;
|
||||
|
||||
private OnSelectDateListener onSelectDateListener;
|
||||
|
||||
private OnCalendarClickListener clickListener;
|
||||
|
||||
public CalendarView(Context context,
|
||||
CalendarAttr attr,
|
||||
CalendarViewAdapter adapter,
|
||||
OnSelectDateListener onSelectDateListener,
|
||||
OnCalendarClickListener clickListener) {
|
||||
super(context);
|
||||
this.attr = attr;
|
||||
this.adapter = adapter;
|
||||
this.clickListener = clickListener;
|
||||
this.onSelectDateListener = onSelectDateListener;
|
||||
this.setOnLongClickListener(this);
|
||||
initView();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 View
|
||||
*/
|
||||
private void initView() {
|
||||
mRowCount = attr.getRowCount();
|
||||
mViewHeight = attr.getViewHeight();
|
||||
mItemHeight = attr.getItemHeight();
|
||||
mTextSize = attr.getTextSize();
|
||||
mBaseLine = (int) (mTextSize + mItemHeight) / 2;
|
||||
mCurrItem = CalendarUtils.getIndexOfCurrDay(State.VIEW_MONTH);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 为对应视图生成对应日历项, 以SeedDay为对应
|
||||
*/
|
||||
final int generateItem() {
|
||||
if (attr.getCalendarType() != State.VIEW_WEEK)
|
||||
items = CalendarUtils.generateItemForMonthView(seedDay.getYear(), seedDay.getMonth());
|
||||
else
|
||||
items = CalendarUtils.generateItemForWeekView(seedDay.getYear(), seedDay.getMonth(), seedDay.getDay());
|
||||
return items.indexOf(seedDay);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当视图变化时变化 UI
|
||||
*/
|
||||
public void changeViewType() {
|
||||
if (attr.getCalendarType() == State.VIEW_FULL) {
|
||||
attr.setItemHeight(State.DEFAULT_ITEM_HEIGHT_FULL);
|
||||
} else {
|
||||
attr.setItemHeight(State.DEFAULT_ITEM_HEIGHT);
|
||||
}
|
||||
mItemHeight = attr.getItemHeight();
|
||||
mViewHeight = attr.getViewHeight();
|
||||
setViewHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
mCurrItem = generateItem();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void updateView() {
|
||||
mCurrItem = generateItem();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
public CalendarDay getSeedDay() {
|
||||
return seedDay;
|
||||
}
|
||||
|
||||
public void setSeedDay(CalendarDay seedDay) {
|
||||
this.seedDay = seedDay;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (attr.getCalendarType() != State.VIEW_FULL) {
|
||||
setMeasuredDimension(widthMeasureSpec, mViewHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float touchX = event.getX();
|
||||
float touchY = event.getY();
|
||||
int action = event.getAction();
|
||||
float disX, disY;
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mX = touchX;
|
||||
mY = touchY;
|
||||
isClick = true;
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
disX = touchX - mX;
|
||||
disY = touchY - mY;
|
||||
if (Math.abs(disX) > 2 * mItemWidth || Math.abs(disY) > 2 * mItemHeight) {
|
||||
isScroll = true;
|
||||
}
|
||||
isClick = false;
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (isClick) {
|
||||
items.get(mCurrItem).setSelectState(State.DAY_UN_SELECT);
|
||||
mCurrItem = getIndexOnView();
|
||||
adapter.setSelectDay(items.get(mCurrItem));
|
||||
if (items.get(mCurrItem).getMonthState() != State.DAY_CURR_MONTH) {
|
||||
items.get(mCurrItem).setSelectState(State.DAY_UN_SELECT);
|
||||
onSelectDateListener.onSelectOtherMonth(items.get(mCurrItem).getMonthState());
|
||||
mCurrItem = 0;
|
||||
} else {
|
||||
items.get(mCurrItem).setSelectState(State.DAY_SELECT);
|
||||
}
|
||||
if (adapter.getSelectDay().isMarkSchedule()) {
|
||||
clickListener.OnClick(adapter.getSelectDay());
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public List<CalendarDay> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<CalendarDay> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public void setmCurrItem(int mCurrItem) {
|
||||
this.mCurrItem = mCurrItem;
|
||||
}
|
||||
|
||||
private int getIndexOnView() {
|
||||
int indexX = (int) mX / mItemWidth;
|
||||
int indexY = (int) mY / mItemHeight;
|
||||
int position = -1;
|
||||
if (isClick) {
|
||||
if (indexX > 6) indexX = 6;
|
||||
position = 7 * indexY + indexX;
|
||||
}
|
||||
if (position > 41)
|
||||
position = 41;
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
mItemWidth = getWidth() / 7;
|
||||
mItemHeight = attr.getItemHeight();
|
||||
mRowCount = attr.getRowCount();
|
||||
mBaseLine = (int) (mTextSize * 1.5);
|
||||
int sW = mItemWidth / 2;
|
||||
int sH = mBaseLine;
|
||||
for (int i = 0; i < mRowCount; ++i) {
|
||||
for (int j = 0; j < 7; ++j) {
|
||||
draw(canvas, items.get(7 * i + j), sW + mItemWidth * j, sH + mItemHeight * i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void draw(Canvas canvas, CalendarDay day, int x, int y) {
|
||||
onDrawText(canvas, day, x, y);
|
||||
onDrawMark(canvas, day, x, y);
|
||||
}
|
||||
|
||||
private void onDrawText(Canvas canvas, CalendarDay day, int x, int y) {
|
||||
Paint paint = new Paint();
|
||||
paint.setTextSize(mTextSize);
|
||||
paint.setColor(Color.GRAY);
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
// Log.e("View", day.toString());
|
||||
if (day.isCurrDay()) {
|
||||
paint.setColor(Color.BLUE);
|
||||
} else if (day.getSelectState() == State.DAY_SELECT) {
|
||||
paint.setColor(Color.GREEN);
|
||||
} else if (day.getMonthState() == State.DAY_CURR_MONTH) {
|
||||
paint.setColor(Color.BLACK);
|
||||
}
|
||||
canvas.drawText(Integer.toString(day.getDay()), x, y, paint);
|
||||
}
|
||||
|
||||
private void onDrawMark(Canvas canvas, CalendarDay day, int x, int y) {
|
||||
if (day.isMarkSchedule()) {
|
||||
Paint paint = new Paint();
|
||||
paint.setColor(Color.BLUE);
|
||||
canvas.drawCircle(x, y+20, 10, paint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置 View 高度
|
||||
*
|
||||
* @param height 高度
|
||||
*/
|
||||
private void setViewHeight(int height) {
|
||||
Log.e(null, "setViewHeight");
|
||||
ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) this.getLayoutParams();
|
||||
params.height = height;
|
||||
this.setLayoutParams(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (clickListener != null) {
|
||||
clickListener.OnLongClick(adapter.getSelectDay());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface OnCalendarClickListener {
|
||||
void OnClick(CalendarDay day);
|
||||
void OnLongClick(CalendarDay day);
|
||||
}
|
||||
}
|
@ -0,0 +1,188 @@
|
||||
package com.idealist.calendarview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
|
||||
import com.idealist.calendarview.interf.OnSelectDateListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CalendarViewAdapter extends PagerAdapter {
|
||||
|
||||
private CalendarAttr attr;
|
||||
private List<CalendarView> mViews = new ArrayList<>();
|
||||
private int mCurrPosition = CalendarPager.CURRENT_DAY_INDEX;
|
||||
|
||||
// 保存上一次点击的日期
|
||||
private static CalendarDay mRecDate;
|
||||
private CalendarDay mSelectDay;
|
||||
private OnCalendarTypeChangeListener typeChangeListener;
|
||||
|
||||
public CalendarViewAdapter(Context context, CalendarAttr attr,
|
||||
OnSelectDateListener dateListener,
|
||||
CalendarView.OnCalendarClickListener longClickListener) {
|
||||
super();
|
||||
this.attr = attr;
|
||||
initViewAdapter(context, dateListener, longClickListener);
|
||||
}
|
||||
|
||||
|
||||
private void initViewAdapter(Context context, OnSelectDateListener dateListener,
|
||||
CalendarView.OnCalendarClickListener longClickListener) {
|
||||
mSelectDay = CalendarUtils.getCurrDay();
|
||||
CalendarDay day;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
CalendarView view = new CalendarView(context, attr, this, dateListener, longClickListener);
|
||||
day = CalendarUtils.getNearMonthDay(mSelectDay, i - 1);
|
||||
view.setSeedDay(day);
|
||||
mViews.add(view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过滑动更新 View
|
||||
*
|
||||
* @param position 需要更新的 View 的 position
|
||||
*/
|
||||
public void updateViewByScrollHorizontally(int position) {
|
||||
Log.e("adapter", "position: " + position + " mCurrPosition: " + mCurrPosition);
|
||||
CalendarDay seedDay = mViews.get(position % 3).getSeedDay();
|
||||
int offset = 0;
|
||||
if (position > mCurrPosition) {
|
||||
offset = 1;
|
||||
} else if (position < mCurrPosition) {
|
||||
offset = -1;
|
||||
}
|
||||
CalendarView view = mViews.get((position + offset) % 3);
|
||||
//TODO 注意视图
|
||||
if (attr.getCalendarType() != State.VIEW_WEEK)
|
||||
view.setSeedDay(CalendarUtils.getNearMonthDay(seedDay, offset));
|
||||
else
|
||||
view.setSeedDay(CalendarUtils.getNearWeekDay(seedDay, offset));
|
||||
}
|
||||
|
||||
|
||||
public int getCalendarType() {
|
||||
return attr.getCalendarType();
|
||||
}
|
||||
|
||||
/**
|
||||
* 当视图类型改变时更新 View 的显示模式
|
||||
*
|
||||
* @param updateType 更新的显示模式
|
||||
*/
|
||||
public void changeCalendarType(int updateType) {
|
||||
attr.setCalendarType(updateType);
|
||||
CalendarDay seedDay = mViews.get(mCurrPosition % 3).getSeedDay();
|
||||
saveSelectedDate();
|
||||
for (int i = -1; i < 2; ++i) {
|
||||
CalendarView view = mViews.get((mCurrPosition + i) % 3);
|
||||
if (updateType == State.VIEW_WEEK) {
|
||||
view.setSeedDay(CalendarUtils.getNearWeekDay(mSelectDay, i));
|
||||
} else {
|
||||
view.setSeedDay(CalendarUtils.getNearMonthDay(mSelectDay, i));
|
||||
}
|
||||
view.changeViewType();
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 由 pager 通知 adapter 发生点击事件更改,进行处理
|
||||
// * @param day 选中 CalendarDay
|
||||
// */
|
||||
// public void notifyDataChanged() {
|
||||
//
|
||||
// }
|
||||
|
||||
public void saveSelectedDate() {
|
||||
mRecDate = mSelectDay;
|
||||
}
|
||||
|
||||
public static CalendarDay loadSelectedDate() {
|
||||
return mRecDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
// 实现无限循环
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
|
||||
super.setPrimaryItem(container, position % 3, object);
|
||||
this.mCurrPosition = position;
|
||||
Log.e("adapterPri", Integer.toString(position));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem(@NonNull ViewGroup container, int position) {
|
||||
// if (position < 2) return null;
|
||||
|
||||
CalendarView view = mViews.get(position % 3);
|
||||
view.generateItem();
|
||||
view.invalidate();
|
||||
|
||||
int mChildNum = container.getChildCount();
|
||||
if (mChildNum == mViews.size()) {
|
||||
container.removeView(view);
|
||||
}
|
||||
|
||||
if (container.getChildCount() < mViews.size()) {
|
||||
container.addView(view, 0);
|
||||
} else {
|
||||
container.addView(view, position % 3);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
public void updateDayInViewState(int position) {
|
||||
CalendarView view = mViews.get(position % 3);
|
||||
view.setSeedDay(mSelectDay);
|
||||
view.updateView();
|
||||
}
|
||||
|
||||
public void updateViewScheduleChange() {
|
||||
CalendarView view = mViews.get(mCurrPosition % 3);
|
||||
view.updateView();
|
||||
}
|
||||
|
||||
public void setTypeChangeListener(OnCalendarTypeChangeListener typeChangeListener) {
|
||||
this.typeChangeListener = typeChangeListener;
|
||||
}
|
||||
|
||||
|
||||
public CalendarDay getSelectDay() {
|
||||
return mSelectDay;
|
||||
}
|
||||
|
||||
public void setSelectDay(CalendarDay mSelectDay) {
|
||||
this.mSelectDay = mSelectDay;
|
||||
}
|
||||
|
||||
public List<CalendarView> getViews() {
|
||||
return mViews;
|
||||
}
|
||||
|
||||
public interface OnCalendarTypeChangeListener {
|
||||
void onCalendarTypeChanged(int Calendar_Type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(@NonNull android.view.View view, @NonNull Object object) {
|
||||
return view == ((View) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.idealist.calendarview.interf;
|
||||
|
||||
import com.idealist.calendarview.CalendarDay;
|
||||
|
||||
public interface OnSelectDateListener {
|
||||
void onSelectOtherMonth(int offset);//点击其它月份日期
|
||||
}
|
@ -1,18 +1,142 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/CLayout"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
<LinearLayout
|
||||
android:id="@+id/custom_date_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="42dp"
|
||||
android:orientation="horizontal" >
|
||||
<TextView
|
||||
android:id="@+id/custom_year_view"
|
||||
android:layout_width="72sp"
|
||||
android:layout_marginLeft="30dp"
|
||||
android:layout_height="match_parent"
|
||||
android:textColor="#ff25adff"
|
||||
android:textSize="27sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_month_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="bottom"
|
||||
android:textColor="#26ADFF"
|
||||
android:textSize="20sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
style="@style/weekIndicatorStyle"
|
||||
android:text="日"/>
|
||||
<TextView
|
||||
style="@style/weekIndicatorStyle"
|
||||
android:text="一"/>
|
||||
<TextView
|
||||
style="@style/weekIndicatorStyle"
|
||||
android:text="二"/>
|
||||
<TextView
|
||||
style="@style/weekIndicatorStyle"
|
||||
android:text="三"/>
|
||||
<TextView
|
||||
style="@style/weekIndicatorStyle"
|
||||
android:text="四"/>
|
||||
<TextView
|
||||
style="@style/weekIndicatorStyle"
|
||||
android:text="五"/>
|
||||
<TextView
|
||||
style="@style/weekIndicatorStyle"
|
||||
android:text="六"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/cdLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.idealist.calendarview.CalendarPager
|
||||
android:id="@+id/custom_vp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- <androidx.recyclerview.widget.RecyclerView-->
|
||||
<!-- android:id="@+id/list_item"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent"-->
|
||||
<!-- app:layout_behavior="com.idealist.calendarview.RecyclerViewBehavior"/>-->
|
||||
|
||||
<!-- <cc.trity.floatingactionbutton.FloatingActionButton-->
|
||||
<!-- android:id="@+id/add_schedule"-->
|
||||
<!-- android:layout_width="40dp"-->
|
||||
<!-- android:layout_height="40dp"-->
|
||||
<!-- android:layout_gravity="bottom|start"-->
|
||||
<!-- app:fab_size="mini"-->
|
||||
<!-- app:fab_title="FAB 0"-->
|
||||
<!-- app:fab_colorNormal="#e41c1c"-->
|
||||
<!-- app:fab_icon="@drawable/schedule"-->
|
||||
<!-- />-->
|
||||
|
||||
<!-- <cc.trity.floatingactionbutton.FloatingActionsMenu-->
|
||||
<!-- android:id="@+id/right_labels"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_gravity="bottom|end"-->
|
||||
<!-- app:fab_expandDirection="up"-->
|
||||
<!-- app:fab_colorNormal="#f0f01a"-->
|
||||
<!-- app:fab_icon = "@drawable/ic_baseline_add_24"-->
|
||||
<!-- app:fab_addButtonSize="mini"-->
|
||||
<!-- >-->
|
||||
|
||||
<!-- <cc.trity.floatingactionbutton.FloatingActionButton-->
|
||||
<!-- android:id="@+id/diary_entry"-->
|
||||
<!-- android:layout_width="30dp"-->
|
||||
<!-- android:layout_height="30dp"-->
|
||||
<!-- android:background="@drawable/ic_baseline_add_24"-->
|
||||
<!-- app:fab_size="normal"-->
|
||||
<!-- app:fab_title="FAB 3"-->
|
||||
<!-- app:fab_colorNormal="#09F7F7"-->
|
||||
<!-- app:fab_icon="@drawable/diary"-->
|
||||
<!-- />-->
|
||||
|
||||
<!-- <cc.trity.floatingactionbutton.FloatingActionButton-->
|
||||
<!-- android:id="@+id/course_entry"-->
|
||||
<!-- android:layout_width="50dp"-->
|
||||
<!-- android:layout_height="50dp"-->
|
||||
<!-- app:fab_colorNormal="#24d63c"-->
|
||||
<!-- app:fab_size="normal"-->
|
||||
<!-- app:fab_icon="@drawable/course"-->
|
||||
<!-- />-->
|
||||
|
||||
<!-- <cc.trity.floatingactionbutton.FloatingActionButton-->
|
||||
<!-- android:id="@+id/zone_entry"-->
|
||||
<!-- android:layout_width="50dp"-->
|
||||
<!-- android:layout_height="50dp"-->
|
||||
<!-- app:fab_colorNormal="#501161"-->
|
||||
<!-- app:fab_size="normal"-->
|
||||
<!-- app:fab_icon="@drawable/zone"-->
|
||||
<!-- />-->
|
||||
|
||||
<!-- </cc.trity.floatingactionbutton.FloatingActionsMenu>-->
|
||||
<!-- <com.google.android.material.floatingactionbutton.FloatingActionButton-->
|
||||
<!-- android:id="@+id/addSchedule"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_gravity="end|bottom"-->
|
||||
<!-- android:layout_margin="30dp"-->
|
||||
<!-- android:backgroundTint="#7575EF"-->
|
||||
<!-- android:src="@drawable/ic_baseline_add_24"-->
|
||||
<!-- android:contentDescription="@string/add"-->
|
||||
<!-- app:fabSize="normal"-->
|
||||
<!-- />-->
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="weekIndicatorStyle">
|
||||
<item name="android:layout_width">0dp</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:textSize">13sp</item>
|
||||
<item name="android:textColor">#ff25adff</item>
|
||||
</style>
|
||||
|
||||
<style name="VideoShareImageView">
|
||||
<item name="android:layout_height">25dp</item>
|
||||
<item name="android:layout_width">25dp</item>
|
||||
<item name="android:layout_marginTop">8dp</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in new issue