首页
工具
心境语句
相册
建站轨迹
关于
Search
1
微信小程序:计算属性的两种体现方式及应用场景
1,594 阅读
2
Antd Upload 组件上传文件接收数据流并下载
1,059 阅读
3
C#插件火车头采集器动态切换代理IP,及自动切换UserAgent
542 阅读
4
[C#]使用dnSpy对目标程序(EXE或DLL)进行反编译修改并编译运行
537 阅读
5
ADODB.Connection 错误 800a0e7a 未找到提供程序。该程序可能未正确安装解决方法
499 阅读
react
typecho
ASP
Centos
MYSQL
PHP
Sql server
Javascript
nodejs
数据采集
.NET
git
编程算法
管理及流程
Vue
微信小程序
android
python
mongodb
登录
Search
标签搜索
kotlin
node-sass
nuxtjs
C#火车头插件
火车头采集器
火车头代理
C#反编译
程序逆向
dnSpy教程
Antd
InputNumber
NPM教程
NPM命令
rrweb教程
git慢
git镜像
vim命令
git命令
网页音乐插件
网页播放器
Elysian
累计撰写
74
篇文章
累计收到
0
条评论
首页
栏目
react
typecho
ASP
Centos
MYSQL
PHP
Sql server
Javascript
nodejs
数据采集
.NET
git
编程算法
管理及流程
Vue
微信小程序
android
python
mongodb
页面
工具
心境语句
相册
建站轨迹
关于
搜索到
74
篇与
Elysian
的结果
2022-07-06
mongodb在修改数据时,使用原有值更新内容
其实需要时间的内容在其他数据库中很简单,例如mysql如下:update news set click=click+1 where addtime>'2022-01-01';但是,在mongodb中查询了很多update的相关资料,在update方法中,没找到批量通过原有值修改的方法;(mongodb基础薄弱,可能最终还是因为我没找到,以后找到了补上)最终使用的先查询出结果,然后forEach的方式处理了,具体如下:db.集合名.find({这里可以写你的筛选条件}).forEach( function(item){ db.集合名.update( {"_id":item._id}, {"$set": {"CreatedTime":new Date(item.CreatedTime.getTime() + 1*60*60000)}}) })解释:1、为什么不直接用 update 去查询并更新,还要分成两个步骤写?对于这些数据,我是要在原有数据的基础上做修改,也就是【个性化】修改,直接使用update 的话,更新的字段数据都是一样的值参考来源:https://blog.csdn.net/weixin_44282947/article/details/118583626
2022年07月06日
242 阅读
0 评论
0 点赞
2022-06-29
MicroPython-ESP32开发环境搭建
相关工具及文件下载IDE-thonny:https://thonny.org/MicroPython:https://micropython.org/windows-ESP32驱动及其他相关文件:https://gitee.com/panxin1213/micropythontools/环境安装首先要安装thonny,然后安装windows-ESP32驱动,再将下载的micropython对应esp32电路板的烧录进板子中。thonny安装IDE安装很简单,直接下一步下一步就可以了。ESP32,windows驱动安装下载好驱动包后安装与系统版本相关的exe文件就可以了。MicroPython烧录1、打开thonny,选择运行-选择解释器2、在弹开的窗口中,选择thonny使用的解释器,这里使用MicroPython,然后Port部分选择安装好驱动的端口,这里要链接好电路板。3、如果是新的电路板,还没有烧录过环境的时候,需要点击Install or update firmware,烧录micropython解释器进入电路板,如下图所示,烧录环境4、烧录成功后,回显示done,表示成功,如果显示 Timed out waiting for packet header等错误,需要长按住电路板上的boot键,然后再按确定重新烧录。测试运行环境弄好后如下图,可以再thonny上看到对应链接上的电路板micropython环境及电路板上的python文件。
2022年06月29日
85 阅读
0 评论
0 点赞
2022-06-20
利用python和git实现目录文件变更自动备份
前言背景1、主要是突然有一个需要实时备份数据库文件,防止数据丢失的需求,思前想后,发现存在很多方式,例如备份在自己的其他服务器,备份在本地等,最终决定编写一个python脚本用来判断数据库备份文件夹文编改动后通过git提交到github或者gitee代码from watchdog.observers import Observer from watchdog.events import * import time from git import Repo import os def pushgit(ccpath): if(".git" in ccpath): print(1); else: try: dirfile = "C:\\Users\\Administrator\\Documents\\Navicat\\MySQL\\servers\\127.0.0.1\\ddh\\" # code的文件位置,我默认将其存放在根目录下 repo = Repo(dirfile) g = repo.git g.add("--all") g.commit("-m auto update") g.push() print("Successful push!") except : print("error push!") class FileEventHandler(FileSystemEventHandler): def __init__(self): FileSystemEventHandler.__init__(self) def on_moved(self, event): pushgit(event.src_path) if event.is_directory: print("directory moved from {0} to {1}".format(event.src_path,event.dest_path)) else: print("file moved from {0} to {1}".format(event.src_path,event.dest_path)) def on_created(self, event): pushgit(event.src_path) if event.is_directory: print("directory created:{0}".format(event.src_path)) else: print("file created:{0}".format(event.src_path)) def on_deleted(self, event): pushgit(event.src_path) if event.is_directory: print("directory deleted:{0}".format(event.src_path)) else: print("file deleted:{0}".format(event.src_path)) def on_modified(self, event): pushgit(event.src_path) if event.is_directory: print("directory modified:{0}".format(event.src_path)) else: print("file modified:{0}".format(event.src_path)) if __name__ == "__main__": observer = Observer() event_handler = FileEventHandler() observer.schedule(event_handler,"C:\\Users\\Administrator\\Documents\\Navicat\\MySQL\\servers\\127.0.0.1\\ddh\\",True) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()centos7 后端运行脚本命令nohup python3 -u auto_up.py > test.log 2>&1 &写好脚本文件中,将脚本文件加入到开机自动运行里就可以监控更新了。然后如果是备份数据库,则只需要创建数据库自动备份计划,就可以完成了。
2022年06月20日
254 阅读
0 评论
0 点赞
2022-06-07
计算机视觉经典库OpenCV
相关文档OpenCV中文官方文档:http://woshicver.com/OpenCV-Python中文教程:https://www.kancloud.cn/aollo/aolloopencv/269602Github 地址:https://github.com/fendouai/OpenCVTutorials
2022年06月07日
38 阅读
0 评论
0 点赞
2022-05-18
安卓组件,仿IOS平台UISegmentControlView
该文章主要是做一个备忘记录转至:https://blog.csdn.net/yeah0126/article/details/51452508感谢作者控件简介UISegmentControl在IOS平台的App中非常常见,其控件如下图所示:IOS平台的UISegmentControl这种控件的主要作用是动态的更改界面的显示内容,一般应用于内容较多的界面,且分屏显示不同种类的内容。控件属性说明<declare-styleable name="SegmentControlView"> <attr name="scv_BackgroundSelectedColor" format="reference|color" /><!--选中segment的背景颜色--> <attr name="scv_BackgroundNormalColor" format="reference|color" /><!--未选中segment的背景颜色--> <attr name="scv_TextSelectedColor" format="reference|color" /><!--选中segment的文字颜色--> <attr name="scv_TextNormalColor" format="reference|color" /><!--未选中segment的文字颜色--> <attr name="scv_FrameColor" format="reference|color" /><!--segment边框的颜色--> <attr name="scv_FrameWidth" format="reference|dimension" /><!--segment边框的宽度--> <attr name="scv_FrameCornerRadius" format="reference|dimension" /><!--segment四个圆角的半径大小--> <attr name="scv_TextSize" format="reference|dimension" /><!--文字大小--> <attr name="scv_TextArray" format="reference" /><!--string数组,每一个string都会填充到一个segment中--> <attr name="scv_SelectedIndex" format="reference|integer" /><!--默认选中的segment--> <attr name="scv_SegmentPaddingHorizontal" format="reference|dimension" /><!--每一个segment内部的水平padding--> <attr name="scv_SegmentPaddingVertical" format="reference|dimension" /><!--每一个Segment的竖直方向的padding--> <attr name="scv_Gradient" format="reference|boolean" /><!--Segment改变时是否使用颜色渐变效果--> </declare-styleable>布局文件创建SegmentControlView<cn.carbs.android.segmentcontrolview.library.SegmentControlView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:paddingLeft="10dp" android:paddingRight="10dp" app:scv_FrameCornerRadius="6dp" app:scv_FrameWidth="1dp" app:scv_Gradient="true" app:scv_SegmentPaddingVertical="5dp" app:scv_TextArray="@array/segment_control_arrays_0"/>使用方法引用dependencies { implementation 'cn.carbs.android:SegmentControlView:1.0.0' }使用segmentcontrolview.setOnSegmentChangedListener(OnSegmentChangedListener { newSelectedIndex -> if (viewpager != null) { //change the second argument to true if you want the gradient effect when viewpager is changing viewpager.setCurrentItem(newSelectedIndex, false) //viewpager changing without animation } }) //set viewpager to change segment according to the state of viewpager segmentcontrolview.setViewPager(viewpager) //set the selected index of segments initiatively segmentcontrolview.setSelectedIndex() //set gradient effect if you want segmentcontrolview.setGradient(true)源码package cn.carbs.android.segmentcontrolview.library; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; import android.support.v4.view.ViewPager; import android.text.TextUtils; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import java.lang.reflect.Field; /** * an SegmentControlView inspired by the UISegmentControl on IOS platform. * this view has many interesting such as : * 1. set gradient effect when segment is changing by ViewPager if needed * 2. set the corners' radius * 3. set colors of texts and background * 4. set titles in xml resource file * 5. has pressed effect when finger touches this view, you can set the dark coefficient * * Author Carbs.Wang * Email yeah0126#yeah.net */ public class SegmentControlView extends View { /** * onSegmentChanged function will be triggered if segment changed */ public interface OnSegmentChangedListener{ void onSegmentChanged(int newSelectedIndex); } private static final float TOUCHED_BACKGROUND_DARK_COEFFICIENT = 0.95F; private static final int COLOR_PRIMARY_NORMAL = 0XFFFFFFFF; private static final int COLOR_PRIMARY_SELECTED = 0XFF2CA99F; private static final int DEFAULT_COLOR_BACKGROUND_SELECTED = COLOR_PRIMARY_SELECTED; private static final int DEFAULT_COLOR_BACKGROUND_NORMAL = COLOR_PRIMARY_NORMAL; private static final int DEFAULT_COLOR_TEXT_SELECTED = COLOR_PRIMARY_NORMAL; private static final int DEFAULT_COLOR_TEXT_NORMAL = COLOR_PRIMARY_SELECTED; private static final int DEFAULT_COLOR_FRAME = COLOR_PRIMARY_SELECTED; private static final int DEFAULT_TEXT_SIZE_SP = 16; private static final int DEFAULT_FRAME_WIDTH_PX = 2; private static final int DEFAULT_FRAME_CORNER_RADIUS_PX = 0; private static final int DEFAULT_SELECTED_INDEX = 0; private static final int DEFAULT_SEGMENT_PADDING_HORIZONTAL = 16; private static final int DEFAULT_SEGMENT_PADDING_VERTICAL = 12; private static final boolean DEFAULT_IS_GRADIENT = false; private String[] mTexts = null; private int mColorBackgroundSelected = DEFAULT_COLOR_BACKGROUND_SELECTED; private int mColorBackgroundNormal = DEFAULT_COLOR_BACKGROUND_NORMAL; private int mColorTextSelected = DEFAULT_COLOR_TEXT_SELECTED; private int mColorTextNormal = DEFAULT_COLOR_TEXT_NORMAL; private int mColorFrame = DEFAULT_COLOR_FRAME; private int mFrameWidth = DEFAULT_FRAME_WIDTH_PX; private int mFrameCornerRadius = DEFAULT_FRAME_CORNER_RADIUS_PX; private int mTextSize = 0; private int mSelectedIndex = DEFAULT_SELECTED_INDEX; //used in wrap_content mode private int mSegmentPaddingHorizontal = DEFAULT_SEGMENT_PADDING_HORIZONTAL; private int mSegmentPaddingVertical = DEFAULT_SEGMENT_PADDING_VERTICAL; private boolean mIsGradient = DEFAULT_IS_GRADIENT; private OnSegmentChangedListener mOnSegmentChangedListener; private float unitWidth = 0; private Paint paintText; //painter of the text private Paint paintBackground; //painter of the background private Paint paintFrame; //painter of the frame private RectF rectF; private RectF rectFArc; private Path pathFrame; private float textCenterYOffset; private int preTouchedIndex = -1; private int curTouchedIndex = -1; private ViewPager viewPager; public SegmentControlView(Context context) { super(context); init(); } public SegmentControlView(Context context, AttributeSet attrs) { super(context, attrs); initAttr(context, attrs); init(); } public SegmentControlView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttr(context, attrs); init(); } private void initAttr(Context context, AttributeSet attrs) { if (attrs == null) { return; } TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SegmentControlView); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); if(attr == R.styleable.SegmentControlView_scv_BackgroundSelectedColor){ mColorBackgroundSelected = a.getColor(attr, DEFAULT_COLOR_BACKGROUND_SELECTED); }else if(attr == R.styleable.SegmentControlView_scv_BackgroundNormalColor){ mColorBackgroundNormal = a.getColor(attr, DEFAULT_COLOR_BACKGROUND_NORMAL); }else if(attr == R.styleable.SegmentControlView_scv_TextSelectedColor){ mColorTextSelected = a.getColor(attr, DEFAULT_COLOR_TEXT_SELECTED); }else if(attr == R.styleable.SegmentControlView_scv_TextNormalColor){ mColorTextNormal = a.getColor(attr, DEFAULT_COLOR_TEXT_NORMAL); }else if(attr == R.styleable.SegmentControlView_scv_FrameColor){ mColorFrame = a.getColor(attr, DEFAULT_COLOR_FRAME); }else if(attr == R.styleable.SegmentControlView_scv_TextSize){ mTextSize = a.getDimensionPixelSize(attr, sp2px(getContext(), DEFAULT_TEXT_SIZE_SP)); }else if(attr == R.styleable.SegmentControlView_scv_TextArray){ mTexts = convertCharSequenceToString(a.getTextArray(attr)); }else if(attr == R.styleable.SegmentControlView_scv_FrameWidth){ mFrameWidth = a.getDimensionPixelSize(attr, DEFAULT_FRAME_WIDTH_PX); }else if(attr == R.styleable.SegmentControlView_scv_FrameCornerRadius){ mFrameCornerRadius = a.getDimensionPixelSize(attr, DEFAULT_FRAME_CORNER_RADIUS_PX); }else if(attr == R.styleable.SegmentControlView_scv_SelectedIndex){ mSelectedIndex = a.getInteger(attr, DEFAULT_SELECTED_INDEX); }else if(attr == R.styleable.SegmentControlView_scv_SegmentPaddingHorizontal){ mSegmentPaddingHorizontal = a.getDimensionPixelSize(attr, DEFAULT_SEGMENT_PADDING_HORIZONTAL); }else if(attr == R.styleable.SegmentControlView_scv_SegmentPaddingVertical){ mSegmentPaddingVertical = a.getDimensionPixelSize(attr, DEFAULT_SEGMENT_PADDING_VERTICAL); }else if(attr == R.styleable.SegmentControlView_scv_Gradient){ mIsGradient = a.getBoolean(attr, DEFAULT_IS_GRADIENT); } } a.recycle(); } private void init(){ rectF = new RectF(); rectFArc = new RectF(); pathFrame = new Path(); if(mTextSize == 0) mTextSize = sp2px(getContext(), DEFAULT_TEXT_SIZE_SP); paintText = new Paint(); paintText.setAntiAlias(true); paintText.setTextAlign(Paint.Align.CENTER); paintText.setTextSize(mTextSize); paintBackground = new Paint(); paintBackground.setAntiAlias(true); paintBackground.setStyle(Paint.Style.FILL); paintFrame = new Paint(); paintFrame.setAntiAlias(true); paintFrame.setStyle(Paint.Style.STROKE); paintFrame.setStrokeWidth(mFrameWidth); paintFrame.setColor(mColorFrame); textCenterYOffset = getTextCenterYOffset(paintText.getFontMetrics()); this.setClickable(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(measureWidth(widthMeasureSpec, paintText), measureHeight(heightMeasureSpec, paintText)); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); rectF.left = getPaddingLeft(); rectF.top = getPaddingTop(); rectF.right = w - getPaddingRight(); rectF.bottom = h - getPaddingBottom(); float inset = (float)Math.ceil(mFrameWidth / 2); rectF.inset(inset, inset); if(mTexts!= null && mTexts.length > 0){ unitWidth = rectF.width() / mTexts.length; } rectFArc.left = 0; rectFArc.top = 0; rectFArc.right = 2 * mFrameCornerRadius; rectFArc.bottom = 2 * mFrameCornerRadius; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(!isStringArrayEmpty(mTexts)){ drawBackgroundAndFrameAndText(canvas); } } @Override public boolean onTouchEvent(MotionEvent event) { preTouchedIndex = curTouchedIndex; switch(event.getAction()){ case MotionEvent.ACTION_DOWN: curTouchedIndex = getTouchedIndex(event.getX(), event.getY()); if(preTouchedIndex != curTouchedIndex){ invalidate(); } break; case MotionEvent.ACTION_MOVE: curTouchedIndex = getTouchedIndex(event.getX(), event.getY()); if(preTouchedIndex != curTouchedIndex){ invalidate(); } break; case MotionEvent.ACTION_UP: curTouchedIndex = getTouchedIndex(event.getX(), event.getY()); if(curTouchedIndex != -1){ if(mOnSegmentChangedListener != null && mSelectedIndex != curTouchedIndex){ mOnSegmentChangedListener.onSegmentChanged(curTouchedIndex); } mSelectedIndex = curTouchedIndex; } curTouchedIndex = -1; if(mIsGradient && checkViewPagerOnPageChangeListener(this.viewPager)){ }else{ invalidate(); } break; case MotionEvent.ACTION_CANCEL: curTouchedIndex = -1; invalidate(); break; } return super.onTouchEvent(event); } public void setTextSize(int textSize){ if(this.mTextSize != textSize){ this.mTextSize = textSize; paintText.setTextSize(textSize); textCenterYOffset = getTextCenterYOffset(paintText.getFontMetrics()); requestLayout(); invalidate(); } } public int getSelectedIndex(){ return mSelectedIndex; } public void setSelectedIndex(int selectedIndex){ if(mSelectedIndex != selectedIndex){ mSelectedIndex = selectedIndex; if(mOnSegmentChangedListener != null){ mOnSegmentChangedListener.onSegmentChanged(mSelectedIndex); } // invalidate(); if(mIsGradient && checkViewPagerOnPageChangeListener(this.viewPager)){ }else{ invalidate(); } } } public void setTextColor(int textColorNormal, int textColorSelected){ this.mColorTextNormal = textColorNormal; this.mColorTextSelected = textColorSelected; invalidate(); } public void setBackgroundColor(int backgroundColorNormal, int backgroundColorSelected){ this.mColorBackgroundNormal = backgroundColorNormal; this.mColorBackgroundSelected = backgroundColorSelected; invalidate(); } public void setFrameColor(int frameColor){ this.mColorFrame = frameColor; invalidate(); } public void setFrameWidth(int frameWidth){ this.mFrameWidth = frameWidth; requestLayout(); invalidate(); } public void setTexts(String[] texts){ assertTextsValid(texts); if(texts == null || texts.length < 2){ throw new IllegalArgumentException("SegmentControlView's content text array'length should larger than 1"); } if(checkIfEqual(this.mTexts, texts)){ return; } this.mTexts = texts; unitWidth = rectF.width() / texts.length; requestLayout(); invalidate(); } public int getCount(){ if(mTexts == null) return 0; return mTexts.length; } /** * setViewPager(viewpager) to response to the change of ViewPager * @param viewPager the viewPager you want segmentcontrolview to respond with */ public void setViewPager(ViewPager viewPager) { this.viewPager = viewPager; if (viewPager != null) { viewPager.setOnPageChangeListener(new InternalViewPagerListener()); } } /** * set if this view has the Gradient effect when segment changed * @param gradient set if you want gradient effect */ public void setGradient(boolean gradient){ if(mIsGradient != gradient){ mIsGradient = gradient; } } public boolean getGradient(){ return mIsGradient; } /** * when segment changed, * mOnSegmentChangedListener.onSegmentChanged(newSelectedIndex) will be triggered * @param listener OnSegmentChangedListener */ public void setOnSegmentChangedListener(OnSegmentChangedListener listener){ mOnSegmentChangedListener = listener; } public void update(){ invalidate(); } private float getTextCenterYOffset(Paint.FontMetrics fontMetrics){ if(fontMetrics == null) return 0; return Math.abs(fontMetrics.top + fontMetrics.bottom)/2; } private String[] convertCharSequenceToString(CharSequence[] csArray){ if(csArray == null) return null; String[] sArray = new String[csArray.length]; for(int i = 0; i < csArray.length; i++){ sArray[i] = csArray[i].toString(); } return sArray; } private void assertTextsValid(String[] texts){ if(texts == null || texts.length < 2){ throw new IllegalArgumentException("SegmentControlView's content text array'length should larger than 1"); } } private boolean checkViewPagerOnPageChangeListener(ViewPager viewPager){ if(viewPager == null) return false; Field field = null; try { field = ViewPager.class.getDeclaredField("mOnPageChangeListener"); if(field == null) return false; field.setAccessible(true); Object o = field.get(viewPager); if(o != null && o instanceof InternalViewPagerListener){ return true; } } catch (Exception e) { return false; } return false; } private int getTouchedIndex(float x, float y){ if(!rectF.contains(x, y)){ return -1; } for(int i = 0; i < mTexts.length; i++){ if(rectF.left + i * unitWidth <= x && x < rectF.left + (i + 1) * unitWidth){ return i; } } return -1; } private boolean checkIfEqual(String[] a, String[] b){ if(a == null && b == null){ return true; } if(a != null){ if(b == null){ return false; } if(a.length != b.length){ return false; } for(int i = 0; i < a.length; i++){ if(a[i] == null && b[i] == null){ continue; } if(a[i] != null && a[i].equals(b[i])){ continue; }else{ return false; } } return true; } return false; } private int measureWidth(int measureSpec, Paint paint) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { int maxWidth = 0; int maxWidthItem = getMaxWidthOfTextArray(mTexts, paint); maxWidth = (maxWidthItem + 2 * mSegmentPaddingHorizontal + 2 * mFrameWidth) * mTexts.length; if(maxWidth < 2 * mFrameCornerRadius){ maxWidth = 2 * mFrameCornerRadius; } result = this.getPaddingLeft() + this.getPaddingRight() + maxWidth;//MeasureSpec.UNSPECIFIED if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; } private int measureHeight(int measureSpec, Paint paint) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { int maxHeight = 0; int maxHeightItem = getMaxHeightOfTextArray(mTexts, paint); maxHeight = maxHeightItem + 2 * mSegmentPaddingVertical + 2 * mFrameWidth; if(maxHeight < 2 * mFrameCornerRadius){ maxHeight = 2 * mFrameCornerRadius; } result = this.getPaddingTop() + this.getPaddingBottom() + maxHeight;//MeasureSpec.UNSPECIFIED if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; } private int getMaxWidthOfTextArray(String[] array, Paint paint){ if(array == null){ return 0; } int maxWidth = 0; for(String item : array){ if(item != null){ int itemWidth = getTextWidth(item, paint); maxWidth = Math.max(itemWidth, maxWidth); } } return maxWidth; } private int getMaxHeightOfTextArray(String[] array, Paint paint){ if(array == null){ return 0; } int maxHeight = 0; for(String item : array){ if(item != null){ int itemHeight = getTextHeight(item, paint); maxHeight = Math.max(itemHeight, maxHeight); } } return maxHeight; } private void drawBackgroundAndFrameAndText(Canvas canvas){ int curBackgroundColor = 0; int curTextColor = 0; for(int i = 0; i < mTexts.length; i++){ float left = rectF.left + unitWidth * i; pathFrame.reset(); if(i == 0){ pathFrame.moveTo(rectF.left, rectF.top + mFrameCornerRadius); rectFArc.offsetTo(rectF.left, rectF.top); pathFrame.arcTo(rectFArc, 180, 90); pathFrame.lineTo(rectF.left + unitWidth, rectF.top); pathFrame.lineTo(rectF.left + unitWidth, rectF.bottom); pathFrame.lineTo(rectF.left + mFrameCornerRadius, rectF.bottom); rectFArc.offsetTo(rectF.left, rectF.bottom - 2 * mFrameCornerRadius); pathFrame.arcTo(rectFArc, 90, 90); }else if(i == (mTexts.length - 1)){ pathFrame.moveTo(rectF.left + i * unitWidth, rectF.top); pathFrame.lineTo(rectF.right - mFrameCornerRadius, rectF.top); rectFArc.offsetTo(rectF.right - 2 * mFrameCornerRadius, rectF.top); pathFrame.arcTo(rectFArc, 270, 90); pathFrame.lineTo(rectF.right, rectF.bottom - mFrameCornerRadius); rectFArc.offsetTo(rectF.right - 2 * mFrameCornerRadius, rectF.bottom - 2 * mFrameCornerRadius); pathFrame.arcTo(rectFArc, 0, 90); pathFrame.lineTo(rectF.left + i * unitWidth, rectF.bottom); }else{ pathFrame.moveTo(left, rectF.top); pathFrame.lineTo(left + unitWidth, rectF.top); pathFrame.lineTo(left + unitWidth, rectF.bottom); pathFrame.lineTo(left, rectF.bottom); } pathFrame.close(); if(!mIsGradient){ if(i == mSelectedIndex){ curBackgroundColor = mColorBackgroundSelected; curTextColor = mColorTextSelected; }else{ curBackgroundColor = mColorBackgroundNormal; curTextColor = mColorTextNormal; } } if(mIsGradient){ if(viewPagerPositionOffset != 0f){ if(i == viewPagerPosition){ curBackgroundColor = getEvaluateColor(viewPagerPositionOffset, mColorBackgroundSelected, mColorBackgroundNormal); curTextColor = getEvaluateColor(viewPagerPositionOffset, mColorTextSelected, mColorTextNormal); }else if(i == viewPagerPosition + 1){ curBackgroundColor = getEvaluateColor(viewPagerPositionOffset, mColorBackgroundNormal, mColorBackgroundSelected); curTextColor = getEvaluateColor(viewPagerPositionOffset, mColorTextNormal, mColorTextSelected); }else{ curBackgroundColor = mColorBackgroundNormal; curTextColor = mColorTextNormal; } }else{ if(i == mSelectedIndex){ curBackgroundColor = mColorBackgroundSelected; curTextColor = mColorTextSelected; }else{ curBackgroundColor = mColorBackgroundNormal; curTextColor = mColorTextNormal; } } } paintBackground.setColor(curBackgroundColor); if(curTouchedIndex == i){ paintBackground.setColor(getDarkColor(curBackgroundColor, TOUCHED_BACKGROUND_DARK_COEFFICIENT)); } canvas.drawPath(pathFrame, paintBackground); canvas.drawPath(pathFrame, paintFrame); paintText.setColor(curTextColor); canvas.drawText(mTexts[i], left + unitWidth / 2,rectF.centerY() + textCenterYOffset, paintText); } } private int viewPagerPosition = -1; private float viewPagerPositionOffset = 0f; private class InternalViewPagerListener implements ViewPager.OnPageChangeListener { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if(mIsGradient){ mSelectedIndex = position; viewPagerPosition = position; viewPagerPositionOffset = positionOffset; invalidate(); } } @Override public void onPageScrollStateChanged(int state) { } @Override public void onPageSelected(int position) { if(mIsGradient){ }else{ SegmentControlView.this.setSelectedIndex(position); } } } private int getDarkColor(int color, float darkCoefficient){ int a = (color & 0xff000000) >>> 24; int r = (color & 0x00ff0000) >>> 16; int g = (color & 0x0000ff00) >>> 8; int b = (color & 0x000000ff) >>> 0; r = (int)(r * darkCoefficient); g = (int)(g * darkCoefficient); b = (int)(b * darkCoefficient); return a << 24 | r << 16 | g << 8 | b; } private int getEvaluateColor(float fraction, int startColor, int endColor){ int a, r, g, b; int sA = (startColor & 0xff000000) >>> 24; int sR = (startColor & 0x00ff0000) >>> 16; int sG = (startColor & 0x0000ff00) >>> 8; int sB = (startColor & 0x000000ff) >>> 0; int eA = (endColor & 0xff000000) >>> 24; int eR = (endColor & 0x00ff0000) >>> 16; int eG = (endColor & 0x0000ff00) >>> 8; int eB = (endColor & 0x000000ff) >>> 0; a = (int)(sA + (eA - sA) * fraction); r = (int)(sR + (eR - sR) * fraction); g = (int)(sG + (eG - sG) * fraction); b = (int)(sB + (eB - sB) * fraction); return a << 24 | r << 16 | g << 8 | b; } private boolean isStringArrayEmpty(String[] array){ return (array == null || array.length == 0); } private static int sp2px(Context context, float spValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } private int getTextWidth(String text, Paint paint){ if(!TextUtils.isEmpty(text)){ return (int)(paint.measureText(text) + 0.5f); } return -1; } private int getTextHeight(String text, Paint paint){ if(!TextUtils.isEmpty(text)){ Rect textBounds = new Rect(); paint.getTextBounds(text, 0, text.length(), textBounds); return textBounds.height(); } return -1; } }项目地址:https://github.com/Carbs0126/AndroidSegmentControlView
2022年05月18日
69 阅读
0 评论
0 点赞
1
...
3
4
5
...
15