【MyAndroid】日期时间滚轮选择器--100个经典UI设计模板(97/100)
效果如下:
使用
布局文件如下:
<com.ycuwq.datepicker.date.DatePicker
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:id="@+id/dayPicker_dialog"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.ycuwq.datepicker.date.DatePicker>
<com.ycuwq.datepicker.time.HourAndMinutePicker
android:id="@+id/hour_min_picker_dialog"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/dayPicker_dialog"
android:layout_width="0dp"
android:layout_height="wrap_content"
/>
com.ycuwq.datepicker.date.DatePicker是组合
里面的布局文件如下:
<com.ycuwq.datepicker.date.YearPicker
android:id="@+id/yearPicker_layout_date"
app:halfVisibleItemCount="2"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<com.ycuwq.datepicker.date.MonthPicker
android:id="@+id/monthPicker_layout_date"
app:halfVisibleItemCount="2"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<com.ycuwq.datepicker.date.DayPicker
android:id="@+id/dayPicker_layout_date"
app:halfVisibleItemCount="2"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
java里进行监听如下:
- YearPicker.OnYearSelectedListener
- MonthPicker.OnMonthSelectedListener
- DayPicker.OnDaySelectedListener
- HourPicker.OnHourSelectedListener
- MinutePicker.OnMinuteSelectedListener
布局中的属性说明
属性列表如下:
<declare-styleable name="WheelPicker">
<attr name="halfVisibleItemCount"/>//可见的行数
<attr name="itemTextSize"/>//文本大小
<attr name="itemMaximumWidthText"/>宽度
<attr name="itemTextColor"/>文本颜色
<attr name="textGradual"/>字体渐变,开启后越靠近边缘,字体越模糊
<attr name="selectedTextColor"/>选中文本颜色
<attr name="selectedTextSize"/>选中的文本大小
<attr name="currentItemPosition"/>当前项位置
<attr name="itemWidthSpace"/>两个Item之间的高宽间隔
<attr name="itemHeightSpace"/>两个Item之间的高宽间隔
<attr name="zoomInSelectedItem"/>是否进行缩放效果
<attr name="wheelCyclic"/>循环
<attr name="wheelCurtain"/>幕布
<attr name="wheelCurtainColor"/>幕布颜色
<attr name="wheelCurtainBorder" />幕布边框
<attr name="wheelCurtainBorderColor"/>幕布边框的颜色
<attr name="indicatorText"/>指示器文字的文本
<attr name="indicatorTextSize"/>指示器文字的文本大小
<attr name="indicatorTextColor"/>指示器文字的文本颜色
</declare-styleable>
<declare-styleable name="YearPicker">
<attr name="startYear" format="integer"/> 开始年份
<attr name="endYear" format="integer"/>结束年份
</declare-styleable>
<declare-styleable name="MonthPicker">
</declare-styleable>
<declare-styleable name="DatePicker">
<attr name="halfVisibleItemCount"/>
<attr name="itemTextSize"/>
<attr name="itemTextColor"/>
<attr name="textGradual"/>
<attr name="selectedTextColor"/>
<attr name="selectedTextSize"/>
<attr name="itemWidthSpace"/>
<attr name="itemHeightSpace"/>
<attr name="zoomInSelectedItem"/>
<attr name="wheelCyclic"/>
<attr name="wheelCurtain"/>
<attr name="wheelCurtainColor"/>
<attr name="wheelCurtainBorder"/>
<attr name="wheelCurtainBorderColor"/>
</declare-styleable>
<declare-styleable name="HourAndMinutePicker">
<attr name="halfVisibleItemCount"/>
<attr name="itemTextSize"/>
<attr name="itemTextColor"/>
<attr name="textGradual"/>
<attr name="selectedTextColor"/>
<attr name="selectedTextSize"/>
<attr name="itemWidthSpace"/>
<attr name="itemHeightSpace"/>
<attr name="zoomInSelectedItem"/>
<attr name="wheelCyclic"/>
<attr name="wheelCurtain"/>
<attr name="wheelCurtainColor"/>
<attr name="wheelCurtainBorder"/>
<attr name="wheelCurtainBorderColor"/>
</declare-styleable>
线条和矩形边框幕布设置
位置:com.ycuwq.datepicker.WheelPicker#onDraw(Canvas canvas)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setTextAlign(Paint.Align.CENTER);
if (mIsShowCurtain) {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mCurtainColor);
canvas.drawRect(mSelectedItemRect, mPaint);
}
if (mIsShowCurtainBorder) {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(mCurtainBorderColor);
canvas.drawLine(mSelectedItemRect.left
, mSelectedItemRect.top
, mSelectedItemRect.right
, mSelectedItemRect.top
, mPaint); //绘制直线
canvas.drawLine(mSelectedItemRect.left
, mSelectedItemRect.bottom
, mSelectedItemRect.right
, mSelectedItemRect.bottom
, mPaint); //绘制直线
// canvas.drawRect(mSelectedItemRect, mPaint);
// canvas.drawRect(mDrawnRect, mPaint);
}
int drawnSelectedPos = - mScrollOffsetY / mItemHeight;
mPaint.setStyle(Paint.Style.FILL);
//首尾各多绘制一个用于缓冲
for (int drawDataPos = drawnSelectedPos - mHalfVisibleItemCount - 1;
drawDataPos <= drawnSelectedPos + mHalfVisibleItemCount + 1; drawDataPos++) {
int position = drawDataPos;
if (mIsCyclic) {
position = fixItemPosition(position);
} else {
if (position < 0 || position > mDataList.size() - 1) {
continue;
}
}
T data = mDataList.get(position);
int itemDrawY = mFirstItemDrawY + (drawDataPos + mHalfVisibleItemCount) * mItemHeight + mScrollOffsetY;
//距离中心的Y轴距离
int distanceY = Math.abs(mCenterItemDrawnY - itemDrawY);
if (mIsTextGradual) {
//文字颜色渐变要在设置透明度上边,否则会被覆盖
//计算文字颜色渐变
if (distanceY < mItemHeight) { //距离中心的高度小于一个ItemHeight才会开启渐变
float colorRatio = 1 - (distanceY / (float) mItemHeight);
mSelectedItemPaint.setColor(mLinearGradient.getColor(colorRatio));
mTextPaint.setColor(mLinearGradient.getColor(colorRatio));
} else {
mSelectedItemPaint.setColor(mSelectedItemTextColor);
mTextPaint.setColor(mTextColor);
}
//计算透明度渐变
float alphaRatio;
if (itemDrawY > mCenterItemDrawnY) {
alphaRatio = (mDrawnRect.height() - itemDrawY) /
(float) (mDrawnRect.height() - (mCenterItemDrawnY));
} else {
alphaRatio = itemDrawY / (float) mCenterItemDrawnY;
}
alphaRatio = alphaRatio < 0 ? 0 :alphaRatio;
mSelectedItemPaint.setAlpha((int) (alphaRatio * 255));
mTextPaint.setAlpha((int) (alphaRatio * 255));
}
//开启此选项,会将越靠近中心的Item字体放大
if (mIsZoomInSelectedItem) {
if (distanceY < mItemHeight) {
float addedSize = (mItemHeight - distanceY) / (float) mItemHeight * (mSelectedItemTextSize - mTextSize);
mSelectedItemPaint.setTextSize(mTextSize + addedSize);
mTextPaint.setTextSize(mTextSize + addedSize);
} else {
mSelectedItemPaint.setTextSize(mTextSize);
mTextPaint.setTextSize(mTextSize);
}
} else {
mSelectedItemPaint.setTextSize(mTextSize);
mTextPaint.setTextSize(mTextSize);
}
String drawText = mDataFormat == null ? data.toString() : mDataFormat.format(data);
//在中间位置的Item作为被选中的。
if (distanceY < mItemHeight / 2) {
canvas.drawText(drawText, mFirstItemDrawX, itemDrawY, mSelectedItemPaint);
} else {
canvas.drawText(drawText, mFirstItemDrawX, itemDrawY, mTextPaint);
}
}
if (!TextUtils.isEmpty(mIndicatorText)) {
canvas.drawText(mIndicatorText, mFirstItemDrawX + mTextMaxWidth / 2F, mCenterItemDrawnY, mIndicatorPaint);
}
}
线条边框
矩形边框幕布
公开源码不渣
https://gitee.com/lc951/my-android
参考:
https://github.com/ycuwq/DatePicker
自研产品推荐
历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:
- api参数填写
- api请求响应数据展示
- PDF形式的分享文档
- Mock本地化解决方案
- api列表数据本地化处理
- 再加上UI方面的打磨
为了更好服务大家把之前的公众号和软件激活结合,如有疑问请大家反馈到公众号即可,下个版本30%以上的更新会来自公众号的反馈。
嗯!先解释不上服务端原因,API调试工具的绝大多数时候就是一个数据模型、数据处理、数据模型理解共识的问题解决工具,所以作者结合自己十多年开发使用的一些痛点来打造的,再加上服务端开发一般是面向企业的,作者目前没有精力和时间去打造企业服务。再加上没有资金投入所以服务端开发会滞后,至于什么时候会进行开发,这个要看募资情况和用户反馈综合考虑。虽然目前国内有些比较知名的api工具了,但作者使用后还是觉得和实际使用场景不符。如果有相关吐槽也可以在作者的公众号里反馈蛤!
下面是一段smartApi使用介绍:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?