Android自定义控件进阶——Canvas之图片文字

本次了解一些绘制图片文字相关的内容。如果你对前几篇文章讲述的内容熟练掌握的话,那么恭喜你,本篇结束之后,大部分的自定义View已经难不倒你了,当然了,这并不是终点,接下来还会有更加炫酷的技能。

一.Canvas的常用操作速查表

操作类型 相关API 备注
绘制颜色 drawColor,drawRGB,drawARGB 使用单一颜色填充整个画布
绘制基本形状 drawPoint,drawPoints,drawLine,drawLines,drawRect,drawRoundRect,drawOval,drawCircle,drawArc 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧
绘制图片 drawBitmap,drawPicture 绘制位图和图片
绘制文本 drawText,drawPosText,drawTextOnPath 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字
绘制路径 drawPath 绘制路径,绘制贝塞尔曲线时也需要用到该函数
顶点操作 drawVertices,drawBitmapMesh 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用
画布剪裁 clipPath,clipRect 设置画布的显示区域
画布快照 save,restore,saveLayerXxx,restoreToCount,getSaveCount 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数
画布变换 translate,scale,rotate,skew 依次为 位移、缩放、 旋转、错切
Matrix(矩阵) getMatrix,setMatrix,concat 实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。

二.Canvas基本操作详解

1.绘制图片

绘制有两种方法,drawPicture(矢量图) 和 drawBitmap(位图),接下来我们一一了解。

(1)drawPicture

使用Picture前请关闭硬件加速,以免引起不必要的问题!使用Picture前请关闭硬件加速,以免引起不必要的问题!使用Picture前请关闭硬件加速,以免引起不必要的问题!

在AndroidMenifest文件中application节点下添上 android:hardwareAccelerated=”false”以关闭整个应用的硬件加速。更多请参考这里:Android的硬件加速及可能导致的问题

关于drawPicture一开始还是挺让人费解的,不过嘛,我们接下来慢慢研究一下它的用途。

既然是drawPicture就要了解一下什么是Picture。 顾名思义,Picture的意思是图片。

不过嘛,我觉得这么用图片这个名词解释Picture是不合适的,为何这么说?请看其官方文档对Picture的解释:

A Picture records drawing calls (via the canvas returned by beginRecording) and can then play them back into Canvas (via draw(Canvas) or drawPicture(Picture)).For most content (e.g. text,lines,rectangles),drawing a sequence from a picture can be faster than the equivalent API calls,since the picture performs its playback without incurring any method-call overhead.

好吧,我知道很多人对这段鸟语是看不懂的,至于为什么要放在这里,仅仅是为了显得更加专业(偷笑)。

下面我就对这段不明觉厉的鸟语用通俗的话翻译一下:

某一天小萌想在朋友面前显摆一下,于是在单杠上来了一个后空翻,动作姿势请参照下图:

朋友都说 恩,很不错。 想再看一遍 (〃ω〃)。ヽ(〃∀〃)ノ。⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄

于是小萌又来了一遍,如是几次之后,小萌累的吐血三升。

于是小萌机智的想,我何不能用手机将我是飒爽英姿录下来呢,直接保存成为后空翻.avi 下次想显摆的时候直接拿出手机,点一下播放就行了,省时省力。

小萌被自己的机智深深的折服了,然后Picture就诞生啦。(╯‵□′)╯︵┻━┻掀桌,坑爹呢,这剧情跳跃也忒大了吧。

好吧,言归正传,这次我们了解的Picture和上文中的录像功能是类似的,只不过我们Picture录的是Canvas中绘制的内容。

我们把Canvas绘制点,线,矩形等诸多操作用Picture录制下来,下次需要的时候拿来就能用,使用Picture相比于再次调用绘图API,开销是比较小的,也就是说对于重复的操作可以更加省时省力。

PS:你可以把Picture看作是一个录制Canvas操作的录像机。

了解了Picture的概念之后,我们再了解一下Picture的相关方法。

相关方法 简介
public int getWidth () 获取宽度
public int getHeight () 获取高度
public Canvas beginRecording (int width,int height) 开始录制 (返回一个Canvas,在Canvas中所有的绘制都会存储在Picture中)
public void endRecording () 结束录制
public void draw (Canvas canvas) 将Picture中内容绘制到Canvas中
public static Picture createFromStream (InputStream stream) (已废弃)通过输入流创建一个Picture
public void writeToStream (OutputStream stream) (已废弃)将Picture中内容写出到输出流中

上面表格中基本上已经列出了Picture的所有方法,其中getWidth和getHeight没什么好说的,最后两个已经废弃也自然就不用关注了,排除了这些方法之后,只剩三个方法了,接下来我们就比较详细的了解一下:

很明显,beginRecording 和 endRecording 是成对使用的,一个开始录制,一个是结束录制,两者之间的操作将会存储在Picture中。

使用示例:

准备工作:

录制内容,即将一些Canvas操作用Picture存储起来,录制的内容是不会直接显示在屏幕上的,只是存储起来了而已。

// 1.创建Picture
private Picture mPicture = new Picture();

---------------------------------------------------------------

// 2.录制内容方法
private void recording() {
    // 开始录制 (接收返回值Canvas)
    Canvas canvas = mPicture.beginRecording(500,500);
    // 创建一个画笔
    Paint paint = new Paint();
    paint.setColor(Color.BLUE);
    paint.setStyle(Paint.Style.FILL);

    // 在Canvas中具体操作
    // 位移
    canvas.translate(250,250);
    // 绘制一个圆
    canvas.drawCircle(0,100,paint);

    mPicture.endRecording();
}

---------------------------------------------------------------

// 3.在使用前调用(我在构造函数中调用了)
  public Canvas3(Context context,AttributeSet attrs) {
    super(context,attrs);
    
    recording();    // 调用录制
}

具体使用:

Picture虽然方法就那么几个,但是具体使用起来还是分很多情况的,由于录制的内容不会直接显示,就像存储的视频不点击播放不会自动播放一样,同样,想要将Picture中的内容显示出来就需要手动调用播放(绘制),将Picture中的内容绘制出来可以有以下几种方法:

序号 简介
1 使用Picture提供的draw方法绘制。
2 使用Canvas提供的drawPicture方法绘制。
3 将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。

以上几种方法主要区别:

主要区别 分类 简介
是否对Canvas有影响 1有影响 2,3不影响 此处指绘制完成后是否会影响Canvas的状态(Matrix clip等)
可操作性强弱 1可操作性较弱 2,3可操作性较强 此处的可操作性可以简单理解为对绘制结果可控程度。

几种方法简介和主要区别基本就这么多了,接下来对于各种使用方法一一详细介绍:

1.使用Picture提供的draw方法绘制:

// 将Picture中的内容绘制在Canvas上
mPicture.draw(canvas);  

PS:这种方法在比较低版本的系统上绘制后可能会影响Canvas状态,所以这种方法一般不会使用。

2.使用Canvas提供的drawPicture方法绘制

drawPicture有三种方法:

public void drawPicture (Picture picture)

public void drawPicture (Picture picture,Rect dst)

public void drawPicture (Picture picture,RectF dst)

和使用Picture的draw方法不同,Canvas的drawPicture不会影响Canvas状态。

简单示例:

canvas.drawPicture(mPicture,new RectF(0,mPicture.getWidth(),200));

PS:对照上一张图片,可以比较明显的看出,绘制的内容根据选区进行了缩放。

3.将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。

// 包装成为Drawable
PictureDrawable drawable = new PictureDrawable(mPicture);
// 设置绘制区域 -- 注意此处所绘制的实际内容不会缩放
drawable.setBounds(0,250,mPicture.getHeight());
// 绘制
drawable.draw(canvas);

PS:此处setBounds是设置在画布上的绘制区域,并非根据该区域进行缩放,也不是剪裁Picture,每次都从Picture的左上角开始绘制。

注意:在使用Picture之前请关闭硬件加速,以免引起不必要的问题,如何关闭请参考这里: Android的硬件加速及可能导致的问题

(2)drawBitmap

其实一开始知道要讲Bitmap我是拒绝的,为什么呢?因为Bitmap就是很多问题的根源啊有木有,Bitmap可能导致内存不足,内存泄露,ListView中的复用混乱等诸多问题。想完美的掌控Bitmap还真不是一件容易的事情。限于篇幅本文对于Bitmap不会过多的展开,只讲解一些常用的功能

既然要绘制Bitmap,就要先获取一个Bitmap,那么如何获取呢?

获取Bitmap方式:

序号 获取方式 备注
1 通过Bitmap创建 复制一个已有的Bitmap(新Bitmap状态和原有的一致) 或者 创建一个空白的Bitmap(内容可改变)
2 通过BitmapDrawable获取 从资源文件 内存卡 网络等地方获取一张图片并转换为内容不可变的Bitmap
3 通过BitmapFactory获取 从资源文件 内存卡 网络等地方获取一张图片并转换为内容不可变的Bitmap

通常来说,我们绘制Bitmap都是读取已有的图片转换为Bitmap绘制到Canvas上。 很明显,第1种方式不能满足我们的要求,暂时排除。 第2种方式虽然也可满足我们的要求,但是我不推荐使用这种方式,至于为什么在后续详细讲解Drawable的时候会说明,暂时排除。 第3种方法我们会比较详细的说明一下如何从各个位置获取图片。

通过BitmapFactory从不同位置获取Bitmap:

资源文件(drawable/mipmap/raw):

Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),R.raw.bitmap);

资源文件(assets):

Bitmap bitmap=null;
try {
    InputStream is = mContext.getAssets().open("bitmap.png");
    bitmap = BitmapFactory.decodeStream(is);
    is.close();
} catch (IOException e) {
    e.printStackTrace();
}

内存卡文件:

Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/bitmap.png");

网络文件:

// 此处省略了获取网络输入流的代码
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();

既然已经获得到了Bitmap,那么就开始本文的重点了,将Bitmap绘制到画布上。

绘制Bitmap:

依照惯例先预览一下drawBitmap的常用方法:

// 第一种
public void drawBitmap (Bitmap bitmap,Matrix matrix,Paint paint)

// 第二种
public void drawBitmap (Bitmap bitmap,float left,float top,Paint paint)

// 第三种
public void drawBitmap (Bitmap bitmap,Rect src,Rect dst,Paint paint)
public void drawBitmap (Bitmap bitmap,RectF dst,Paint paint)

第一种方法中后两个参数(matrix,paint)是在绘制的时候对图片进行一些改变,如果只是需要将图片内容绘制出来只需要如下操作就可以了:

PS:图片左上角位置默认为坐标原点。

canvas.drawBitmap(bitmap,new Matrix(),new Paint());

关于Matrix和Paint暂时略过吧,一展开又是啰啰嗦嗦一大段,反正挖坑已经是常态了,大家应该也习惯了(PAP).

第二种方法就是在绘制时指定了图片左上角的坐标(距离坐标原点的距离):

注意:此处指定的是与坐标原点的距离,并非是与屏幕顶部和左侧的距离,虽然默认状态下两者是重合的,但是也请注意分别两者的不同。

canvas.drawBitmap(bitmap,200,500,new Paint());

第三种方法比较有意思,上面多了两个矩形区域(src,dst),这两个矩形选区是干什么用的?

名称 作用
Rect src 指定绘制图片的区域
Rect dst 或RectF dst 指定图片在屏幕上显示(绘制)的区域

示例:

// 将画布坐标系移动到画布中央
canvas.translate(mWidth/2,mHeight/2);

// 指定图片绘制区域(左上角的四分之一)
Rect src = new Rect(0,bitmap.getWidth()/2,bitmap.getHeight()/2);

// 指定图片在屏幕上显示的区域
Rect dst = new Rect(0,400);

// 绘制图片
canvas.drawBitmap(bitmap,src,dst,null);

详解:

上面是以绘制该图为例,用src指定了图片绘制部分的区域,即下图中红色方框标注的区域。

然后用dst指定了绘制在屏幕上的绘制,即下图中蓝色方框标注的区域,图片宽高会根据指定的区域自动进行缩放。

从上面可知,第三种方法可以绘制图片的一部分到画布上,这有什么用呢?

如果你看过某些游戏的资源文件,你可能会看到如下的图片(图片来自网络):

用一张图片包含了大量的素材,在绘制的时候每次只截取一部分进行绘制,这样可以大大的减少素材数量,而且素材管理起来也很方便。

然而这和我们有什么关系呢?我们又不做游戏开发。

确实,我们不做游戏开发,但是在某些时候我们需要制作一些炫酷的效果,这些效果因为太复杂了用代码很难实现或者渲染效率不高。这时候很多人就会想起帧动画,将动画分解成一张一张的图片然后使用帧动画制作出来,这种实现方式的确比较简单,但是一个动画效果的图片有十几到几十张,一个应用里面来几个这样炫酷的动画效果就会导致资源文件出现一大堆,想找其中的某一张资源图片简直就是灾难啊有木有。但是把同一个动画效果的所有资源图片整理到一张图片上,会大大的减少资源文件数量,方便管理,妈妈再也不怕我找不到资源文件了,同时也节省了图片文件头、文件结束块以及调色板等占用的空间。

下面是利用drawBitmap第三种方法制作的一个简单示例:

资源文件如下:

最终效果如下:

源码如下:

PS:由于是示例代码,做的很粗糙,仅作为学习示例,不建议在任何实际项目中使用。

查看源码https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/Code/CheckView.md

2.绘制文字

依旧预览一下相关常用方法:

// 第一类
public void drawText (String text,float x,float y,Paint paint)
public void drawText (String text,int start,int end,Paint paint)
public void drawText (CharSequence text,Paint paint)
public void drawText (char[] text,int index,int count,Paint paint)

// 第二类
public void drawPosText (String text,float[] pos,Paint paint)
public void drawPosText (char[] text,Paint paint)

// 第三类
public void drawTextOnPath (String text,Path path,float hOffset,float vOffset,Paint paint)
public void drawTextOnPath (char[] text,Paint paint)

PS 其中的CharSequence和String的区别可以到这里看看:https://github.com/GcsSloop/AndroidNote/issues/16

绘制文字部分大致可以分为三类:

第一类只能指定文本基线位置(基线x默认在字符串左侧,基线y默认在字符串下方)。 第二类可以分别指定每个文字的位置。 第三类是指定一个路径,根据路径绘制文字。

通过上面常用方法的参数也可看出,绘制文字也是需要画笔的,而且文字的大小,颜色,字体,对齐方式都是由画笔控制的。

不过嘛这里仅简单介绍几种常用方法(反正挖坑多了也不怕),具体在讲解Paint时再详细讲解。

Paint文本相关常用方法表

标题 相关方法 备注
色彩 setColor setARGB setAlpha 设置颜色,透明度
大小 setTextSize 设置文本字体大小
字体 setTypeface 设置或清除字体样式
样式 setStyle 填充(FILL),描边(STROKE),填充加描边(FILL_AND_STROKE)
对齐 setTextAlign 左对齐(LEFT),居中对齐(CENTER),右对齐(RIGHT)
测量 measureText 测量文本大小(注意,请在设置完文本各项参数后调用)

为了绘制文本,我们先创建一个文本画笔:

Paint textPaint = new Paint();          // 创建画笔
textPaint.setColor(Color.BLACK);        // 设置颜色
textPaint.setStyle(Paint.Style.FILL);   // 设置样式
textPaint.setTextSize(50);              // 设置字体大小

第一类(drawText)

第一类可以指定文本开始的位置,可以截取文本中部分内容进行绘制。

其中x,y两个参数是指定文本绘制两个基线,示例:

// 文本(要绘制的内容)
String str = "ABCDEFG";

// 参数分别为 (文本 基线x 基线y 画笔)
canvas.drawText(str,textPaint);

PS: 图中字符串下方的红线是基线y,基线x未在图中画出。

当然啦,除了能指定绘制文本的起始位置,还能只取出文本中的一部分内容进行绘制。

截取文本中的一部分,对于String和CharSequence来说只指定字符串下标start和end位置(注意:0<= start < end < str.length())

以上一个例子使用的字符串为例,它的下标是这样的(等一下,我为啥要说这个,算了,不管了,就这样吧。

(๑•́ ₃ •̀๑)

字符 A B C D E F G
下标 0 1 2 3 4 5 6

假设我我们指定star为1,end为3,那么最终截取的字符串就是”BC”。

一般来说,使用start和end指定的区间是前闭后开的,即包含start指定的下标,而不包含end指定的下标,故[1,3)最后获取到的下标只有 下标1 和 下标2 的字符,就是”BC”.

示例:

// 文本(要绘制的内容)
String str = "ABCDEFG";

// 参数分别为 (字符串 开始截取位置 结束截取位置 基线x 基线y 画笔)
canvas.drawText(str,1,3,textPaint);

另外,对于字符数组char[]我们截取字符串使用起始位置(index)和长度(count)来确定。

同样,我们指定index为1,count为3,那么最终截取到的字符串是”BCD”.

其实就是从下标位置为1处向后数3位就是截取到的字符串,示例:

// 字符数组(要绘制的内容)
char[] chars = "ABCDEFG".toCharArray();

// 参数为 (字符数组 起始坐标 截取长度 基线x 基线y 画笔)
canvas.drawText(chars,textPaint);

第二类(drawPosText)

通过和第一类比较,我们可以发现,第二类中没有指定x,y坐标的参数,而是出现了这样一个参数float[] pos

好吧,这个名为pos的浮点型数组就是指定坐标的,至于为啥要用数组嘛,因为这家伙野心比较大,想给每个字符都指定一个位置。

示例:

String str = "SLOOP";

canvas.drawPosText(str,new float[]{
      100,// 第一个字符位置
      200,// 第二个字符位置
      300,300,// ...
      400,400,500
},textPaint);

不过嘛,虽然虽然这个方法也比较容易理解,但是关于这个方法我个人是不推荐使用的,因为坑比较多,主要有一下几点:

序号 反对理由
1 必须指定所有字符位置,否则直接crash掉,反人类设计
2 性能不佳,在大量使用的时候可能导致卡顿
3 不支持emoji等特殊字符,不支持字形组合与分解

关于第二类的第二种方法:

public void drawPosText (char[] text,Paint paint)

和上面一样,就是从字符数组中切出来一段进行绘制,相信以诸位看官的聪明才智一眼就看出来了,我这里就不多说了,真的不是我偷懒啊(ˉ▽ ̄~) ~~

第三类(drawTextOnPath)

第三类要用到path这个大杀器,作为一个厉害角色怎么能这么轻易露脸呢,先保持一下神秘感,也就是说,下回再和大家见面喽。

三.总结

学会了图片和文字绘制,对于大部分自定义View都能制作了,可以去看看这位大神制作的作品,尝试模仿一下 一个绚丽的loading动效分析与实现!

更多Android 知识点可参考

Android 性能调优系列https://0a.fit/dNHYY

Android 车载学习指南https://0a.fit/jdVoy

Android Framework核心知识点笔记https://0a.fit/acnLL

Android 八大知识体系https://0a.fit/mieWJ

Android 中高级面试题锦https://0a.fit/YXwVq

原文地址:https://blog.csdn.net/weixin_61845324

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


更新Android SDK到3.0版本时,遇到Failed to rename directory E:\android\tools to E:\android\temp\ToolPackage.old01问题,导致无法更新,出现该问题的原因是由于3.0版本与较早的sdk版本之间文件结构有冲突,解决
Android 如何解决dialog弹出时无法捕捉Activity的back事件 在一些情况下,我们需要捕捉back键事件,然后在捕捉到的事件里写入我们需要进行的处理,通常可以采用下面三种办法捕捉到back事件: 1)重写onKeyDown或者onKeyUp方法 2)重写onBackPressed方
Android实现自定义带文字和图片的Button 在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法。一.用系统自带的Button实现 最简单的一种办法就是利用系统自带的Button来实现,这种方式代码量最小。在Button的属性中有一个是drawable
Android中的&quot;Unable to start activity ComponentInfo&quot;的错误 最近在做一款音乐播放器的时候,然后在调试的过程中发现一直报这个错误&quot;Unable to start activity ComponentInfo&quot;,从字面
Android 关于长按back键退出应用程序的实现最近在做一个Android上的应用,碰到一个问题就是如何实现长按back键退出应用程序。在网上查找了很多资料,发现几乎没有这样的实现,大部分在处理时是双击back键来退出应用程序。参考了一下双击back键退出应用程序的代码,网上主流的一种方法是下面
android自带的时间选择器只能精确到分,但是对于某些应用要求选择的时间精确到秒级,此时只有自定义去实现这样的时间选择器了。下面介绍一个可以精确到秒级的时间选择器。 先上效果图: 下面是工程目录: 这个控件我也是用的别人的,好像是一个老外写的,com.wheel中的WheelView是滑动控件的主
Android平台下利用zxing实现二维码开发 现在走在大街小巷都能看到二维码,而且最近由于项目需要,所以研究了下二维码开发的东西,开源的二维码扫描库主要有zxing和zbar,zbar在iPos平台上应用比较成熟,而在Android平台上主流还是用zxing库,因此这里主要讲述如何利用zxing
Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的item默认的外观,下面讲解以下在使用listview时最常见的几个问题。1.如何改变item的背景色和按
如何向Android模拟器中导入含有中文名称的文件在进行Android开发的时候,如果需要向Android模拟器中导入文件进行测试,通过DDMS下手动导入或者在命令行下通过adb push命令是无法导入含有中文文件名的文件的。后来发现借用其他工具可以向模拟器中导入中文名称的文件,这个工具就是Ultr
Windows 下搭建Android开发环境一.下载并安装JDK版本要求JDK1.6+,下载JDK成功后进行安装,安装好后进行环境变量的配置【我的电脑】-——&gt;【属性】——&gt;【高级】 ——&gt;【环境变量】——&gt;【系统变量】中点击【新建】:变量名:CLASSPATH变量值:……
如何利用PopupWindow实现弹出菜单并解决焦点获取以及与软键盘冲突问题 在android中有时候可能要实现一个底部弹出菜单,此时可以考虑用PopupWindow来实现。下面就来介绍一下如何使用PopupWindow实现一个弹出窗。 主Activity代码:public void onCreat
解决Android中的ERROR: the user data image is used by another emulator. aborting的方法 今天调试代码的时候,突然出现这个错误,折腾了很久没有解决。最后在google上找到了大家给出的两种解决方案,下面给出这两种方法的链接博客:ht
AdvserView.java package com.earen.viewflipper; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory;
ImageView的scaleType的属性有好几种,分别是matrix(默认)、center、centerCrop、centerInside、fitCenter、fitEnd、fitStart、fitXY。 |值|说明| |:--:|:--| |center|保持原图的大小,显示在ImageVie
文章浏览阅读8.8k次,点赞9次,收藏20次。本文操作环境:win10/Android studio 3.21.环境配置 在SDK Tools里选择 CMAKE/LLDB/NDK点击OK 安装这些插件. 2.创建CMakeLists.txt文件 在Project 目录下,右键app,点击新建File文件,命名为CMakeLists.txt点击OK,创建完毕! 3.配置文件 在CMa..._link c++ project with gradle
文章浏览阅读1.2w次,点赞15次,收藏69次。实现目的:由mainActivity界面跳转到otherActivity界面1.写好两个layout文件,activity_main.xml和otherxml.xmlactivity_main.xml&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;RelativeLayout ="http://schemas..._android studio 界面跳转
文章浏览阅读3.8w次。前言:最近在找Android上的全局代理软件来用,然后发现了这两款神作,都是外国的软件,而且都是开源的软件,因此把源码下载了下来,给有需要研究代理这方面的童鞋看看。不得不说,国外的开源精神十分浓,大家相互使用当前基础的开源软件,然后组合成一个更大更强的大开源软件。好吧,废话不多说,下面简单介绍一下这两款开源项目。一、ProxyDroid:ProxyDroid功能比较强大,用到的技术也比较多,源码也_proxydroid
文章浏览阅读2.5w次,点赞17次,收藏6次。创建项目后,运行项目时Gradle Build 窗口却显示错误:程序包R不存在通常情况下是不会出现这个错误的。我是怎么遇到这个错误的呢?第一次创建项目,company Domain我使用的是:aven.com,但是创建过程在卡在了Building 'Calculator' Gradle Project info这个过程中,于是我选择了“Cancel”第二次创建项目,我还是使用相同的项目名称和项目路_r不存在
文章浏览阅读8.9w次,点赞4次,收藏43次。前言:在Android上使用系统自带的代理,限制灰常大,仅支持系统自带的浏览器。这样像QQ、飞信、微博等这些单独的App都不能使用系统的代理。如何让所有软件都能正常代理呢?ProxyDroid这个软件能帮你解决!使用方法及步骤如下:一、推荐从Google Play下载ProxyDroid,目前最新版本是v2.6.6。二、对ProxyDroid进行配置(基本配置:) (1) Auto S_proxydroid使用教程
文章浏览阅读1.1w次,点赞4次,收藏17次。Android Studio提供了一个很实用的工具Android设备监视器(Android device monitor),该监视器中最常用的一个工具就是DDMS(Dalvik Debug Monitor Service),是 Android 开发环境中的Dalvik虚拟机调试监控服务。可以进行的操作有:为测试设备截屏,查看特定进程中正在运行的线程以及堆栈信息、Logcat、广播状态信息、模拟电话_安卓摄像头调试工具