android自定义起止时间的时间刻度尺,Android中自定义RecyclerView如何实现不固定刻度的刻度尺...
Android中自定义RecyclerView如何实现不固定刻度的刻度尺
发布时间:2020-07-17 16:50:28
来源:亿速云
阅读:116
作者:小猪
这篇文章主要讲解了Android中自定义RecyclerView如何实现不固定刻度的刻度尺,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。
本文实例为大家分享了自定义RecyclerView实现不固定刻度的刻度尺的具体代码,供大家参考,具体内容如下
##不均匀刻度效果图
##等比例刻度效果图
实现功能目前
1、实现类似日期/分类等大小不固定的水平刻度尺效果
2、实现标准刻度尺效果
3、监听RecyclerView滑动时居中条目
4、去掉边缘阴影
定义RecyclerView
public class CenterRecyclerView extends RecyclerView {
//设置RecyclerView的速度
private static final int MAXIMUM_FLING_VELOCITY = 3000;
//画中轴线
private Paint mCenterLinePaint;
private Context context;
private CenterLayoutManager mLayoutManager;
private Paint mTextPaint;
private String text = "";
private String textUnit = "";
private Paint mTextUnitPaint;
private int mWidth;
private int mHeight;
private int mLineStartY;
private int mLineEndY;
private int mTextStartY;
public CenterRecyclerView(@NonNull Context context) {
this(context, null);
}
public CenterRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, -1);
}
public CenterRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
this.context = context;
initPaint();
}
public void setTypeface(Typeface typeface) {
mTextPaint.setTypeface(typeface);
mTextUnitPaint.setTypeface(typeface);
}
private void initPaint() {
mCenterLinePaint = new Paint();
mCenterLinePaint.setAntiAlias(true);
mCenterLinePaint.setStrokeWidth(ScreenUtil.dip2px(context, 4));
mCenterLinePaint.setTextAlign(Paint.Align.CENTER);
mCenterLinePaint.setColor(0xff6e9fff);
mTextUnitPaint = new Paint();
mTextUnitPaint.setStyle(Paint.Style.FILL);
mTextUnitPaint.setStrokeWidth(ScreenUtil.dip2px(context, 4));
mTextUnitPaint.setTextSize(ScreenUtil.dip2px(context, 15));
mTextUnitPaint.setColor(Color.parseColor("#DD5F00"));
mTextPaint = new Paint();
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setStrokeWidth(ScreenUtil.dip2px(context, 4));
mTextPaint.setTextSize(ScreenUtil.dip2px(context, 60));
mTextPaint.setColor(Color.parseColor("#DD5F00"));
mTextPaint.setTextAlign(Paint.Align.CENTER);
}
@Override
public void addOnScrollListener(@NonNull OnScrollListener listener) {
super.addOnScrollListener(listener);
postInvalidate();
}
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
}
//获取相关参数
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mWidth = getWidth();
mHeight = getHeight();
int lineHeight = ScreenUtil.dip2px(context, 58);
mLineStartY = mHeight / 2 - lineHeight / 2;
mLineEndY = mHeight / 2 + lineHeight / 2;
mTextStartY = mHeight / 2 - ScreenUtil.dip2px(context, 55);
}
@Override
public void draw(Canvas c) {
super.draw(c);
Log.d("szjjyh", "draw: " + getWidth());
drawCenterLine(c);
drawText(c);
}
//画线
private void drawCenterLine(Canvas canvas) {
canvas.drawLine(mWidth / 2, mLineStartY, mWidth / 2, mLineEndY, mCenterLinePaint);
}
//画字/画单位
private void drawText(Canvas c) {
c.drawText(text, mWidth / 2, mTextStartY, mTextPaint);
if (textUnit != null && textUnit.length() != 0) {
float textWidth = mTextPaint.measureText(text);
c.drawText(textUnit, (mWidth + textWidth) / 2, mTextStartY, mTextUnitPaint);
}
}
public String getText() {
return text;
}
public void setText(String text) {
if (text == null) {
return;
}
this.text = text;
}
public String getTextUnit() {
return textUnit;
}
public void setTextUnit(String textUnit) {
if (textUnit == null) {
return;
}
this.textUnit = textUnit;
}
@Override
public void setAdapter(@Nullable Adapter adapter) {
super.setAdapter(adapter);
}
@Override
public void setLayoutManager(@Nullable LayoutManager layout) {
super.setLayoutManager(layout);
mLayoutManager = (CenterLayoutManager) layout;
}
@Override
public boolean fling(int velocityX, int velocityY) {
velocityX = solveVelocity(velocityX);
velocityY = solveVelocity(velocityY);
return super.fling(velocityX, velocityY);
}
private int solveVelocity(int velocity) {
if (velocity > 0) {
return Math.min(velocity, MAXIMUM_FLING_VELOCITY);
} else {
return Math.max(velocity, -MAXIMUM_FLING_VELOCITY);
}
}
// @Override
// protected float getLeftFadingEdgeStrength() {
// return 0;
// }
}
定义LinearLayoutManager
public class CenterLayoutManager extends LinearLayoutManager {
public CenterLayoutManager(Context context) {
super(context);
}
public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public CenterLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
//计算偏移量自己适配
@Override
public void scrollToPosition(int position) {
scrollToPositionWithOffset(position,-15);
}
@Override
public void scrollToPositionWithOffset(int position, int offset) {
super.scrollToPositionWithOffset(position, offset);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
public void smoothScrollToPosition(RecyclerView recyclerView, int position) {
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
private static class CenterSmoothScroller extends LinearSmoothScroller {
CenterSmoothScroller(Context context) {
super(context);
}
//滑动到中间位置
@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
//滚动速度设置
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return 4;
}
@Override
protected int getVerticalSnapPreference() {
return super.getVerticalSnapPreference();
}
}
}
滑动事件监听
public class CenterScrollListener extends RecyclerView.OnScrollListener {
private CenterLayoutManager mLayoutManager;
RecyclerView recyclerView;
private int mPosition;
private double intScrollState;
private int mFirstItemPosition1;
private int mLastItemPosition1;
private boolean is_Stop;
private String TAG = "CenterScrollListener";
private double is_playSound;
public CenterScrollListener(OnItemCenterScrollistner onItemCenterScrollistner) {
this.onItemCenterScrollistner = onItemCenterScrollistner;
}
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
init(recyclerView);
intScrollState = newState;
is_Stop = false;
if (intScrollState == RecyclerView.SCROLL_STATE_IDLE) {
Log.e(TAG, "onScrollStateChanged: 11111:"+mPosition);
CeterScroll(0, mPosition);
}
}
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
init(recyclerView);
int x = Math.abs(dx);
if (!is_Stop && x <= 1) {
is_Stop = true;
if (dx >= 0) {
mPosition = (mFirstItemPosition1 + mLastItemPosition1) / 2;
View childAt = mLayoutManager.findViewByPosition(mPosition);
if (childAt.getLeft() < ScreenUtil.getScreenWidth(recyclerView.getContext()) / 2) {
mPosition = mPosition + 1;
}
Log.e(TAG, "111111: w:" + childAt.getWidth() + " :l:" +
childAt.getLeft() + " :r:" + childAt.getRight());
} else {
mPosition = (mFirstItemPosition1 + mLastItemPosition1) / 2;
View childAt = mLayoutManager.findViewByPosition(mPosition);
if (childAt.getLeft() > ScreenUtil.getScreenWidth(recyclerView.getContext()) / 2) {
mPosition = mPosition - 1;
}
}
}
CeterScroll(x, mPosition);
}
//事件监听
private void init(@NonNull RecyclerView recyclerView) {
this.recyclerView = recyclerView;
if (mLayoutManager == null) {
mLayoutManager = (CenterLayoutManager) recyclerView.getLayoutManager();
}
int firstItemPosition = mLayoutManager.findFirstVisibleItemPosition();
int lastItemPosition = mLayoutManager.findLastVisibleItemPosition();
mFirstItemPosition1 = mLayoutManager.findFirstCompletelyVisibleItemPosition();
mLastItemPosition1 = mLayoutManager.findLastCompletelyVisibleItemPosition();
mPosition = (mFirstItemPosition1 + mLastItemPosition1) / 2;
if (is_playSound != mPosition) {
is_playSound = mPosition;
int count = mLayoutManager.getItemCount();
// soundpool.play(soundmap.get(1), 1, 1, 0, 0, 1);
if (onItemCenterScrollistner != null) {
//中间条目事件监听
onItemCenterScrollistner.onItemCenterScrollistner(mLastItemPosition1, mPosition,count);
}
}
//目前由于要实现灰色条目当条目间距为10dp,屏幕宽度360时不能继续滑动
if (mPosition <= 18) {
CeterScroll(0, 18);
}
}
//速度变小时自动滚动到中间位置
private void CeterScroll(int dx, int position) {
if ((intScrollState == RecyclerView.SCROLL_STATE_SETTLING || intScrollState
== RecyclerView.SCROLL_STATE_IDLE) && Math.abs(dx) <= 1) {
mLayoutManager.smoothScrollToPosition(recyclerView, position);
}
}
OnItemCenterScrollistner onItemCenterScrollistner;
public void setOnItemCenterScrollistner(OnItemCenterScrollistner onItemCenterScrollistner) {
this.onItemCenterScrollistner = onItemCenterScrollistner;
}
public interface OnItemCenterScrollistner {
void onItemCenterScrollistner(int lastItemPosition1, int position, int count);
}
adpater实现
public class DateAdapter extends BaseRecyclerAdapter {
private static final int layoutId = R.layout.view_item_date;
public DateAdapter(Context context, List datas) {
super(context, datas, layoutId);
}
@Override
protected void bindData(BaseViewHolder holder, CalendarDateBean data, int position) {
if (data.getDay() == 1) {
//R.id.tv_1为线需要居中否则和中轴线不会完全对称 R.id.tv_2为大刻度文字
holder.getView(R.id.tv_1).setScaleX(2F);
holder.setText(R.id.tv_2, data.getMonth() + "月");
holder.getView(R.id.tv_2).setVisibility(View.VISIBLE);
holder.getView(R.id.tv_1).setBackgroundColor(Color.parseColor("#ffffff"));
} else if (data.getDay() ==-1){
holder.getView(R.id.tv_1).setScaleX(1F);
holder.getView(R.id.tv_2).setVisibility(View.GONE);
holder.getView(R.id.tv_1).setBackgroundColor(Color.parseColor("#222222"));
}else {
holder.getView(R.id.tv_1).setScaleX(1F);
holder.getView(R.id.tv_2).setVisibility(View.GONE);
holder.getView(R.id.tv_1).setBackgroundColor(Color.parseColor("#ffffff"));
}
}
}
activity 加载view展示
private void initRecyclerView() {
//此处试配时注意item10dp 宽度360 计算发放 360/10/2得到记得适配
for (int i = 0; i < 18; i++) {
TimeBean timeBean = new TimeBean();
mList.add(timeBean);
}
for (int i = 0; i < 1440; i++) {
int minute = i % 60;
int hour = i / 60;
if (CalendarUtil.getHourTime()==hour&&CalendarUtil.getMinuteTime()==minute){
mPostion = i;
}
TimeBean timeBean = new TimeBean();
timeBean.setHour(hour);
timeBean.setMinute(minute);
timeBean.setTimeDate(CalendarUtil.getHourToMinute(hour,minute));
mList.add(timeBean);
}
for (int i = 0; i < 18; i++) {
TimeBean timeBean = new TimeBean();
// timeBean.setMinute(-1);
mList.add(timeBean);
}
rv_data = findViewById(R.id.rv_data);
mAdapter = new TimeAdapter(this, mList);
rv_data.setAdapter(mAdapter);
//设置字体
rv_data.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/dincond_boldalternate.ttf"));
CenterLayoutManager layoutManager = new CenterLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
rv_data.setLayoutManager(layoutManager);
rv_data.scrollToPosition(mPostion);
rv_data.addOnScrollListener(new CenterScrollListener((lastItemPosition, position,count) -> {
//更新文本和单位
rv_data.setText(mList.get(position).getTimeDate());
if (mList.get(position).getHour()>12){
rv_data.setTextUnit("PM");
}else {
rv_data.setTextUnit("AM");
}
}));
}
看完上述内容,是不是对Android中自定义RecyclerView如何实现不固定刻度的刻度尺有进一步的了解,如果还想学习更多内容,欢迎关注亿速云行业资讯频道。
android自定义起止时间的时间刻度尺,Android中自定义RecyclerView如何实现不固定刻度的刻度尺...相关推荐
- 自定义RecyclerView实现不固定刻度的刻度尺
##不均匀刻度效果图 ##等比例刻度效果图 实现功能目前 1.实现类似日期/分类等大小不固定的水平刻度尺效果 2.实现标准刻度尺效果 3.监听RecyclerView滑动时居中条目 4.去掉边缘阴影 ...
- php自定义函数全局声明,【phpcms-v9】phpcms-v9中自定义全局函数文件:extention.func.php...
/** * extention.func.php 用户自定义函数库 * * @copyright(C) 2005-2010 PHPCMS * @licensehttp://www.phpcms.cn/ ...
- vue2、vue3中自定义v-model的使用和区别
在我们的日常开发中,时常需要写一些自定义组件,而其中可能就会使用到v-model,v-model是Vue中的一个指令,用来实现数据的双向绑定,实现数据.视图更新,v-model是一个语法糖,,我们可以 ...
- VC中自定义IE浏览器
VC中自定义IE浏览器 http://www.5xsoft.com/Article.aspx?id=155 本教程提供了自定义浏览器控件的行为和外观的一些方法.你将看到高级的宿主接口, IDocHos ...
- android自定义起止时间的时间刻度尺,Android 自定义View篇(六)实现时钟表盘效果...
前言 Android 自定义 View 是高级进阶不可或缺的内容,日常工作中,经常会遇到产品.UI 设计出花里胡哨的界面.当系统自带的控件不能满足开发需求时,就只能自己动手撸一个效果. 本文就带自定义 ...
- Android 自定义带图标Toast,工具方法,Toast自定义显示时间
带图标Toast工具方法1 样式 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:an ...
- Android 系统(201)---Android 自定义View实战系列 :时间轴
Android 自定义View实战系列 :时间轴 Android开发中,时间轴的 UI需求非常常见,如下图: 本文将结合 自定义View & RecyclerView的知识,手把手教你实现该常 ...
- 可以缩放平移的时间刻度尺,方便自定义UI需求。仿萤石云历史录像时间轴
https://github.com/Liberations/TimeRuler TimeRuler [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ijjdgeFo-1 ...
- Android 节操视频播放器jiecaovideoplayer自定义播放音频使用:屏蔽全屏按钮,增加倒计时,当前时间/总时间
一.屏蔽全屏按钮 找到JCVideoPlayerStandard.java文件中的代码: private void fixAudio() {if (SrcType.equalsIgnoreCase(& ...
最新文章
- MySQL性能优化之参数配置
- python解析xml文件选用模块_python-minidom模块【解析xml】
- 独立思考者模型:寻找潜藏在表象背后的真相 探寻真相的方法
- 大道至简阅读笔记01
- SAP 电商云 Spartacus UI Angular Component 动态创建的单步调试
- python vtk_VTK在python环境下的安装和调用
- 20155209 2016-2017-2 《Java程序设计》第五周学习总结
- 设计模式18_责任链
- kubernetes--pod的生命周期管理(PostStart,PreStop)
- java文件传输加密_java程序对于文件的加密和解密
- 010Editor逆向分析
- 致我们终将远离的子女
- 嵌入式系统概论-考试总结
- 5v供电的数字功放芯片有哪些
- photoshop基本的操作
- 计算机excel没点保存,【2人回答】电脑突然断电,EXCEL没保存怎么找回已录入的资料?-3D溜溜网...
- JVM-调优《常见可视化工具与命令行的使用》
- 日语学习的在线资料,朋友推荐,拿来分享
- hautoj1262: 魔法宝石
- mysql utf8mb4 bin_Mysql的utf8与utf8mb4区别,utf8mb4_bin、utf8mb4_general_ci与utf8mb4_unicode_ci的选择...
热门文章
- 常用系统变量 SY-*
- 微信小程序 js中遍历list
- Java中IO流(3).
- 时隔27年,微软IE浏览器正式退出历史舞台,一个时代的结束
- pycharm远程连接服务器问题Uploading PyCharm helpers Python Interpreter... Python helpers are not copied yet
- webSocket配置wss访问
- cppcheck代码检查工具安装与使用技巧
- 亚马逊将推出VR购物应用,支持Vive Rift PSVR三大平台
- PC实现Win10/原生安卓双系统
- 【leetcode】二维子矩阵的和