Android 使用 Path 实现搜索动态加载动画效果

所属分类: 软件编程 / Android 阅读数: 70
收藏 0 赞 0 分享

今天实现一个搜索动态加载数据的动画效果,还是先看效果吧,用文字描述干巴巴的,看图说话什么都明白了,

实现这个就是使用Path中的getSegment()不断的去改变它截取片段的start和stop,再结合动画,今天就分步骤实现它,看完以后你也会觉的不是很难,只是没想到这么实现而已,所以要多见识,所谓眼界决定你的高度,还是延续我写博客的习惯,一步步分析,第一步就是绘制如下图:

如果单纯的绘制这个图很简单很简单的,绘制一个圆,然后再绘制一根线就搞定,但是要考虑这里的效果,就不能这么干了,如果你看了上面的gif图就知道,其实这是2个同心圆,然后前一个path的起点和后一个path的起点相连接就是形成一条直线了,但是path中的图形内容也就是这个圆是怎么绘制出来的呢?如果是绘制圆的话,上面的线起点和终点位置怎么去计算,这是个问题,但是我们绘制圆还可以使用绘制椭圆的形式也是可以绘制达到圆的效果,从45度开始绘制一个圆,是不是这个线的起点搞定了,分析图如下:

那么好,根据上面的分析开始写代码绘制出一个静态的搜索图:

package com.tuya;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by admin on 2016/12/17.
 */
public class DynamicSearchView2 extends View {
 private Paint paint;
 private int width;//view的宽度
 private int height;//view的高度
 private Path searchPath;
 private Path circlePath;
 private float BigCircleRectWidth;//搜索圆对应的外切正方形边长
 private PathMeasure pathMeasure;
 private float[] pos;
 public DynamicSearchView2(Context context) {
  this(context,null);
 }
 public DynamicSearchView2(Context context, AttributeSet attrs) {
  this(context, attrs,0);
 }
 public DynamicSearchView2(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }
 private void init() {
  paint = new Paint();
  paint.setAntiAlias(true);
  paint.setStrokeWidth(3);
  paint.setColor(Color.WHITE);
  paint.setStyle(Paint.Style.STROKE);
 }
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  width = w;
  height = h;
  initPath();
 }
 /**
  * 初始化path
  */
 private void initPath() {
  searchPath = new Path();
  circlePath = new Path();
  if(width>height){//长方形
   BigCircleRectWidth = height;
  }else if(width<height){
   BigCircleRectWidth = width;
  }else{
   BigCircleRectWidth = width;
  }
  float smallbordWidth =BigCircleRectWidth/8;
  RectF searchRect = new RectF(-smallbordWidth,-smallbordWidth,smallbordWidth,smallbordWidth);
  searchPath.addArc(searchRect,45,360);
  float bigBordWidth = smallbordWidth*2;
  RectF circleRect = new RectF(-bigBordWidth,-bigBordWidth,bigBordWidth,bigBordWidth);
  circlePath.addArc(circleRect,45,-360);
  pathMeasure = new PathMeasure(circlePath,false);
  pos = new float[2];
  pathMeasure.getPosTan(0,pos,null);
  searchPath.lineTo(pos[0],pos[1]);
 }
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  canvas.translate(width/2,height/2);//平移画布把这个view的中心点当做原点
  canvas.drawPath(searchPath,paint);
  canvas.drawPath(circlePath,paint);
 }
}

效果图:

本来这个外圆是不需要draw上去的,我在这绘制上去只是告诉你这二个圆是有一定的联系,哪为什么这根线是这样的呢?我们在绘制这个圆的时候是从45度开始绘制360刚好是一周,形成了一个圆,现在做个测试不要360,就写个330度,效果如下:

这个时候你会发现这条线是对的,导致问题其实是这样的,如图分析:

把绘制椭圆的关键代码:

searchPath.addArc(searchRect,45,358);

circlePath.addArc(circleRect,45,-358);

不要写成360,改为358试试,效果图:


发现这线是不是正常了,至于外面的圆还有点缺口,第一你可以把358改成359应该没事了,还有就是我们其实真实的效果并不需要这个外面的圆,所以不改也没事,那么好,第一步算是完成了,现在想想第二步怎么实现,先把第二步的效果用gif展示看下,不然光想没思路,就像你看美女,第一眼看那,是吧,就不多说了!要有画面感,

还是画布分析:


哪我们只要改变startD这个离起始点的位置值就ok,当然有很多种方法,但是Android中基本上都是使用值动画,ok,根据这个思路实现这个第二步逻辑:

package com.tuya;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by admin on 2016/12/17.
 */
public class DynamicSearchView2 extends View {
 private Paint paint;
 private int width;//view的宽度
 private int height;//view的高度
 private Path searchPath;
 private Path circlePath;
 private float BigCircleRectWidth;//搜索圆对应的外切正方形边长
 private PathMeasure pathMeasure;
 private float[] pos;
 private float animPercent;//
 private ValueAnimator serchStartAnim;
 private long animDuration = 2000;//动画时间
 public DynamicSearchView2(Context context) {
  this(context,null);
 }
 public DynamicSearchView2(Context context, AttributeSet attrs) {
  this(context, attrs,0);
 }
 public DynamicSearchView2(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }
 private void init() {
  initPaint();
  initAnim();
  initAnimListener();
  startAnim();
 }
 /**
  * 开始执行动画
  */
 private void startAnim() {
  serchStartAnim.start();
 }
 /**
  * 动画监听
  */
 private void initAnimListener() {
  serchStartAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
     //获取动画在单位时间内,每次执行的值
    animPercent = (float) valueAnimator.getAnimatedValue();
    invalidate();
   }
  });
 }
 /**
  * 初始化动画
  */
 private void initAnim() {
  serchStartAnim = ValueAnimator.ofFloat(0,1).setDuration(animDuration);
 }
 /**
  * 初始化画笔
  */
 private void initPaint() {
  paint = new Paint();
  paint.setAntiAlias(true);
  paint.setStrokeWidth(3);
  paint.setColor(Color.WHITE);
  paint.setStyle(Paint.Style.STROKE);
 }

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  width = w;
  height = h;
  initPath();
 }
 /**
  * 初始化path
  */
 private void initPath() {
  searchPath = new Path();
  circlePath = new Path();
  if(width>height){//长方形
   BigCircleRectWidth = height;
  }else if(width<height){
   BigCircleRectWidth = width;
  }else{
   BigCircleRectWidth = width;
  }
  float smallbordWidth =BigCircleRectWidth/8;
  RectF searchRect = new RectF(-smallbordWidth,-smallbordWidth,smallbordWidth,smallbordWidth);

  searchPath.addArc(searchRect,45,358);
  float bigBordWidth = smallbordWidth*2;
  RectF circleRect = new RectF(-bigBordWidth,-bigBordWidth,bigBordWidth,bigBordWidth);
  circlePath.addArc(circleRect,45,-358);
  pathMeasure = new PathMeasure(circlePath,false);
  pos = new float[2];
  pathMeasure.getPosTan(0,pos,null);
  searchPath.lineTo(pos[0],pos[1]);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
   canvas.translate(width/2,height/2);//平移画布把这个view的中心点当做原点
   drawSearch(canvas);
 }
 private void drawSearch(Canvas canvas) {
  Path dst = new Path();
  pathMeasure.setPath(searchPath,false);
  pathMeasure.getSegment(pathMeasure.getLength()*animPercent,pathMeasure.getLength(),dst,true);
  canvas.drawPath(searchPath,paint);
 }
}

效果:

现在还我们效果还差外圆的大圆的效果了,那么大圆是在小圆动画执行完毕后再去做旋转效果的,那好,我们只要监听动画就可以,画图:

package com.tuya;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by admin on 2016/12/17.
 */
public class DynamicSearchView2 extends View {
 private static final String TAG = "DynamicSearchView2";
 private Paint paint;
 private int width;//view的宽度
 private int height;//view的高度
 private Path searchPath;
 private Path circlePath;
 private float BigCircleRectWidth;//搜索圆对应的外切正方形边长
 private PathMeasure pathMeasure;
 private float[] pos;
 private float animPercent;//
 private ValueAnimator serchStartAnim;
 private ValueAnimator bigCircleAnim;//外面大圆运动的动画
 private long animDuration = 2000;//动画时间
 private int drawTag = 1;//区分是绘制搜索框还是外层圆
 public DynamicSearchView2(Context context) {
  this(context,null);
 }
 public DynamicSearchView2(Context context, AttributeSet attrs) {
  this(context, attrs,0);
 }
 public DynamicSearchView2(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }
 private void init() {
  initPaint();
  initAnim();
  initAnimListener();
  startAnim();
 }
 /**
  * 开始执行动画
  */
 private void startAnim() {
  drawTag = 1;
  serchStartAnim.start();
  invalidate();
 }
 /**
  * 开启大圆执行动画
  */
 public void startBigCirCleAnim(){
  serchStartAnim.removeAllUpdateListeners();//把上一个动画监听移除 以免总成诡异的bug
  bigCircleAnim.start();
  drawTag = 2;
 }
 /**
  * 动画监听
  */
 private void initAnimListener() {
  serchStartAnim.addListener(new Animator.AnimatorListener() {
   @Override
   public void onAnimationStart(Animator animator) {
   }
   @Override
   public void onAnimationEnd(Animator animator) {
    startBigCirCleAnim();
   }
   @Override
   public void onAnimationCancel(Animator animator) {
   }
   @Override
   public void onAnimationRepeat(Animator animator) {
   }
  });
  serchStartAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    //获取动画在单位时间内,每次执行的值
    animPercent = (float) valueAnimator.getAnimatedValue();
    invalidate();
   }
  });
  bigCircleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    //获取动画在单位时间内,每次执行的值
    animPercent = (float) valueAnimator.getAnimatedValue();
    invalidate();
   }
  });
 }
 /**
  * 初始化动画
  */
 private void initAnim() {
  bigCircleAnim = ValueAnimator.ofFloat(0,1).setDuration(animDuration);
  serchStartAnim = ValueAnimator.ofFloat(0,1).setDuration(animDuration);
 }
 /**
  * 初始化画笔
  */
 private void initPaint() {
  paint = new Paint();
  paint.setAntiAlias(true);
  paint.setStrokeWidth(3);
  paint.setColor(Color.WHITE);
  paint.setStyle(Paint.Style.STROKE);
 }
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  width = w;
  height = h;
  initPath();
 }
 /**
  * 初始化path
  */
 private void initPath() {
  searchPath = new Path();
  circlePath = new Path();
  if(width>height){//长方形
   BigCircleRectWidth = height;
  }else if(width<height){
   BigCircleRectWidth = width;
  }else{
   BigCircleRectWidth = width;
  }
  float smallbordWidth =BigCircleRectWidth/8;
  RectF searchRect = new RectF(-smallbordWidth,-smallbordWidth,smallbordWidth,smallbordWidth);

  searchPath.addArc(searchRect,45,358);
  float bigBordWidth = smallbordWidth*2;
  RectF circleRect = new RectF(-bigBordWidth,-bigBordWidth,bigBordWidth,bigBordWidth);
  circlePath.addArc(circleRect,45,-358);
  pathMeasure = new PathMeasure(circlePath,false);
  pos = new float[2];
  pathMeasure.getPosTan(0,pos,null);
  searchPath.lineTo(pos[0],pos[1]);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  canvas.translate(width/2,height/2);//平移画布把这个view的中心点当做原点
  drawSearch(canvas);
 }
 private void drawSearch(Canvas canvas) {
  if(drawTag==1){
   drawSearchGraph(canvas);
  }else if(drawTag==2){
   drawBigCircleGraph(canvas);
  }
 }
 /**
  * 绘制外层大圆
  * @param canvas
  */
 private void drawBigCircleGraph(Canvas canvas) {
  pathMeasure.setPath(circlePath, false);
  Path dst2 = new Path();
  float stop = pathMeasure.getLength() * animPercent;
  float start = (float) (stop - ((0.5 - Math.abs(animPercent - 0.5)) * 200f));
  pathMeasure.getSegment(start, stop, dst2, true);
  canvas.drawPath(dst2, paint);
 }
 /**
  * 绘制搜索框
  * @param canvas
  */
 private void drawSearchGraph(Canvas canvas) {
  pathMeasure.setPath(searchPath,false);
  Path dst = new Path();
  pathMeasure.getSegment(pathMeasure.getLength()*animPercent,pathMeasure.getLength(),dst,true);
  canvas.drawPath(dst,paint);
 }
}

效果:

发现转一圈就到头了,如果有特定的需求肯定是要控制整个转圈的圈数,如果是网络加载的话,除非网络特别的好,先不管了,因为等下还要写周报,也是很痛苦的

现在还差最后一步就是大圆的运动完后要绘制搜索框出来,其实这个和第一步效果刚好是相关的,

package com.tuya;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by admin on 2016/12/17.
 */
public class DynamicSearchView2 extends View {
 private static final String TAG = "DynamicSearchView2";
 private Paint paint;
 private int width;//view的宽度
 private int height;//view的高度
 private Path searchPath;
 private Path circlePath;
 private float BigCircleRectWidth;//搜索圆对应的外切正方形边长
 private PathMeasure pathMeasure;
 private float[] pos;
 private float animPercent;//
 private ValueAnimator serchStartAnim;
 private ValueAnimator bigCircleAnim;//外面大圆运动的动画
 private ValueAnimator startDrawSearchAnim;//最后一步绘制搜索框
 private long animDuration = 2000;//动画时间
 private int drawTag = 1;//区分是绘制搜索框还是外层圆
 public DynamicSearchView2(Context context) {
  this(context,null);
 }
 public DynamicSearchView2(Context context, AttributeSet attrs) {
  this(context, attrs,0);
 }
 public DynamicSearchView2(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }
 private void init() {
  initPaint();
  initAnim();
  initAnimListener();
  startAnim();
 }
 /**
  * 开始执行动画
  */
 private void startAnim() {
  drawTag = 1;
  serchStartAnim.start();
  invalidate();
 }
 /**
  * 开启大圆执行动画
  */
 public void startBigCirCleAnim(){
  serchStartAnim.removeAllUpdateListeners();//把上一个动画监听移除 以免总成诡异的bug
  bigCircleAnim.start();
  drawTag = 2;
 }
 /**
  * 最后绘制搜索框的动画
  */
 public void drawSearchAanim(){
  bigCircleAnim.removeAllUpdateListeners();//把上一个动画监听移除 以免总成诡异的bug
  startDrawSearchAnim.start();
  drawTag = 3;
 }
 /**
  * 动画监听
  */
 private void initAnimListener() {
  bigCircleAnim.addListener(new Animator.AnimatorListener() {
   @Override
   public void onAnimationStart(Animator animator) {
   }
   @Override
   public void onAnimationEnd(Animator animator) {
    drawSearchAanim();
   }
   @Override
   public void onAnimationCancel(Animator animator) {
   }
   @Override
   public void onAnimationRepeat(Animator animator) {
   }
  });
  serchStartAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    //获取动画在单位时间内,每次执行的值
    animPercent = (float) valueAnimator.getAnimatedValue();
    invalidate();
   }
  });
  serchStartAnim.addListener(new Animator.AnimatorListener() {
   @Override
   public void onAnimationStart(Animator animator) {
   }
   @Override
   public void onAnimationEnd(Animator animator) {
    startBigCirCleAnim();
   }
   @Override
   public void onAnimationCancel(Animator animator) {
   }
   @Override
   public void onAnimationRepeat(Animator animator) {
   }
  });
  serchStartAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    //获取动画在单位时间内,每次执行的值
    animPercent = (float) valueAnimator.getAnimatedValue();
    invalidate();
   }
  });
  bigCircleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    //获取动画在单位时间内,每次执行的值
    animPercent = (float) valueAnimator.getAnimatedValue();
    invalidate();
   }
  });
  startDrawSearchAnim .addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    //获取动画在单位时间内,每次执行的值
    animPercent = (float) valueAnimator.getAnimatedValue();
    invalidate();
   }
  });
 }
 /**
  * 初始化动画
  */
 private void initAnim() {
  bigCircleAnim = ValueAnimator.ofFloat(0,1).setDuration(animDuration);
  serchStartAnim = ValueAnimator.ofFloat(0,1).setDuration(animDuration);
  startDrawSearchAnim = ValueAnimator.ofFloat(1,0).setDuration(animDuration);
 }
 /**
  * 初始化画笔
  */
 private void initPaint() {
  paint = new Paint();
  paint.setAntiAlias(true);
  paint.setStrokeWidth(6);
  paint.setColor(Color.WHITE);
  paint.setStyle(Paint.Style.STROKE);
 }
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  width = w;
  height = h;
  initPath();
 }
 /**
  * 初始化path
  */
 private void initPath() {
  searchPath = new Path();
  circlePath = new Path();
  if(width>height){//长方形
   BigCircleRectWidth = height;
  }else if(width<height){
   BigCircleRectWidth = width;
  }else{
   BigCircleRectWidth = width;
  }
  float smallbordWidth =BigCircleRectWidth/8;
  RectF searchRect = new RectF(-smallbordWidth,-smallbordWidth,smallbordWidth,smallbordWidth);
  searchPath.addArc(searchRect,45,358);
  float bigBordWidth = smallbordWidth*2;
  RectF circleRect = new RectF(-bigBordWidth,-bigBordWidth,bigBordWidth,bigBordWidth);
  circlePath.addArc(circleRect,45,-358);
  pathMeasure = new PathMeasure(circlePath,false);
  pos = new float[2];
  pathMeasure.getPosTan(0,pos,null);
  searchPath.lineTo(pos[0],pos[1]);
 }
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  canvas.translate(width/2,height/2);//平移画布把这个view的中心点当做原点
  drawSearch(canvas);
 }
 private void drawSearch(Canvas canvas) {
  if(drawTag==1){
   drawSearchGraph(canvas);
  }else if(drawTag==2){
   drawBigCircleGraph(canvas);
  }else if(drawTag==3){
   drawSearchBox(canvas);
  }
 }
 /**
  * 最后一步绘制搜索框 从终点到起点
  * @param canvas
  */
 private void drawSearchBox(Canvas canvas) {
  pathMeasure.setPath(searchPath, false);
  Path dst3 = new Path();
  pathMeasure.getSegment(pathMeasure.getLength() * animPercent, pathMeasure.getLength(), dst3, true);
  canvas.drawPath(dst3, paint);
 }
 /**
  * 绘制外层大圆
  * @param canvas
  */
 private void drawBigCircleGraph(Canvas canvas) {
  pathMeasure.setPath(circlePath, false);
  Path dst2 = new Path();
  float stop = pathMeasure.getLength() * animPercent;
  float start = (float) (stop - ((0.5 - Math.abs(animPercent - 0.5)) * 200f));
  pathMeasure.getSegment(start, stop, dst2, true);
  canvas.drawPath(dst2, paint);
 }
 /**
  * 绘制搜索框
  * @param canvas
  */
 private void drawSearchGraph(Canvas canvas) {
  pathMeasure.setPath(searchPath,false);
  Path dst = new Path();
  pathMeasure.getSegment(pathMeasure.getLength()*animPercent,pathMeasure.getLength(),dst,true);
  canvas.drawPath(dst,paint);
 }
}

效果:

github: https://github.com/zhouguizhi/PathSearch

以上所述是小编给大家介绍的Android 使用 Path 实现搜索动态加载动画效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

更多精彩内容其他人还在看

Android框架学习之Volley和Glide详解

这篇文章主要给大家介绍了关于Android框架学习之Volley和Glide的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Android中Fragment的基本用法示例总结

Fragment是activity的界面中的一部分或一种行为,下面这篇文章主要给大家介绍了关于Android中Fragment的基本用法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
收藏 0 赞 0 分享

Android.mk引入第三方jar包和so库文件的方法

这篇文章主要介绍了Android.mk引入第三方jar包和so库文件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android仿微信录制小视频

这篇文章主要为大家详细介绍了Android仿微信录制小视频,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

android实现一键锁屏和一键卸载的方法实例

这篇文章主要给大家介绍了关于android如何实现一键锁屏和一键卸载的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
收藏 0 赞 0 分享

Android手势密码--设置和校验功能的实现代码

这篇文章主要介绍了Android手势密码--设置和校验功能的实现代码,非常不错,具有一定的参考校验价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Kotlin学习笔记之const val与val

这篇文章主要给大家介绍了关于Kotlin学习笔记之const val与val的相关资料,并给大家介绍了const val和val区别以及Kotlin中var和val的区别,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Android实现调用系统分享功能示例的总结

这篇文章主要介绍了通过Android调用系统分享文本信息、单张图片、多个文件和指定分享到微信、QQ,同时分享图片和文字的功能示例,小编觉得挺不错,一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android自定义view实现输入控件

这篇文章主要为大家详细介绍了Android自定义view实现输入控件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android使用Intent.ACTION_SEND分享图片和文字内容的示例代码

这篇文章主要介绍了Android使用Intent.ACTION_SEND分享图片和文字内容的示例代码的实例代码,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多