效果图:

自定义圆形弹出菜单:

使用的时候,可以将此代码直接复制到自己的项目中

package com.administrator.menunewcustom;import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.LinearInterpolator;import java.util.ArrayList;
import java.util.List;/*** Created by Anshul on 24/06/15.*/
public class GooeyMenu extends View {private static final long ANIMATION_DURATION = 1000;private static final int DEFUALT_MENU_NO = 5;private final float START_ANGLE = 0f;private final float END_ANGLE = 45f;private int mNumberOfMenu;//Todoprivate final float BEZIER_CONSTANT = 0.551915024494f;// pre-calculated valueprivate int mFabButtonRadius;private int mMenuButtonRadius;private int mGab;private int mCenterX;private int mCenterY;private Paint mCirclePaint;private ArrayList<CirclePoint> mMenuPoints = new ArrayList<>();private ArrayList<ObjectAnimator> mShowAnimation = new ArrayList<>();private ArrayList<ObjectAnimator> mHideAnimation = new ArrayList<>();private ValueAnimator mBezierAnimation, mBezierEndAnimation, mRotationAnimation;private boolean isMenuVisible = true;private Float bezierConstant = BEZIER_CONSTANT;private Bitmap mPlusBitmap;private float mRotationAngle;private ValueAnimator mRotationReverseAnimation;private GooeyMenuInterface mGooeyMenuInterface;private boolean gooeyMenuTouch;private Paint mCircleBorder;private List<Drawable> mDrawableArray;public static final int[] STATE_ACTIVE ={android.R.attr.state_enabled, android.R.attr.state_active};public static final int[] STATE_PRESSED ={android.R.attr.state_enabled, -android.R.attr.state_active,android.R.attr.state_pressed};public GooeyMenu(Context context) {super(context);init(null);}public GooeyMenu(Context context, AttributeSet attrs) {super(context, attrs);init(attrs);}public GooeyMenu(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(attrs);}public GooeyMenu(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);init(attrs);}private void init(AttributeSet attrs) {if (attrs != null) {TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs,R.styleable.GooeyMenu,0, 0);try {mNumberOfMenu = typedArray.getInt(R.styleable.GooeyMenu_no_of_menu, DEFUALT_MENU_NO);mFabButtonRadius = (int) typedArray.getDimension(R.styleable.GooeyMenu_fab_radius, getResources().getDimension(R.dimen.big_circle_radius));mMenuButtonRadius = (int) typedArray.getDimension(R.styleable.GooeyMenu_menu_radius, getResources().getDimension(R.dimen.small_circle_radius));mGab = (int) typedArray.getDimension(R.styleable.GooeyMenu_gap_between_menu_fab, getResources().getDimensionPixelSize(R.dimen.min_gap));TypedValue outValue = new TypedValue();// Read array of target drawablesif (typedArray.getValue(R.styleable.GooeyMenu_menu_drawable, outValue)) {Resources res = getContext().getResources();TypedArray array = res.obtainTypedArray(outValue.resourceId);mDrawableArray = new ArrayList<>(array.length());for (int i = 0; i < array.length(); i++) {TypedValue value = array.peekValue(i);mDrawableArray.add(getResources().getDrawable(value != null ? value.resourceId : 0));}array.recycle();}} finally {typedArray.recycle();typedArray = null;}}mCirclePaint = new Paint();mCirclePaint.setColor(getResources().getColor(R.color.default_color));mCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);mCircleBorder = new Paint(mCirclePaint);mCircleBorder.setStyle(Paint.Style.STROKE);mCircleBorder.setStrokeWidth(1f);mCircleBorder.setColor(getResources().getColor(R.color.default_color_dark));mBezierEndAnimation = ValueAnimator.ofFloat(BEZIER_CONSTANT + .2f, BEZIER_CONSTANT);mBezierEndAnimation.setInterpolator(new LinearInterpolator());mBezierEndAnimation.setDuration(300);mBezierEndAnimation.addUpdateListener(mBezierUpdateListener);mBezierAnimation = ValueAnimator.ofFloat(BEZIER_CONSTANT - .02f, BEZIER_CONSTANT + .2f);mBezierAnimation.setDuration(ANIMATION_DURATION / 4);mBezierAnimation.setRepeatCount(4);mBezierAnimation.setInterpolator(new LinearInterpolator());mBezierAnimation.addUpdateListener(mBezierUpdateListener);mBezierAnimation.addListener(mBezierAnimationListener);mRotationAnimation = ValueAnimator.ofFloat(START_ANGLE, END_ANGLE);mRotationAnimation.setDuration(ANIMATION_DURATION / 4);mRotationAnimation.setInterpolator(new AccelerateInterpolator());mRotationAnimation.addUpdateListener(mRotationUpdateListener);mRotationReverseAnimation = ValueAnimator.ofFloat(END_ANGLE, START_ANGLE);mRotationReverseAnimation.setDuration(ANIMATION_DURATION / 4);mRotationReverseAnimation.setInterpolator(new AccelerateInterpolator());mRotationReverseAnimation.addUpdateListener(mRotationUpdateListener);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int desiredWidth;int desiredHeight;desiredWidth = getMeasuredWidth();desiredHeight = getContext().getResources().getDimensionPixelSize(R.dimen.min_height);int widthMode = MeasureSpec.getMode(widthMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);int width;int height;//Measure Widthif (widthMode == MeasureSpec.EXACTLY) {//Must be this sizewidth = widthSize;} else if (widthMode == MeasureSpec.AT_MOST) {//Can't be bigger than...width = Math.min(desiredWidth, widthSize);} else {//Be whatever you wantwidth = desiredWidth;}//Measure Heightif (heightMode == MeasureSpec.EXACTLY) {//Must be this sizeheight = heightSize;} else if (heightMode == MeasureSpec.AT_MOST) {//Can't be bigger than...height = Math.min(desiredHeight, heightSize);} else {//Be whatever you wantheight = desiredHeight;}setMeasuredDimension(width, height);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mCenterX = w / 2;mCenterY = h - mFabButtonRadius;for (int i = 0; i < mNumberOfMenu; i++) {CirclePoint circlePoint = new CirclePoint();circlePoint.setRadius(mGab);circlePoint.setAngle((Math.PI / (mNumberOfMenu + 1)) * (i + 1));mMenuPoints.add(circlePoint);ObjectAnimator animShow = ObjectAnimator.ofFloat(mMenuPoints.get(i), "Radius", 0f, mGab);animShow.setDuration(ANIMATION_DURATION);animShow.setInterpolator(new AnticipateOvershootInterpolator());animShow.setStartDelay((ANIMATION_DURATION * (mNumberOfMenu - i)) / 10);animShow.addUpdateListener(mUpdateListener);mShowAnimation.add(animShow);ObjectAnimator animHide = animShow.clone();animHide.setFloatValues(mGab, 0f);animHide.setStartDelay((ANIMATION_DURATION * i) / 10);mHideAnimation.add(animHide);if (mDrawableArray != null) {for (Drawable drawable : mDrawableArray)drawable.setBounds(0, 0, /*2 * */mMenuButtonRadius,/* 2 * */mMenuButtonRadius);}}}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();mPlusBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.plus);}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();mPlusBitmap = null;mBezierAnimation = null;mHideAnimation.clear();mHideAnimation = null;mShowAnimation.clear();mHideAnimation = null;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);for (int i = 0; i < mNumberOfMenu; i++) {CirclePoint circlePoint = mMenuPoints.get(i);float x = (float) (circlePoint.radius * Math.cos(circlePoint.angle));float y = (float) (circlePoint.radius * Math.sin(circlePoint.angle));canvas.drawCircle(x + mCenterX, mCenterY - y, mMenuButtonRadius, mCirclePaint);if (i < mDrawableArray.size()) {canvas.save();canvas.translate(x + mCenterX - mMenuButtonRadius / 2, mCenterY - y - mMenuButtonRadius / 2);mDrawableArray.get(i).draw(canvas);canvas.restore();}}canvas.save();canvas.translate(mCenterX, mCenterY);Path path = createPath();canvas.drawPath(path, mCirclePaint);canvas.drawPath(path, mCircleBorder);canvas.rotate(mRotationAngle);canvas.drawBitmap(mPlusBitmap, -mPlusBitmap.getWidth() / 2, -mPlusBitmap.getHeight() / 2, mCirclePaint);canvas.restore();}// Use Bezier path to create circle,/*    P_0 = (0,1), P_1 = (c,1), P_2 = (1,c), P_3 = (1,0)P_0 = (1,0), P_1 = (1,-c), P_2 = (c,-1), P_3 = (0,-1)P_0 = (0,-1), P_1 = (-c,-1), P_3 = (-1,-c), P_4 = (-1,0)P_0 = (-1,0), P_1 = (-1,c), P_2 = (-c,1), P_3 = (0,1)with c = 0.551915024494*/private Path createPath() {Path path = new Path();float c = bezierConstant * mFabButtonRadius;path.moveTo(0, mFabButtonRadius);path.cubicTo(bezierConstant * mFabButtonRadius, mFabButtonRadius, mFabButtonRadius, BEZIER_CONSTANT * mFabButtonRadius, mFabButtonRadius, 0);path.cubicTo(mFabButtonRadius, BEZIER_CONSTANT * mFabButtonRadius * (-1), c, (-1) * mFabButtonRadius, 0, (-1) * mFabButtonRadius);path.cubicTo((-1) * c, (-1) * mFabButtonRadius, (-1) * mFabButtonRadius, (-1) * BEZIER_CONSTANT * mFabButtonRadius, (-1) * mFabButtonRadius, 0);path.cubicTo((-1) * mFabButtonRadius, BEZIER_CONSTANT * mFabButtonRadius, (-1) * bezierConstant * mFabButtonRadius, mFabButtonRadius, 0, mFabButtonRadius);return path;}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (isGooeyMenuTouch(event)) {return true;}int menuItem = isMenuItemTouched(event);if (isMenuVisible && menuItem > 0) {if (menuItem <= mDrawableArray.size()) {mDrawableArray.get(mMenuPoints.size() - menuItem).setState(STATE_PRESSED);invalidate();}return true;}return false;case MotionEvent.ACTION_UP:if (isGooeyMenuTouch(event)) {mBezierAnimation.start();cancelAllAnimation();if (isMenuVisible) {startHideAnimate();if (mGooeyMenuInterface != null) {mGooeyMenuInterface.menuClose();}} else {startShowAnimate();if (mGooeyMenuInterface != null) {mGooeyMenuInterface.menuOpen();}}isMenuVisible = !isMenuVisible;return true;}if (isMenuVisible) {menuItem = isMenuItemTouched(event);invalidate();if (menuItem > 0) {if (menuItem <= mDrawableArray.size()) {mDrawableArray.get(mMenuPoints.size() - menuItem).setState(STATE_ACTIVE);postInvalidateDelayed(1000);}if (mGooeyMenuInterface != null) {mGooeyMenuInterface.menuItemClicked(menuItem);}return true;}}return false;}return true;}private int isMenuItemTouched(MotionEvent event) {if (!isMenuVisible) {return -1;}for (int i = 0; i < mMenuPoints.size(); i++) {CirclePoint circlePoint = mMenuPoints.get(i);float x = (float) (mGab * Math.cos(circlePoint.angle)) + mCenterX;float y = mCenterY - (float) (mGab * Math.sin(circlePoint.angle));if (event.getX() >= x - mMenuButtonRadius && event.getX() <= x + mMenuButtonRadius) {if (event.getY() >= y - mMenuButtonRadius && event.getY() <= y + mMenuButtonRadius) {return mMenuPoints.size() - i;}}}return -1;}public void setOnMenuListener(GooeyMenuInterface onMenuListener) {mGooeyMenuInterface = onMenuListener;}public boolean isGooeyMenuTouch(MotionEvent event) {if (event.getX() >= mCenterX - mFabButtonRadius && event.getX() <= mCenterX + mFabButtonRadius) {if (event.getY() >= mCenterY - mFabButtonRadius && event.getY() <= mCenterY + mFabButtonRadius) {return true;}}return false;}// Helper class for animation and Menu Item cicle center Pointspublic class CirclePoint {private float x;private float y;private float radius = 0.0f;private double angle = 0.0f;public void setX(float x1) {x = x1;}public float getX() {return x;}public void setY(float y1) {y = y1;}public float getY() {return y;}public void setRadius(float r) {radius = r;}public float getRadius() {return radius;}public void setAngle(double angle) {this.angle = angle;}public double getAngle() {return angle;}}private void startShowAnimate() {mRotationAnimation.start();for (ObjectAnimator objectAnimator : mShowAnimation) {objectAnimator.start();}}private void startHideAnimate() {mRotationReverseAnimation.start();for (ObjectAnimator objectAnimator : mHideAnimation) {objectAnimator.start();}}private void cancelAllAnimation() {for (ObjectAnimator objectAnimator : mHideAnimation) {objectAnimator.cancel();}for (ObjectAnimator objectAnimator : mShowAnimation) {objectAnimator.cancel();}}ValueAnimator.AnimatorUpdateListener mUpdateListener = new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {invalidate();}};ValueAnimator.AnimatorUpdateListener mBezierUpdateListener = new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {bezierConstant = (float) valueAnimator.getAnimatedValue();invalidate();}};ValueAnimator.AnimatorUpdateListener mRotationUpdateListener = new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {mRotationAngle = (float) valueAnimator.getAnimatedValue();invalidate();}};ValueAnimator.AnimatorListener mBezierAnimationListener = new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animator) {}@Overridepublic void onAnimationEnd(Animator animator) {mBezierEndAnimation.start();}@Overridepublic void onAnimationCancel(Animator animator) {}@Overridepublic void onAnimationRepeat(Animator animator) {}};public interface GooeyMenuInterface {/*** Called when menu opened*/void menuOpen();/*** Called when menu Closed*/void menuClose();/*** Called when Menu item Clicked** @param menuNumber give menu number which clicked.*/void menuItemClicked(int menuNumber);}
}

相关配制文件

values - array.xml中

<?xml version="1.0" encoding="utf-8"?>
<resources><array name="drawable_array"><item>@drawable/item_selector</item><item>@drawable/selector_video</item><!--<item>@drawable/selector_audio</item>--><!--<item>@drawable/selector_photo</item>--><!--<item>@drawable/selector_doc</item>--></array>
</resources>

values - attrs.xml中

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="GooeyMenu"><attr name="no_of_menu" format="integer" /><attr name="fab_radius" format="dimension" /><attr name="menu_radius" format="dimension" /><attr name="gap_between_menu_fab" format="dimension" /><attr name="menu_drawable" format="reference" /></declare-styleable>
</resources>

values - color.xml中

<?xml version="1.0" encoding="utf-8"?>
<resources><color name="default_color">#768F76</color><color name="default_color_dark">#768F76</color><color name="color_red">#FF0000</color>
</resources>

values-dimens.xml中

<resources><!-- Default screen margins, per the Android Design guidelines. --><dimen name="activity_horizontal_margin">16dp</dimen><dimen name="activity_vertical_margin">16dp</dimen><dimen name="min_height">20dp</dimen><!-- 菜单中间按钮的半径--><dimen name="big_circle_radius">20dp</dimen><!-- 弹出菜单按钮的半径--><dimen name="small_circle_radius">15dp</dimen><!-- 子按钮与主按钮间的距离--><dimen name="min_gap">50dp</dimen>
</resources>

在而布局文件中的使用

<RelativeLayout 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:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.administrator.menunewcustom.GooeyMenuandroid:id="@+id/gooey_menu"android:layout_width="match_parent"android:layout_height="match_parent"app:fab_radius="@dimen/big_circle_radius"app:gap_between_menu_fab="@dimen/min_gap"app:menu_radius="@dimen/small_circle_radius"app:no_of_menu="4"app:menu_drawable="@array/drawable_array"/></RelativeLayout><!-- 子按钮与主按钮间的距离--><!--  app:gap_between_menu_fab="@dimen/min_gap"--><!-- 弹出菜单按钮的半径--><!--  app:menu_radius="@dimen/small_circle_radius"--><!-- 设置子菜单 按钮的图片--><!--  app:menu_drawable="@array/drawable_array"--><!-- 设置子菜单的个数--><!--  app:menu_drawable="@array/drawable_array"-->

java代码中的使用

package com.administrator.menunewcustom;import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;public class MainActivity extends ActionBarActivity implements GooeyMenu.GooeyMenuInterface {private GooeyMenu mGooeyMenu;private Toast mToast;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mGooeyMenu = (GooeyMenu) findViewById(R.id.gooey_menu);mGooeyMenu.setOnMenuListener(this);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.menu_main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();//noinspection SimplifiableIfStatementif (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}@Overridepublic void menuOpen() {showToast("Menu Open");}@Overridepublic void menuClose() {showToast( "Menu Close");}@Overridepublic void menuItemClicked(int menuNumber) {showToast( "Menu item clicked : " + menuNumber);}private void showToast(String msg){if(mToast!=null){mToast.cancel();}mToast= Toast.makeText(this,msg,Toast.LENGTH_SHORT);mToast.setGravity(Gravity.CENTER,0,0);mToast.show();}
}

Android_自定义水波纹菜单弹出效果相关推荐

  1. Android 仿 新闻阅读器 菜单弹出效果(附源码DEMO)

    这一系列博文都是:(android高仿系列)今日头条 --新闻阅读器 (一) 开发中碰到问题之后实现的,觉得可能有的开发者用的到或则希望独立成一个小功能DEMO,所以就放出来这么一个DEMO. 原本觉 ...

  2. android实现阅读器底部菜单,android仿新闻阅读器菜单弹出效果实例(附源码DEMO下载)...

    开发中碰到问题之后实现的,觉得可能有的开发者用的到或则希望独立成一个小功能DEMO,所以就放出来这么一个DEMO. 原本觉得是最后完成后发网站客户端的,可是这样体现不出一个功能一个功能的分析实现效果, ...

  3. android 微博底部弹出,Android实现微博菜单弹出效果

    Android实现微博菜单弹出效果 发布时间:2020-08-23 07:48:12 来源:脚本之家 阅读:89 作者:gqdy365 先上Android仿微博菜单弹出效果图,这个截图不是很流畅,大家 ...

  4. android studio菜单自动弹出,Android实现微博菜单弹出效果

    先上Android仿微博菜单弹出效果图,这个截图不是很流畅,大家可以下载apk试一下. 说一下实现思路: 1.截取当前窗口,对图片做高斯模糊处理,将处理后的图片做popupwindow的背景图片: 2 ...

  5. 超酷的计步器APP(一)——炫酷功能实现,自定义水波纹特效、自定义炫酷开始按钮、属性动画的综合体验

    超酷的计步器APP(一)--炫酷功能实现,自定义水波纹特效.自定义炫酷开始按钮.属性动画的综合体验 好久没写博客了,没给大家分享技术了,真是有些惭愧.这段时间我在找工作,今年Android的行情也不怎 ...

  6. Android自定义水波纹动画Layout

    Android自定义水波纹动画Layout 源码是双11的时候就写好了,但是我觉得当天发不太好,所以推迟了几天,没想到过了双11女友就变成了前女友,桑心.唉不说了,来看看代码吧. 展示效果 Hi前辈 ...

  7. 微信小程序第五篇:页面弹出效果及共享元素动画

    系列文章传送门: 微信小程序第一篇:自定义组件详解 微信小程序第二篇:七种主流通信方法详解 微信小程序第三篇:获取页面节点信息 微信小程序第四篇:生成图片并保存到手机相册 目录 一.page-caon ...

  8. ASP.NET Menu控件子菜单弹出导致页面出现滚动条问题

    ASP.NET Menu控件子菜单弹出的时候导致页面CSS属性的Min-Height产生变化,结果是原来全屏的画面,多出了纵滚动条.可以通过如下方法解决: 将ASP.NET控件放置到Table的单元格 ...

  9. 仿简书、淘宝等等App的View弹出效果

    昨天用简书App的时候觉得这个View的弹出效果特别好,而且非常平滑,所以我就尝试写了一个,和简书App上的效果基本一致了: 下面开始讲解: 1.首先我们要知道这个页面有几个View?这个页面其实有四 ...

最新文章

  1. java当前路径和相对路径相关的疑惑
  2. 服务器开机修改grub,修改 grub
  3. python redis 订阅发布_Python-Redis的发布与订阅
  4. 用什么样的个人笔记类软件?OneNote、EverNote(印象笔记)、为知笔记、麦库记事、有道云笔记……...
  5. 在centos7中如何搭建局域网yum源仓库
  6. SocketAPI,CAsyncSocket,CSocket内幕及其用法
  7. Python lambda表达式
  8. [有限元]虚位移原理和虚力原理的证明的统一逻辑
  9. TensorFlow2.0(四)--Keras构建深度神经网络(DNN)
  10. cad小插件文字刷_必备CAD插件大全,内含最全字体库
  11. 软考 - 数据库系统工程师
  12. 世界坐标系、相机坐标系和图像坐标系的转换
  13. Hybrid App 开发快速指南
  14. 香港有个荷里活。。。
  15. 你办培训机构还不知道教育培训管理系统?
  16. Affine-Transformation Parameters Regression for Face Alignment
  17. Qt设计一个给图像打掩膜的界面
  18. 微信公众号支付WeixinJSBridge
  19. ensp 移动主机搜索不到AP信道_H3C H5套装评测,AC+AP无缝漫游
  20. 基于STM32F103设计的智能门锁(支持多种开锁解锁方式)

热门文章

  1. 快准狠!Intel论文揭示自家车牌识别算法:LPRNet
  2. css倒序循环,不借助后台和 JS ,只用 CSS 让一个列表编号倒序
  3. linux系统挂载磁盘慢,arch开机速度竟然是挂载磁盘拖慢了。。
  4. 【机器学习】机器学习从零到掌握之二 -- 教你实现K近邻算法
  5. 【Matplotlib】【Python】如何使用matplotlib绘制绘制随机生成的点--随机漫步详解
  6. 一份清华大佬的代码模版,简洁易懂!
  7. 内卷到逆天!机器学习领域不读PhD,我配不配找工作?
  8. Github | 深度学习研究大咖有哪些?
  9. 收藏 | Python数据分析必备速查表
  10. 请不要把数据分析和机器学习混为一谈