自定义viewgroup实现ArcMenu

最终效果如下

实现思路

通过效果图,会有几个问题:
a、动画效果如何实现
可以看出动画是从顶点外外发射的,可能有人说,那还不简单,默认元素都在定点位置,然后TraslateAnimation就好了;这样忽略了一点,就是TraslateAnimation虽然有动画效果,但是本质是不会改变按钮的位置,我们的按钮动画结束是要点击的;有人可能会说那使用属性动画,或者改变leftMagin,rightMagin;这样可能比较麻烦,其实我们可以默认让子菜单就已经在目标位置,然后GONE,当点击时还是用TraslateAnimation,把起始位置设为定点,终点位置就是我们隐藏的区域,动画结束VISIBLE.

b、如何确定位置呢?

每次会根据子菜单数量,算出a这个角度,然后通过sin , cos 分别算出每个子菜单的left , top ;
当然这是在左上的情况,如果在右上,则top还是和左上一致的,left则为 (屏幕宽度-左上算出的left) ;其他两个方位同理~

整体我通过自定义一个ViewGroup,这个ViewGroup中第一个子元素为点击的按钮(你可以随便布局,随便用什么控件),接下来的子元素我认为是菜单项。根据效果图,决定展开半径和显示的位置,让用户自己去定制。下面看具体实现:

自定义View的属性

<?xml version="1.0" encoding="utf-8"?>
<resources><attr name="position"><enum name="left_top" value="0" /><enum name="right_top" value="1" /><enum name="right_bottom" value="2" /><enum name="left_bottom" value="3" /></attr><attr name="radius" format="dimension"></attr><declare-styleable name="ArcMenu"><attr name="position" /><attr name="radius"/></declare-styleable></resources>

在自定义的ViewGroup中获取这些属性

/** * @author zhy */  
public class ArcMenu extends ViewGroup implements OnClickListener  
{  private static final String TAG = "ArcMenu";  /** * 菜单的显示位置 */  private Position mPosition = Position.LEFT_TOP;  /** * 菜单显示的半径,默认100dp */  private int mRadius = 100;  /** * 用户点击的按钮 */  private View mButton;  /** * 当前ArcMenu的状态 */  private Status mCurrentStatus = Status.CLOSE;  /** * 回调接口 */  private OnMenuItemClickListener onMenuItemClickListener;  /** * 状态的枚举类 *  * @author zhy *  */  public enum Status  {  OPEN, CLOSE  }  /** * 设置菜单现实的位置,四选1,默认右下 *  * @author zhy */  public enum Position  {  LEFT_TOP, RIGHT_TOP, RIGHT_BOTTOM, LEFT_BOTTOM;  }  public interface OnMenuItemClickListener  {  void onClick(View view, int pos);  }  public ArcMenu(Context context)  {  this(context, null);  }  public ArcMenu(Context context, AttributeSet attrs)  {  this(context, attrs, 0);  }  /** * 初始化属性 *  * @param context * @param attrs * @param defStyle */  public ArcMenu(Context context, AttributeSet attrs, int defStyle)  {  super(context, attrs, defStyle);  // dp convert to px  mRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,  mRadius, getResources().getDisplayMetrics());  TypedArray a = context.getTheme().obtainStyledAttributes(attrs,  R.styleable.ArcMenu, defStyle, 0);  int n = a.getIndexCount();  for (int i = 0; i < n; i++)  {  int attr = a.getIndex(i);  switch (attr)  {  case R.styleable.ArcMenu_position:  int val = a.getInt(attr, 0);  switch (val)  {  case 0:  mPosition = Position.LEFT_TOP;  break;  case 1:  mPosition = Position.RIGHT_TOP;  break;  case 2:  mPosition = Position.RIGHT_BOTTOM;  break;  case 3:  mPosition = Position.LEFT_BOTTOM;  break;  }  break;  case R.styleable.ArcMenu_radius:  // dp convert to px  mRadius = a.getDimensionPixelSize(attr, (int) TypedValue  .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100f,  getResources().getDisplayMetrics()));  break;  }  }  a.recycle();  }

计算子元素的大小

@Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  {  int count = getChildCount();  for (int i = 0; i < count; i++)  {  // mesure child  getChildAt(i).measure(MeasureSpec.UNSPECIFIED,  MeasureSpec.UNSPECIFIED);  }  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  }  

确定子元素的位置

@Override  protected void onLayout(boolean changed, int l, int t, int r, int b)  {  if (changed)  {  layoutButton();  int count = getChildCount();  /** * 设置所有孩子的位置 例如(第一个为按钮): 左上时,从左到右 ] 第2个:mRadius(sin0 , cos0) * 第3个:mRadius(sina ,cosa) 注:[a = Math.PI / 2 * (cCount - 1)] * 第4个:mRadius(sin2a ,cos2a) 第5个:mRadius(sin3a , cos3a) ... */  for (int i = 0; i < count - 1; i++)  {  View child = getChildAt(i + 1);  child.setVisibility(View.GONE);  int cl = (int) (mRadius * Math.sin(Math.PI / 2 / (count - 2)  * i));  int ct = (int) (mRadius * Math.cos(Math.PI / 2 / (count - 2)  * i));  // childview width  int cWidth = child.getMeasuredWidth();  // childview height  int cHeight = child.getMeasuredHeight();  // 右上,右下  if (mPosition == Position.LEFT_BOTTOM  || mPosition == Position.RIGHT_BOTTOM)  {  ct = getMeasuredHeight() - cHeight - ct;  }  // 右上,右下  if (mPosition == Position.RIGHT_TOP  || mPosition == Position.RIGHT_BOTTOM)  {  cl = getMeasuredWidth() - cWidth - cl;  }  Log.e(TAG, cl + " , " + ct);  child.layout(cl, ct, cl + cWidth, ct + cHeight);  }  }  }  

首先在layoutButton中对按钮位置就行设置,以及初始化点击事件;然后从第二个子元素开始为菜单项,分别设置其位置,计算的原理就是上面我画的草图,可以再去仔细看看,动手在纸上画一画

/** * 第一个子元素为按钮,为按钮布局且初始化点击事件 */  
private void layoutButton()  
{  View cButton = getChildAt(0);  cButton.setOnClickListener(this);  int l = 0;  int t = 0;  int width = cButton.getMeasuredWidth();  int height = cButton.getMeasuredHeight();  switch (mPosition)  {  case LEFT_TOP:  l = 0;  t = 0;  break;  case LEFT_BOTTOM:  l = 0;  t = getMeasuredHeight() - height;  break;  case RIGHT_TOP:  l = getMeasuredWidth() - width;  t = 0;  break;  case RIGHT_BOTTOM:  l = getMeasuredWidth() - width;  t = getMeasuredHeight() - height;  break;  }  Log.e(TAG, l + " , " + t + " , " + (l + width) + " , " + (t + height));  cButton.layout(l, t, l + width, t + height);  }  

这是定位Button的代码,此时的代码已经实现了定位,如果你把onLayout中childView.setVisibility(VISIBLE)。ArcMenu的整个控件的样子已经实现了,接下来就是点击事件,已经效果动画的实现了。

设置按钮点击事件

/** * 为按钮添加点击事件 */  @Override  public void onClick(View v)  {  mButton = findViewById(R.id.id_button);  if (mButton == null)  {  mButton = getChildAt(0);  }  rotateView(mButton, 0f, 270f, 300);  toggleMenu(300);  }  
/** * 按钮的旋转动画 *  * @param view * @param fromDegrees * @param toDegrees * @param durationMillis */  public static void rotateView(View view, float fromDegrees,  float toDegrees, int durationMillis)  {  RotateAnimation rotate = new RotateAnimation(fromDegrees, toDegrees,  Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  0.5f);  rotate.setDuration(durationMillis);  rotate.setFillAfter(true);  view.startAnimation(rotate);  }  public void toggleMenu(int durationMillis)  {  int count = getChildCount();  for (int i = 0; i < count - 1; i++)  {  final View childView = getChildAt(i + 1);  childView.setVisibility(View.VISIBLE);  int xflag = 1;  int yflag = 1;  if (mPosition == Position.LEFT_TOP  || mPosition == Position.LEFT_BOTTOM)  xflag = -1;  if (mPosition == Position.LEFT_TOP  || mPosition == Position.RIGHT_TOP)  yflag = -1;  // child left  int cl = (int) (mRadius * Math.sin(Math.PI / 2 / (count - 2) * i));  // child top  int ct = (int) (mRadius * Math.cos(Math.PI / 2 / (count - 2) * i));  AnimationSet animset = new AnimationSet(true);  Animation animation = null;  if (mCurrentStatus == Status.CLOSE)  {// to open  animset.setInterpolator(new OvershootInterpolator(2F));  animation = new TranslateAnimation(xflag * cl, 0, yflag * ct, 0);  childView.setClickable(true);  childView.setFocusable(true);  } else  {// to close  animation = new TranslateAnimation(0f, xflag * cl, 0f, yflag  * ct);  childView.setClickable(false);  childView.setFocusable(false);  }  animation.setAnimationListener(new AnimationListener()  {  public void onAnimationStart(Animation animation)  {  }  public void onAnimationRepeat(Animation animation)  {  }  public void onAnimationEnd(Animation animation)  {  if (mCurrentStatus == Status.CLOSE)  childView.setVisibility(View.GONE);  }  });  animation.setFillAfter(true);  animation.setDuration(durationMillis);  // 为动画设置一个开始延迟时间,纯属好看,可以不设  animation.setStartOffset((i * 100) / (count - 1));  RotateAnimation rotate = new RotateAnimation(0, 720,  Animation.RELATIVE_TO_SELF, 0.5f,  Animation.RELATIVE_TO_SELF, 0.5f);  rotate.setDuration(durationMillis);  rotate.setFillAfter(true);  animset.addAnimation(rotate);  animset.addAnimation(animation);  childView.startAnimation(animset);  final int index = i + 1;  childView.setOnClickListener(new View.OnClickListener()  {  @Override  public void onClick(View v)  {  if (onMenuItemClickListener != null)  onMenuItemClickListener.onClick(childView, index - 1);  menuItemAnin(index - 1);  changeStatus();  }  });  }  changeStatus();  Log.e(TAG, mCurrentStatus.name() +"");  }  

点击时,触发TanslateAnimation动画,从定点向外扩展,也给点击按钮添加了一个旋转动画,每个子菜单项同样添加了旋转动画,且如果用户设置回调,调用回调接口;设置子菜单的点击事件。整体就是点击然后动画效果~~

设置子菜单的点击事件

/** * 开始菜单动画,点击的MenuItem放大消失,其他的缩小消失 * @param item */  private void menuItemAnin(int item)  {  for (int i = 0; i < getChildCount() - 1; i++)  {  View childView = getChildAt(i + 1);  if (i == item)  {  childView.startAnimation(scaleBigAnim(300));  } else  {  childView.startAnimation(scaleSmallAnim(300));  }  childView.setClickable(false);  childView.setFocusable(false);  }  }  /** * 缩小消失 * @param durationMillis * @return */  private Animation scaleSmallAnim(int durationMillis)  {  Animation anim = new ScaleAnimation(1.0f, 0f, 1.0f, 0f,  Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  0.5f);  anim.setDuration(durationMillis);  anim.setFillAfter(true);  return anim;  }  /** * 放大,透明度降低 * @param durationMillis * @return */  private Animation scaleBigAnim(int durationMillis)  {  AnimationSet animationset = new AnimationSet(true);  Animation anim = new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f,  Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  0.5f);  Animation alphaAnimation = new AlphaAnimation(1, 0);  animationset.addAnimation(anim);  animationset.addAnimation(alphaAnimation);  animationset.setDuration(durationMillis);  animationset.setFillAfter(true);  return animationset;  }  

点击的菜单项变大且慢慢透明消失,未点击的菜单项缩小消失~有兴趣的可以改成自己喜欢的动画~
注:动画效果很多借鉴了eoe上那位仁兄的代码,这类动画也比较简单,就不多说了~

好了,剩下就是些getter,setter了~

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:zhy="http://schemas.android.com/apk/res/com.example.zhy_arcmenu"android:layout_width="match_parent"android:layout_height="match_parent" ><com.example.zhy_arcmenu.ArcMenu
        android:id="@+id/id_arcmenu1"android:layout_width="fill_parent"android:layout_height="fill_parent"zhy:position="left_top"zhy:radius="130dp" ><RelativeLayout
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/composer_button" ><ImageView
                android:id="@+id/id_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_icn_plus" /></RelativeLayout><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_camera"android:tag="Camera" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_sun"android:tag="Sun" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_place"android:tag="Place" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_sleep"android:tag="Sleep" /></com.example.zhy_arcmenu.ArcMenu><com.example.zhy_arcmenu.ArcMenu
        android:layout_width="fill_parent"android:layout_height="fill_parent"zhy:position="right_bottom"zhy:radius="130dp" ><RelativeLayout
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/composer_button" ><ImageView
                android:id="@+id/id_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_icn_plus" /></RelativeLayout><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_camera"android:tag="Camera" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_sun"android:tag="Sun" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_place"android:tag="Place" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_sleep"android:tag="Sleep" /></com.example.zhy_arcmenu.ArcMenu><com.example.zhy_arcmenu.ArcMenu
        android:layout_width="fill_parent"android:layout_height="fill_parent"zhy:position="left_bottom"zhy:radius="130dp" ><RelativeLayout
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/composer_button" ><ImageView
                android:id="@+id/id_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_icn_plus" /></RelativeLayout><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_sun"android:tag="Sun" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_place"android:tag="Place" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_sleep"android:tag="Sleep" /></com.example.zhy_arcmenu.ArcMenu><com.example.zhy_arcmenu.ArcMenu
        android:layout_width="fill_parent"android:layout_height="fill_parent"zhy:position="right_top"zhy:radius="130dp" ><RelativeLayout
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/composer_button" ><ImageView
                android:id="@+id/id_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_icn_plus" /></RelativeLayout><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_camera"android:tag="Camera" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_sun"android:tag="Sun" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_place"android:tag="Place" /><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/composer_sleep"android:tag="Sleep" /></com.example.zhy_arcmenu.ArcMenu></RelativeLayout>

MainActivity

package com.example.zhy_arcmenu;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.Toast;import com.example.zhy_arcmenu.ArcMenu.OnMenuItemClickListener;public class MainActivity extends Activity
{private ArcMenu mArcMenuLeftTop;@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mArcMenuLeftTop = (ArcMenu) findViewById(R.id.id_arcmenu1);//动态添加一个MenuItemImageView people = new ImageView(this);people.setImageResource(R.drawable.composer_with);people.setTag("People");mArcMenuLeftTop.addView(people);mArcMenuLeftTop.setOnMenuItemClickListener(new OnMenuItemClickListener(){@Overridepublic void onClick(View view, int pos){Toast.makeText(MainActivity.this,pos + ":" + view.getTag(), Toast.LENGTH_SHORT).show();}});}}

注意

本文中用到了android TypedValue.applyDimension,这个方法是转变为标准尺寸的一个函数

参考链接

android TypedValue.applyDimension()的作用 - BuleRiver的专栏 - 博客频道 - CSDN.NET

Animation.setFillAfter and Animation.setFillBefore的作用

动画终止时停留在最后一帧~不然会回到没有执行之前的状态

参考链接

Animation.setFillAfter and Animation.setFillBefore的作用 - PuerTea - 博客园

关于animation的详细介绍

详情参见

【TweenedAnimation】四种动画效果参数详解(自测所得) - 邪天殇 - 博客园

Animation & Property Animation 使用 - Ajian_studio - 博客频道 - CSDN.NET

本文主要参考

Android 自定义ViewGroup手把手教你实现ArcMenu - Hongyang - 博客频道 - CSDN.NET

源代码下载

源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/494127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

也谈谈Atiyah关于黎曼猜想的证明

来源&#xff1a;潇轩社作者&#xff1a;叶扬波 著名数学家&#xff0c;美国爱荷华大学教授。作为数论学家&#xff0c;他在中国大陆出版有《迹公式与模形式》等专著。以下是他谈Atiyah关于黎曼猜想的证明的文章&#xff0c;观点专业而且独到&#xff0c;转载此文&#xff0c;…

大型Javascript应用架构的模式(译文)

附上翻译好的word文件 http://files.cnblogs.com/lizhug/Patterns_For_Large-Scale_JavaScript_Application_Architecture.zip 作者&#xff1a;Addy Osmani 技术评审&#xff1a;Andree Hansson 翻译&#xff1a;李珠刚 珠刚参上 今天我们将要探讨一系列用于大型Javascri…

Animation Property Animation 使用

本篇主要讲Animation 和 Property Animation的使用&#xff0c;最后会讲QQ管家桌面火箭作为例子&#xff1a; 在Android中开发动效有两套框架可以使用&#xff0c;分别为 Animation 和 Property Animation&#xff1b; 相对来说&#xff0c;Animator比Animation要强大太多&…

华为云力推“普惠AI”,EI智能体正在落地行业

来源&#xff1a;北京物联网智能技术应用协会云计算和人工智能是什么关系&#xff1f;一般认为&#xff0c;云计算是人工智能的基础之一。而华为云则认为&#xff0c;要推动人工智能的落地&#xff0c;拥有“算法、算力和数据”还是不足够的&#xff0c;还需要“行业智慧”&…

Android中mesure过程详解

我们在编写layout的xml文件时会碰到layout_width和layout_height两个属性&#xff0c;对于这两个属性我们有三种选择&#xff1a;赋值成具体的数值&#xff0c;match_parent或者wrap_content&#xff0c;而measure过程就是用来处理match_parent或者wrap_content&#xff0c;假如…

黑科技揭秘 | 阿里云“天空物联网”连接范围如何达到700平方公里

来源&#xff1a;阿里云还记得前不久在2018杭州云栖大会上&#xff0c;由飞在天上的飞艇、地下基站共同搭建的阿里云“天空物联网”吗&#xff1f;它实现从地面40000米高空到地下20米的覆盖&#xff0c;并持续为大会服务。体现了持续加码的阿里巴巴物联网战略。在飞艇背后&…

JAVA-用栈机制实现单词逆序排列

就是IO那一段还没学到。 之前的PUCH,POP,STRING和CHAR的关系搞得懂了。 学到一个定位STRING当中CHAR的转换函数。 char String.charAt(x) 1 import java.io.*;2 3 4 class stackString5 {6 private int maxSize;7 private char[] stackX;8 private int top;9 …

Android自定义实现FlowLayout

实现FlowLayout 何为FlowLayout&#xff0c;如果对Java的Swing比较熟悉的话一定不会陌生&#xff0c;就是控件根据ViewGroup的宽&#xff0c;自动的往右添加&#xff0c;如果当前行剩余空间不足&#xff0c;则自动添加到下一行。有点所有的控件都往左飘的感觉&#xff0c;第一…

【重磅】马斯克遇终极麻烦:被起诉欺诈罪 或丢掉CEO职位 特斯拉暴跌约13%

参考&#xff1a;CNBC、Bloomberg编译&#xff1a;网易智能编辑&#xff1a;丁广胜参与&#xff1a;小小美国当地时间周四&#xff0c;法庭的文件显示特斯拉电动汽车公司首席执行官伊隆马斯克(Elon Musk)已被美国证券交易委员会(SEC)以欺诈罪起诉。与特斯拉关系密切的消息人士透…

《麻省理工科技评论》:2018年18大科技趋势,2017年7大失败技术

来源&#xff1a;科技周摘要&#xff1a;2018 年伊始&#xff0c;许多科技大势仍在继续&#xff0c;正如比尔盖茨所说&#xff0c;“大多数人高估了某种技术的短期价值&#xff0c;低估了其长期价值。”同样&#xff0c;大多数的年度预测会高估了一年内一些事件发生的可能性&am…

Android实现支持缩放平移图片

本文主要用到了以下知识点 MatrixGestureDetector 能够捕捉到长按、双击ScaleGestureDetector 用于检测缩放的手势 自由的缩放 需求&#xff1a;当图片加载时&#xff0c;将图片在屏幕中居中&#xff1b;图片宽或高大于屏幕的&#xff0c;缩小至屏幕大小&#xff1b;自由对图…

放麦子

题意&#xff1a; 国际象棋&#xff0c;一共64个方格&#xff0c;第一个格子里放一粒麦子&#xff0c;第二个放2粒&#xff0c;第三个放4粒&#xff0c;第四个放8粒。。。。。&#xff08;后面的数字是前面的两倍&#xff09; 求放满64个格子&#xff0c;一共需要多少粒麦子。 …

Material Design风格登录注册

本文实现了以下功能 完整的代码和样例托管在Github当接口锁定时&#xff0c;防止后退按钮显示在登录Activity 上。自定义 ProgressDialog来显示加载的状态。符合材料设计规范。悬浮标签&#xff08;floating labels&#xff09;&#xff08;来自设计支持库&#xff09;用户表单…

英特尔反驳质疑:芯片供应充足、10nm量产没问题

来源&#xff1a;华尔街见闻摘要&#xff1a;英特尔称2018年会将资本支出增加10亿美元&#xff0c;至总额创纪录的150亿美元&#xff1b;CEO称&#xff0c;个人电脑需求意外回升&#xff0c;但有足够供应满足市场&#xff0c;有望达成全年营收目标&#xff0c;股价涨近4%。竞争…

RecyclerView拖拽排序和滑动删除实现

效果图 如何实现 那么是如何实现的呢&#xff1f;主要就要使用到ItemTouchHelper &#xff0c;ItemTouchHelper 一个帮助开发人员处理拖拽和滑动删除的实现类&#xff0c;它能够让你非常容易实现侧滑删除、拖拽的功能。 实现的代码非常简单我们只需要两步&#xff1a; 实例化…

马斯克刚刚宣布辞去特斯拉董事会职务,仍然担任CEO

来源&#xff1a;大数据文摘编译&#xff1a;蒋宝尚据悉&#xff0c;当地时间周六&#xff0c;马斯克辞去特斯拉董事会主席一职&#xff0c;并且支付2000万美元罚款。以表示对美国证券交易委员会(SEC)指控的回应。SEC的指控来源于马斯克8月7日的一篇推文。推文中&#xff0c;他…

JavaScript 实现 GriwView 单列全选

在 GridView 里有一系列的 Checkbox &#xff0c;要实现对其全选或全不选。开始在网上找了&#xff0c;但是参考的代码会全选 GridView 里所有的 Checkbox &#xff0c;而我要的是单列全选。如图&#xff1a; 审核和权限是要分开的。 我自己写了 JavaScript 代码&#xff0c;贴…

自然语言处理(NLP)前沿进展报告

来源&#xff1a;专知摘要&#xff1a;2018年9 月 9 日-14 日&#xff0c;DeepMind主办的Deep Learning Indaba 2018 大会在南非斯泰伦博斯举行。会上&#xff0c;斯坦陵布什大学Herman Kamper和AYLIEN的Sebastian Ruder等专家做了《自然语言处理前言进展》的报告。报告首先探讨…

Android下利用Bitmap切割图片

在自己自定义的一个组件中由于需要用图片显示数字编号&#xff0c;而当前图片就只有一张&#xff0c;上面有0-9是个数字&#xff0c;于是不得不考虑将其中一个个的数字切割下来&#xff0c;需要显示什么数字&#xff0c;只需要组合一下就好了。 下面是程序的关键代码&#xff…

两种不同的人工智能观:工程观点和科学观点

来源&#xff1a;人机与认知实验室作者按&#xff1a;人工智能是作为工程还是科学&#xff0c;这个问题是一个很严肃的问题&#xff0c;如果从工程技术角度来看人工智能&#xff0c;那么认知科学尤其是认知心理学、神经生理学对人类这样的生物智能的原理性认识&#xff0c;就不…