先上效果如下(模拟器有些卡):

代码实现:
一个数字对应一个 ScrollingNumber 对象。

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;import androidx.annotation.ColorInt;
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;/*** @author ganmin.he* @date 2022/5/13*/
public class ScrollingNumbersView extends View implements ValueAnimator.AnimatorUpdateListener,ColorAnimateHelper.ColorUpdateListener, PauseResumeAnimateHelper.PauseResumeListener {@IntDef({ALIGNMENT_CENTER, ALIGNMENT_LEFT, ALIGNMENT_RIGHT})@Retention(RetentionPolicy.SOURCE)public @interface Alignment {}public static final int ALIGNMENT_CENTER = 0;public static final int ALIGNMENT_LEFT = 1;public static final int ALIGNMENT_RIGHT = 2;public static final float DEFAULT_TEXT_SIZE = 105f;public static final float DEFAULT_LINE_SPACING_MULTIPLIER = 1.5f;public static final float DEFAULT_SINGLE_NUMBER_WIDTH_MULTIPLIER = 1.2f;public static final float DEFAULT_SUB_TEXT_SIZE = 36f;public static final int NO_ADJUST_SUBTEXT = Integer.MAX_VALUE;private final int mMaxDigits; // The count of all numbersprivate int mShowingCount; // The count of showing numbers@Alignmentprivate int mAlignment; // Default: ALIGNMENT_CENTERprivate float mLineSpacingMult; // Default: DEFAULT_LINE_SPACING_MULTIPLIERprivate float mSingleNumberWidthMult; // Default: DEFAULT_SINGLE_NUMBER_WIDTH_MULTIPLIERprivate String mSubText; // May be "%" or "分"private float mSubTextSize; // Default: DEFAULT_SUB_TEXT_SIZEprivate boolean mPauseAt95; // Whether to pause at 95%private int mAdjustSubTextThreshold = NO_ADJUST_SUBTEXT; // adjust sub text x when centeredprivate int mCurrentValue;                     //  0 9 9private int mAdjacentValue;                    //  1 0 0private final int[] mCurrentNumbers;           // |0|9|9|private final int[] mAdjacentNumbers;          // |1|0|0|private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);private final Point mTextWidthHeight = new Point();private final Point mSubWidthHeight = new Point();private final Point mSubLocation = new Point();private final Rect mDrawingArea = new Rect();private final ArrayList<ScrollingNumber> mNumbers = new ArrayList<>();private final AnimatorSet mAnimatorSet = new AnimatorSet();private final ArrayList<Animator> mAnimators = new ArrayList<>();public ScrollingNumbersView(Context context) {this(context, null);}public ScrollingNumbersView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ScrollingNumbersView(Context context, AttributeSet attrs,int defStyleAttr) {this(context, attrs, defStyleAttr, 0);}public ScrollingNumbersView(Context context, AttributeSet attrs,int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ScrollingNumbersView, defStyleAttr, defStyleRes);int maxDigits = a.getInt(R.styleable.ScrollingNumbersView_maxDigits, 3);int initialValue = a.getInt(R.styleable.ScrollingNumbersView_initialValue, 0);int textColor = a.getColor(R.styleable.ScrollingNumbersView_textColor, Color.RED);float textSize = a.getDimension(R.styleable.ScrollingNumbersView_textSize,DEFAULT_TEXT_SIZE);int styleIndex = a.getInt(R.styleable.ScrollingNumbersView_textStyle, Typeface.NORMAL);int alignment = a.getInt(R.styleable.ScrollingNumbersView_alignment, ALIGNMENT_CENTER);float lineSpacingMult = a.getFloat(R.styleable.ScrollingNumbersView_lineSpacingMultiplier,DEFAULT_LINE_SPACING_MULTIPLIER);float singleNumberWidthMult = a.getFloat(R.styleable.ScrollingNumbersView_singleNumberWidthMultiplier,DEFAULT_SINGLE_NUMBER_WIDTH_MULTIPLIER);float subTextSize = a.getDimension(R.styleable.ScrollingNumbersView_subTextSize,DEFAULT_SUB_TEXT_SIZE);String subText = a.getString(R.styleable.ScrollingNumbersView_subText);int adjustSubTextThreshold = a.getInt(R.styleable.ScrollingNumbersView_adjustSubTextThreshold, NO_ADJUST_SUBTEXT);a.recycle();mMaxDigits = maxDigits;mCurrentNumbers = new int[mMaxDigits];mAdjacentNumbers = new int[mMaxDigits];for (int i = 0; i < mMaxDigits; i++) {addScrollingNumber(new ScrollingNumber(i), true);}setPaintColor(textColor);setPaintTextSize(textSize);Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/HelveticaNeue.ttc");setPaintTypeface(Typeface.create(tf, styleIndex));//setPaintTypeface(Typeface.createFromFile("/system/fonts/Smartisan_Latin-Bold.otf"));//setPaintTypeface(Typeface.defaultFromStyle(styleIndex));setAlignment(alignment);setLineSpacingMultiplier(lineSpacingMult);setSingleNumberWidthMultiplier(singleNumberWidthMult);setSubTextSize(subTextSize);setSubText(subText);setAdjustSubTextThresholdWhenCentered(adjustSubTextThreshold);setInitialValue(initialValue);}private void addScrollingNumber(ScrollingNumber sn, boolean toLeft) {if (toLeft) {mNumbers.add(0, sn);} else {mNumbers.add(sn);}ValueAnimator animator = sn.getValueAnimator();animator.addUpdateListener(this);mAnimators.add(animator);mAnimatorSet.playTogether(mAnimators);}/*private void removeScrollingNumber(boolean fromLeft) {if (mNumbers.isEmpty()) {return;}ScrollingNumber sn;if (fromLeft) {sn = mNumbers.remove(0);} else {sn = mNumbers.remove(mNumbers.size() - 1);}if (sn == null) {return;}ValueAnimator animator = sn.getValueAnimator();animator.removeUpdateListener(this);mAnimators.remove(animator);mAnimatorSet.playTogether(mAnimators);sn.removeNumberChangeListener();}*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);int allNumberWidth = (int) (mMaxDigits * mTextWidthHeight.x * mSingleNumberWidthMult);//int height = getPaddingTop() + mTextWidthHeight.y + getPaddingBottom();int height = (int) mPaint.getTextSize();int paddingVertical = (height - mTextWidthHeight.y) / 2;setPadding(getPaddingLeft(), paddingVertical, getPaddingRight(), paddingVertical);int width = getPaddingLeft() + allNumberWidth + mSubWidthHeight.x + getPaddingRight();if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {// Use width, height} else if (widthSpecMode == MeasureSpec.AT_MOST) {height = heightSpecSize;} else if (heightSpecMode == MeasureSpec.AT_MOST) {width = widthSpecSize;}setMeasuredDimension(width, height);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);updateNumberLocation();mDrawingArea.set(0, 0, getWidth(), getHeight());}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.save();int height = getHeight();int color = mPaint.getColor();float factor = 0.5f - mTextWidthHeight.y * 0.5f / height;@SuppressLint("DrawAllocation")LinearGradient verticalGradient = new LinearGradient(0, 0, 0, height,new int[]{Color.TRANSPARENT, color, color, Color.TRANSPARENT},new float[]{0, factor, 1f - factor, 1f},Shader.TileMode.CLAMP);mPaint.setShader(verticalGradient);drawNumberOnCanvas(canvas, mPaint);mPaint.setShader(null);if (!TextUtils.isEmpty(mSubText)) {float textSize = mPaint.getTextSize();mPaint.setTextSize(mSubTextSize);canvas.drawText(mSubText, mSubLocation.x, mSubLocation.y, mPaint);mPaint.setTextSize(textSize);}canvas.restore();}private void drawNumberOnCanvas(Canvas canvas, Paint paint) {for (ScrollingNumber sn : mNumbers) {sn.drawOnCanvas(canvas, paint);}}public void setPaintTextSize(float textSize) {mPaint.setTextSize(textSize);updateTextWidthHeight();updateSubWidthHeight();//updateNumberLocation();}private void updateTextWidthHeight() {Rect bounds = new Rect();mPaint.getTextBounds("0", 0, 1, bounds);mTextWidthHeight.set(bounds.width(), bounds.height());updateNumberLocation();}public void setPaintColor(@ColorInt int color) {mPaint.setColor(color);}public void setPaintTypeface(Typeface tf) {mPaint.setTypeface(tf);}public void setAlignment(@Alignment int alignment) {mAlignment = alignment;updateNumberLocation();}public void setLineSpacingMultiplier(float lineSpacingMult) {mLineSpacingMult = lineSpacingMult;}public void setSingleNumberWidthMultiplier(float singleNumberWidthMult) {mSingleNumberWidthMult = singleNumberWidthMult;updateNumberLocation();}public void setSubText(String text) {mSubText = text == null ? "" : text.trim();updateSubWidthHeight();}public void setSubTextSize(float subTextSize) {mSubTextSize = subTextSize;updateSubWidthHeight();}private void updateSubWidthHeight() {if (mSubTextSize < 0.001f) {mSubText = "";}if (TextUtils.isEmpty(mSubText)) {mSubWidthHeight.set(0, 0);} else {float textSize = mPaint.getTextSize();mPaint.setTextSize(mSubTextSize);Rect bounds = new Rect();mPaint.getTextBounds(mSubText, 0, 1, bounds);mSubWidthHeight.set(bounds.width(), bounds.height());mPaint.setTextSize(textSize);}updateNumberLocation();}public void setPauseAt95Percent(boolean pauseAt95) {mPauseAt95 = pauseAt95;}public void setInitialValue(int initValue) {mCurrentValue = initValue;mAdjacentValue = initValue;valueToArray(mCurrentValue, mCurrentNumbers);valueToArray(mAdjacentValue, mAdjacentNumbers);setNumberWithValue(initValue);}private void setNumberWithValue(int value) {for (ScrollingNumber sn : mNumbers) {sn.setNumberWithValue(value);}int newCount = updateNumberCanShowZero() + 1;updateShowingNumberCount(newCount);}private int updateNumberCanShowZero() {int count = 0;boolean canShowZero = false;for (int i = 0; i < mAdjacentNumbers.length - 1; i++) {mNumbers.get(i).setCanShowZero(canShowZero);if (!canShowZero && mAdjacentNumbers[i] != 0) {count = mAdjacentNumbers.length - (i + 1);canShowZero = true;}}// The ones digit can show zeromNumbers.get(mAdjacentNumbers.length - 1).setCanShowZero(true);return count;}private void updateShowingNumberCount(int newCount) {if (newCount == mShowingCount) {return;}mShowingCount = newCount;updateNumberLocation();}public void setAdjustSubTextThresholdWhenCentered(int adjustSubTextThreshold) {mAdjustSubTextThreshold = adjustSubTextThreshold;updateNumberLocation();}// Call this when mAlignment, mTextWidthHeight, mSubWidthHeight, mSingleNumberWidthMult,// mShowingCount, mAdjustSubTextThreshold changed and onLayoutprivate void updateNumberLocation() {int paddingLeft = getPaddingLeft();int paddingRight = getPaddingRight();int paddingTop = getPaddingTop();int newX = paddingLeft;int singleNumberWidth = (int) (mTextWidthHeight.x * mSingleNumberWidthMult);int allNumberWidth = mMaxDigits * singleNumberWidth;int showingNumberWidth = mShowingCount * singleNumberWidth;int offsetX = allNumberWidth - showingNumberWidth;switch (mAlignment) {case ALIGNMENT_CENTER:int subWidth = (mShowingCount >= mAdjustSubTextThreshold) ? mSubWidthHeight.x : 0;newX = (int) ((getWidth() - showingNumberWidth - subWidth) / 2f) - offsetX;break;case ALIGNMENT_LEFT:newX -= offsetX;break;case ALIGNMENT_RIGHT:newX = getWidth() - paddingRight - mSubWidthHeight.x - allNumberWidth;break;}mSubLocation.set(newX + allNumberWidth, paddingTop + mSubWidthHeight.y);int newY = paddingTop + mTextWidthHeight.y;for (ScrollingNumber sn : mNumbers) {sn.setLocation(newX, newY);newX += singleNumberWidth;}}public void setNumberAnimatorValues(int... targetValues) {for (ScrollingNumber sn : mNumbers) {sn.setAnimatorValues(mCurrentValue, targetValues);}}public void setNumberAnimatorDuration(long duration) {mAnimatorSet.setDuration(duration);}public void startNumberAnimator() {mAnimatorSet.start();}@Overridepublic void onAnimationUpdate(ValueAnimator animation) {invalidate();}@Overridepublic void onColorUpdate(int color) {setPaintColor(color);invalidate();}@Overridepublic void onPause() {mAnimatorSet.pause();}@Overridepublic void onResume() {mAnimatorSet.resume();}private static int[] valueToArray(int value, int length) {int[] array = new int[length];valueToArray(value, array);return array;}private static void valueToArray(int value, int[] array) {/*Arrays.fill(array, 0);char[] chars = String.valueOf(value).toCharArray();int charlen = chars.length;for (int i = 0; i < charlen; i++) {array[i + array.length - charlen] = chars[i] - 48;}*/for (int i = array.length - 1; i >= 0; i--) {array[i] = value % 10;value /= 10;}}private static int arrayToValue(int[] array) {/*int len = array.length;char[] chars = new char[len];for (int i = 0; i < len; i++) {chars[i] = (char) (array[i] + 48);}return Integer.parseInt(String.valueOf(chars));*/int value = 0;int pow = 1;for (int i = array.length - 1; i >= 0; i--) {value += array[i] * pow;pow *= 10;}return value;}public void onNumberChanged(ScrollingNumber sn, int oldNumber, int newNumber) {mCurrentNumbers[mMaxDigits - sn.getDigit() - 1] = newNumber;int oldValue = mCurrentValue;mCurrentValue = arrayToValue(mCurrentNumbers);if (oldValue < 95 && mCurrentValue == 95 && mPauseAt95) {PauseResumeAnimateHelper.getInstance().pauseAnimator();}}public void onAdjacentNumberStartShowing(ScrollingNumber sn, int adjacentNumber) {mAdjacentNumbers[mMaxDigits - sn.getDigit() - 1] = adjacentNumber;int newCount = updateNumberCanShowZero() + 1;updateShowingNumberCount(newCount);mAdjacentValue = arrayToValue(mAdjacentNumbers);}private class ScrollingNumber implements ValueAnimator.AnimatorUpdateListener,Animator.AnimatorListener {private final int mDigit;private final int mPower; // 10^digitprivate final ValueAnimator mValueAnimator;private int mPreNumber, mNumber, mNextNumber;private int mLocationX, mLocationY, mScrollingY;private int mScrollYAccumulation; // |mScrollYAccumulation| < mLineSpacing;private int mLastAnimatedValue;private boolean mNotifyAdjacentNumberStartShowing;private boolean mCanShowZero;public ScrollingNumber(int digit) {mDigit = digit;mPower = (int) Math.pow(10, digit);mValueAnimator = new ValueAnimator();mValueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());mValueAnimator.addUpdateListener(this);mValueAnimator.addListener(this);}public int getDigit() {return mDigit;}private void setNumber(@IntRange(from = 0, to = 9) int number) {onNumberChanged(this, mNextNumber, number);mNotifyAdjacentNumberStartShowing = true;mNumber = number;mPreNumber = (mNumber + 9) % 10;mNextNumber = (mNumber + 1) % 10;}public void setNumberWithValue(int value) {setNumber((value / mPower) % 10);}private boolean isVisible(int number) {int lineSpacing = (int) (mTextWidthHeight.y * mLineSpacingMult);if (number == mPreNumber) {return mScrollingY - lineSpacing > 0;} else if (number == mNumber) {return mScrollingY > 0|| mScrollingY - mTextWidthHeight.y < mDrawingArea.height();} else if (number == mNextNumber) {return mScrollingY + lineSpacing - mTextWidthHeight.y < mDrawingArea.height();}return false;}public void setLocation(int newX, int newY) {mLocationX = newX;int offsetY = newY - mLocationY;mLocationY = newY;mScrollingY += offsetY;}private void scrollYBy(int offsetY) {if (offsetY == 0) {return;}int lineSpacing = (int) (mTextWidthHeight.y * mLineSpacingMult);mScrollingY += offsetY;mScrollYAccumulation += offsetY;int valueDiff = mScrollYAccumulation / lineSpacing;if (valueDiff != 0) {int newNumber = (mNumber - valueDiff) % 10;if (newNumber < 0) {newNumber += 10;}setNumber(newNumber);mScrollingY -= valueDiff * lineSpacing;mScrollYAccumulation %= lineSpacing;}if (mNotifyAdjacentNumberStartShowing) {int adjacentNumber = offsetY > 0 ? mPreNumber : mNextNumber;if (isVisible(adjacentNumber)) {onAdjacentNumberStartShowing(this, adjacentNumber);mNotifyAdjacentNumberStartShowing = false;}}}public void setCanShowZero(boolean canShowZero) {mCanShowZero = canShowZero;}public void drawOnCanvas(Canvas canvas, Paint paint) {int lineSpacing = (int) (mTextWidthHeight.y * mLineSpacingMult);if ((mPreNumber != 0 || mCanShowZero) && isVisible(mPreNumber)) {canvas.drawText("" + mPreNumber, mLocationX, mScrollingY - lineSpacing, paint);}if ((mNumber != 0 || mCanShowZero) && isVisible(mNumber)) {canvas.drawText("" + mNumber, mLocationX, mScrollingY, paint);}if ((mNextNumber != 0 || mCanShowZero) && isVisible(mNextNumber)) {canvas.drawText("" + mNextNumber, mLocationX, mScrollingY + lineSpacing, paint);}}public ValueAnimator getValueAnimator() {return mValueAnimator;}public void setAnimatorValues(int currentValue, int... targetValues) {int lineSpacing = (int) (mTextWidthHeight.y * mLineSpacingMult);int len = targetValues.length + 1;int[] intValues = new int[len];//intValues[0] = 0;for (int i = 1; i < len; i++) {intValues[i] = (currentValue / mPower - targetValues[i - 1] / mPower) * lineSpacing;}mValueAnimator.setIntValues(intValues);}@Overridepublic void onAnimationUpdate(ValueAnimator animation) {int curAnimatedValue = (int) animation.getAnimatedValue();int diff = curAnimatedValue - mLastAnimatedValue;scrollYBy(diff);mLastAnimatedValue = curAnimatedValue;}@Overridepublic void onAnimationStart(Animator animation) {mScrollingY = mLocationY;mScrollYAccumulation = 0;mLastAnimatedValue = 0;}@Overridepublic void onAnimationEnd(Animator animation) {}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}}
}

attrs.xml ScrollingNumbersView 可配置的属性

<resources><!-- Default text typeface style. --><attr name="textStyle"><flag name="normal" value="0" /><flag name="bold" value="1" /><flag name="italic" value="2" /></attr><attr name="alignment"><enum name="center" value="0" /><enum name="left" value="1" /><enum name="right" value="2" /></attr><declare-styleable name="ScrollingNumbersView"><attr name="maxDigits" format="integer" /><attr name="initialValue" format="integer" /><attr name="textColor" format="color" /><attr name="textSize" format="dimension" /><attr name="textStyle" /><attr name="subTextSize" format="dimension" /><attr name="subText" format="string" /><attr name="adjustSubTextThreshold" format="integer" /><attr name="alignment" /><attr name="lineSpacingMultiplier" format="float" /><attr name="singleNumberWidthMultiplier" format="float" /></declare-styleable>
</resources>

Android 绘制数字向上向下滚动的动画相关推荐

  1. 向上滚动 终端_终端 - 如何在Linux控制台上向上/向下滚动?

    终端 - 如何在Linux控制台上向上/向下滚动? 我认识到Up / Down会给你命令历史. 但是,你如何通过上下滚动查看过去的输出? 我使用了Shift + Page Up / Page Down ...

  2. android 上滑隐藏view,Android CoordinatorLayout + AppBarLayout(向上滚动隐藏指定的View)

    在新的Android Support Library里面,新增了CoordinatorLayout, AppBarLayout等. 实现的效果: 向下滚动RecylerView,Tab会被隐藏,向上滚 ...

  3. android 上下数字滚动_原来PPT数字还有这么高大上的展示方式

    数字,是PPT当中非常重要的元素,说明价格.呈现销量.展示性能等等多种场合都有使用,数据也是PPT当中最直观的表现形式. 那么,PPT当中的数字要怎么表现才显得高逼格呢?在这里介绍一个小技巧:动态滚动 ...

  4. android listview 向上自动滚动效果,Android通过代码控制ListView上下滚动的方法

    本文将介绍一种通过代码控制ListView上下滚动的方法. 先上图: 按下按钮会触发ListView滚动或停止. 实现该功能并不难,下面给出主要代码MainActivity.java package ...

  5. ajax实现向上正在加载,向上滚动或者向下滚动分页异步加载数据(Ajax + lazyload)

    /**** desc : 分页异步获取列表数据,页面向上滚动时候加载前面页码,向下滚动时加载后面页码 ajaxdata_url ajax异步的URL 如data.php page_val_name a ...

  6. html页面怎么加向下滚动,如何使用jQuery向上或向下滚动页面到锚点?

    如何使用jQuery向上或向下滚动页面到锚点? 我正在寻找一种方法来包含幻灯片效果,当您单击页面上或下的本地锚点链接时. 我想要一个你有这样一个链接的东西:link text, img etc. 也许 ...

  7. 鼠标滚动时判断向下滚动还是向上滚动

    有时候需要用到,判断页面是向上还是向下滚动了,兼容比较低版本的浏览器如IE6.7等. 原理:拿当前的scrollTop和之前的scrollTop对比  如果变大了,表示向下滚动(scrollTop值变 ...

  8. [Android]自定义View带效果的滚动数字

    [Android]自定义View带效果的滚动数字 @Author GQ 2016年07月29日 一个可以让数字滚动的View,可以自定义参数,是想要的那种效果! 原文github地址 效果图 Andr ...

  9. 鼠标滚轮的滚动事件,判断鼠标向上还是向下滚动

    代码: JS // 鼠标滚动事件windowAddMouseWheel() {let that = this;var scrollFunc = function (e) {e = e || windo ...

最新文章

  1. 编写python脚本完成图片拼接
  2. java icache_Java ICacheWordSubscriber類代碼示例
  3. ajax 上传读取excel
  4. SpringBoot自动配置原理流程
  5. canvas js 绘图插件_Canvas专题—绘制柱状图(2)
  6. 面试官:你知道Redis得持久化机制吗?
  7. 【java】JVM Attach机制实现与jstack使用(jvm参数DisableAttachMechanism)
  8. 策略模式思想及示例代码(Strategy)
  9. OS X 使用技巧——在Finder窗口标题栏上显示路径
  10. Oralce/MySQL 默认隔离级别对比
  11. 面试总结——Java篇
  12. cic滤波器原理 MATLAB,cic滤波器(cic滤波器的原理和设计)
  13. java 分词获取词性_jie分词之分词、词性分析、关键词抽取
  14. 按照斗地主的规则,完成洗牌发牌的动作。
  15. 一步一步搭建自己的web系统(一):搭建后端服务
  16. 英语语音篇 - 自然拼读
  17. 二维码推广方法20种
  18. 分布式系统设计系列 -- 基本原理及高可用策略
  19. 安卓的BP、AP、NV是什么意思
  20. Spring+SpringMVC+Hibernate实现投票/调查问卷网站

热门文章

  1. webRTC(十三):webrtc 统计信息
  2. LeetCode:322. 零钱兑换(python)
  3. mac远程登录虚拟机
  4. 宠物领养管理系统|宠物寄养管理系统JAVA|JSP|SSM|Springboot|web计算机毕业设计源码
  5. python中split_python中split是什么意思
  6. Oracle EBS R12 整合ADF
  7. MTK介绍MTK平台介绍
  8. 使用hugging face提供的预训练模型,报错:ImportError: cannot import name ‘DatasetInfo‘ from ‘huggingface_hub.hf_api
  9. 软件测试市场前景怎么样,软件测试的发展前景怎么样?
  10. 3D游戏建模室内材质调整方法