gcssloop / androidnote Goto Github PK
View Code? Open in Web Editor NEW安卓学习笔记
Home Page: http://www.gcssloop.com/#blog
安卓学习笔记
Home Page: http://www.gcssloop.com/#blog
为什么你会感觉错 因为 物体显示和摄像机的运动是相反的;
rawable用于标记一个可绘制对象 待续。
ViewGroup 和 ChildView 同时注册了事件监听器(onClick等),哪个会执行?
事件优先给 ChildView,会被 ChildView消费掉,ViewGroup 不会响应。
这个好像不符合事件传递机制
错误:升级AndroidStudio时引起的错误。
解决方案:
应该是 1角度=π弧度/180 。1弧度=180度/π。
好像是写反了,另外感谢您的教程。
Matrix m = new Matrix();
m.reset();
m.preTranslate(tx, ty); //使用pre,越靠后越先执行。
m.preScale(sx, sy);
这里为什么越靠后先执行啊,矩阵乘法我记得是从左往右进行乘法计算的呀(╯‵□′)╯︵┻━┻
在实际工作或学习过程中,很多地方都需要展示一些过程,或者展示动态的效果,使用视频显得比较大了,而且也不利于分享,故使用GIF就是一种很好的方法,体积小,易于分享展示。
此处大部分参考自 廖祜秋(我们的秋百万大哥) 整理的内容: Make GIF Snapshot for Android APP
制作GIF一般分为以下两种情况:
类别 | 说明 | 备注 |
---|---|---|
第一种 | 在电脑上可以看到效果 | 在模拟器中运行的app,视频等 |
第二种 | 在手机上可以看到效果 | 在真机中运行的app |
第一种方法比较容易直接录制屏幕然后转换为GIF就行了,有很多可视化的制作软件,这里推荐几种:
名称 | 说明 | 地址 |
---|---|---|
都叫兽GIF | 可视化GIF制作工具,支持录制后再次编辑,不同程度压缩,添加水印等功能,但默认右下角有一个都叫兽的水印,不适合强迫症患者 | 都叫兽GIF Windows直接下载 |
LICEcap | 可视化GIF制作工具,支持编辑录制区域大小,可改变录制帧率,功能没有上面多,但用起来很简单 | LICEcap Windows直接下载 |
ezgif | 在线制作GIF的工具,这个的功能也很强大,支持将多张图片合成为GIF,将视频转换为GIF,剪切旋转等多种操作 | ezgif |
虽然手机上也有一些录屏GIF制作软件,但是大部分都很渣,很难达到我们想要的效果。
我个人一般是将操作过程录制下来,然后发送到电脑上,用电脑软件截取GIF,也就是转为第一种方法。
这个用起来很方便,录制后能直接保存在电脑上。
1.选到该选项卡
2.上面一个按钮是截屏,下面一个按钮是录屏。
作为一个程序猿,虽然可视化操作很爽,但不会两条命令怎么能装逼呢。下面就教大家如何用命令录屏。
$ adb shell // 进入shell
shell@ $ screenrecord --verbose /sdcard/demo.mp4 // 开始录制(保存到内存卡上)
(press Ctrl-C to stop) // 按Ctrl+C结束录制
shell@ $ exit // 结束录制
$ adb pull /sdcard/demo.mp4 // 将内存卡中的文件传到电脑上
虽说是Python命令,但是底层调用的依旧是adb,内部实现依赖了ffmpeg。
详情请参考RoboGif的文档->RoboGif
如果你对Python还不了解,可以到这里学习一下Python的基础知识:PythonNote
我测试后得出的结论不一定对不 但是感觉看完你的我还是有点迷糊 所以就想补充下呢~ PointCount的含义
src : The array of src [x,y] pairs (points)
srcIndex : Index of the first pair of src values(既 第一个点在src的那个位置)
dst : The array of dst [x,y] pairs (points)
dstIndex : Index of the first pair of dst values(既 第一个点在dst的那个位置)
pointCount : The number of pairs/points to be used. Must be [0..4]
总结其含义:
其实最终是反求Matrix。pointCount代表使用dst,src里的几个点,
如果pointCount是1 :
通过src里的0变化到dst里的0 ;计算最终的matrix可以知道 这个是位移;
如果pointCount是2 :
src里的0,1 变化到dst里的0,1 反求matrix可以知道 这个是 缩放,旋转,位移;
如果pointCount是3 :
src里的0,1 ,2 变化到dst里的0,1,2 反求matrix;具体咋变的按不动 反正是反求;
经过测试(这个只是我的疑问,本来不应该有的 但是你用他绘图突然我就有了。。。):
1.如果我用如果我宽度 用btMap的一半呢?绘制btmap,后半的btmap会怎样?
因为调用这个的方法结果是Matrix改变,所以画布 绘画的时候,调用Matrix也是整体改变。那么btMap后边的一半也会随着Matrix改变而不是不变!
在 Path之完结篇(伪) 这篇文章中,在接近末尾部分的"计算 path 边界"内容中 md 语法有问题。
作为一个很懒的程序猿,为你的开发工具选择一个合适的插件将会让你开发事半功倍。
序号 | 插件 | 简介 |
---|---|---|
01 | ButterKnifeZelezny | 配合ButterKnife使用的插件,自动生成ButterKnife相关代码 |
02 | idea-markdown | MarkDown插件 |
03 | idea-multimarkdown | MarkDown插件 |
04 | lint-cleaner-plugin | 移除Android中无用资源 |
05 | PlantUML | 标准建模语言,描述 类(对象的)、对象、关联、职责、行为、接口、用例、包、顺序、协作,以及状态 |
另外推荐知乎上别人整理的资源:
快捷键 | 作用 |
---|---|
Option + Enter | 自动修正 |
Command + N | 自动生成代码(Getter Setter) |
Command + Alt + L | 格式化代码 |
Command + Alt + T | 把选中的代码放在 try{} 、if{} 、 else{} 里 |
Command + / | 注释 // |
Command + Shift + / | 注释 /* */ |
Command + Shift + Up/Down | 语句上下移动 |
Option + Shift + Up/Down | 内容上下移动 |
Option + Command + M | 将选中代码块封装成一个方法 |
Command + D | 复制当前一行(或选择区域),并粘贴到下面 |
Command + Z | 后退 |
Command + Shift + Z | 前进 |
Control + Alt + O | 优化导入的包 |
Ctrl(Command)+ - / + | 折叠/展开代码 |
Ctrl(Command)+Shift+ - / + | 折叠/展开全部代码 |
Ctrl(Command)+Shift+. | 折叠/展开当前花括号中的代码 |
第一类只能指定文本基线位置位置(基线x默认在字符串左侧,基线y默认在字符串下方)。
这个说法有误导性,y应该是文字的baseline位置,而不是bottom
http://sd4886656.iteye.com/blog/1200890
概念区别:
单位 | 含义 |
---|---|
dip | device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。 |
dp | 同上,和dip一样。 |
px | pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素。 |
sp | scaled pixels(放大像素). 主要用于字体显示best for textsize。 |
pt | point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用。 |
in | (英寸):长度单位。 |
mm | (毫米):长度单位。 |
单位转换:
/**
* dp、sp 转换为 px 的工具类
*
* @author fxsky 2012.11.12
*
*/
public class DisplayUtil {
/**
* 将px值转换为dip或dp值,保证尺寸大小不变
*
* @param pxValue
* @param scale
* (DisplayMetrics类中属性density)
* @return
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
/**
* 将dip或dp值转换为px值,保证尺寸大小不变
*
* @param dipValue
* @param scale
* (DisplayMetrics类中属性density)
* @return
*/
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
/**
* 将px值转换为sp值,保证文字大小不变
*
* @param pxValue
* @param fontScale
* (DisplayMetrics类中属性scaledDensity)
* @return
*/
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
/**
* 将sp值转换为px值,保证文字大小不变
*
* @param spValue
* @param fontScale
* (DisplayMetrics类中属性scaledDensity)
* @return
*/
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
**// 大哥,我这代码超简单的,就像我之前说的那样,每一块儿都是照着你的写的,不过就是简化了一下。您帮忙看看~~~ THX!!!
package com.example.administrator.piedraw;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
/**
Created by Administrator on 2016/9/20.
*/
public class PieView extends View {
private Paint mPaint=new Paint();
private Color mColor=new Color();
private float currentAngle=0;
private float startAngle=0;
private float mValue=0;
private int mWidth,mHight;
ArrayList pieList=new ArrayList();
int[] colorList={0xFFCCFF00, 0xFF6495ED, 0xFFE32636, 0xFF800000, 0xFF808000, 0xFFFF8C69, 0xFF808080,
0xFFE6B800, 0xFF7CFC00};
int[] valueList={1,2,3,4,5,6,7,8};
public PieView(Context context){
super(context);
}
public PieView(Context context,AttributeSet attrs){
super(context,attrs,0);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
}
@OverRide
public void onSizeChanged(int w,int h,int oldW,int oldH){
mWidth=w;
mHight=h;
}
@OverRide
public void onDraw(Canvas canvas){
mPaint.setColor(Color.GRAY);
canvas.translate(mWidth/2,mHight/2);
float r=(float)(Math.min(mWidth,mHight)/2*0.8);
RectF rectF=new RectF(-r,-r,r,r);
initialPieData(pieList);
Log.d("PieView","onDraw is been excute------------------");
for(int i=0;i<pieList.size();i++){
Log.d("PieView","pie is been draw------------------------");
PieData pieData=pieList.get(i);
currentAngle=pieData.getAngle();
mPaint.setColor(pieData.getColor());
canvas.drawArc(rectF,startAngle,currentAngle,true,mPaint);
startAngle+=currentAngle;
}
}
public void initialPieData(ArrayList pieList){
int totalValue=0;
for(int i=0;i<valueList.length;i++) {
totalValue += valueList[i];
}
for(int i=0;i<8;i++){
Log.d("PieView","initialPieData is been excute---------------------");
PieData pieData=new PieData();
pieData.setColor(colorList[i]);
int value=valueList[i];
float startAngle=value/totalValue*360;
pieData.setAngle(startAngle);
pieList.add(pieData);
}
}
}
package com.sloop.canvas;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* <ul type="disc">
* <li>Author: Sloop</li>
* <li>Version: v1.0.0</li>
* <li>Copyright: Copyright (c) 2015</li>
* <li>Date: 2016/2/5</li>
* <li><a href="http://www.sloop.icoc.cc" target="_blank">作者网站</a> </li>
* <li><a href="http://weibo.com/5459430586" target="_blank">作者微博</a> </li>
* <li><a href="https://github.com/GcsSloop" target="_blank">作者GitHub</a> </li>
* </ul>
*/
public class CheckView extends View {
private static final int ANIM_NULL = 0; //动画状态-没有
private static final int ANIM_CHECK = 1; //动画状态-开启
private static final int ANIM_UNCHECK = 2; //动画状态-结束
private Context mContext; // 上下文
private int mWidth, mHeight; // 宽高
private Handler mHandler; // handler
private Paint mPaint;
private Bitmap okBitmap;
private int animCurrentPage = -1; // 当前页码
private int animMaxPage = 13; // 总页数
private int animDuration = 500; // 动画时长
private int animState = ANIM_NULL; // 动画状态
private boolean isCheck = false; // 是否只选中状态
public CheckView(Context context) {
super(context, null);
}
public CheckView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
/**
* 初始化
* @param context
*/
private void init(Context context) {
mContext = context;
mPaint = new Paint();
mPaint.setColor(0xffFF5317);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
okBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.checkres);
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (animCurrentPage < animMaxPage && animCurrentPage >= 0) {
invalidate();
if (animState == ANIM_NULL)
return;
if (animState == ANIM_CHECK) {
animCurrentPage++;
} else if (animState == ANIM_UNCHECK) {
animCurrentPage--;
}
this.sendEmptyMessageDelayed(0, animDuration / animMaxPage);
Log.e("AAA", "Count=" + animCurrentPage);
} else {
if (isCheck) {
animCurrentPage = animMaxPage - 1;
} else {
animCurrentPage = -1;
}
invalidate();
animState = ANIM_NULL;
}
}
};
}
/**
* View大小确定
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
}
/**
* 绘制内容
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 移动坐标系到画布**
canvas.translate(mWidth / 2, mHeight / 2);
// 绘制背景圆形
canvas.drawCircle(0, 0, 240, mPaint);
// 得出图像边长
int sideLength = okBitmap.getHeight();
// 得到图像选区 和 实际绘制位置
Rect src = new Rect(sideLength * animCurrentPage, 0, sideLength * (animCurrentPage + 1), sideLength);
Rect dst = new Rect(-200, -200, 200, 200);
// 绘制
canvas.drawBitmap(okBitmap, src, dst, null);
}
/**
* 选择
*/
public void check() {
if (animState != ANIM_NULL || isCheck)
return;
animState = ANIM_CHECK;
animCurrentPage = 0;
mHandler.sendEmptyMessageDelayed(0, animDuration / animMaxPage);
isCheck = true;
}
/**
* 取消选择
*/
public void unCheck() {
if (animState != ANIM_NULL || (!isCheck))
return;
animState = ANIM_UNCHECK;
animCurrentPage = animMaxPage - 1;
mHandler.sendEmptyMessageDelayed(0, animDuration / animMaxPage);
isCheck = false;
}
/**
* 设置动画时长
* @param animDuration
*/
public void setAnimDuration(int animDuration) {
if (animDuration <= 0)
return;
this.animDuration = animDuration;
}
/**
* 设置背景圆形颜色
* @param color
*/
public void setBackgroundColor(int color){
mPaint.setColor(color);
}
}
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeWidth(10f);
mPaint.setAntiAlias(true);
mCoordinatePaint = new Paint();
mCoordinatePaint.setColor(Color.BLACK);
mCoordinatePaint.setStyle(Paint.Style.FILL);
mCoordinatePaint.setStrokeWidth(10f);
mCoordinatePaint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(200, 0, 200, 500, mCoordinatePaint);
canvas.drawLine(0, 500, 200, 500, mCoordinatePaint);
mPaint.setTextSize(100);
canvas.drawText("ABCD", 200, 500, mPaint);
}
绘制出来的结果我发现绘制的文字的原点是左下角(也就是文字的左下角才是200,500这个位置)
第一次使用android studio 编译ndk,
建立src/main/jni目录,编写c代码,
之后在build.gradle里添加ndk 配置
android {
ndk {
moduleName "HelloJNI"
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
sourceSets {
main {
jni.srcDirs = ["jni"]
}
}
怎么也不能编译出so文件,google搜索了好久,也没找到相应的答案
似乎Google上很少有人不能编译出so文件的,但我就是编译不出来,也不报错误
不知道有没有解决方案
曾经的我是一个只会用“逗比式”的小菜鸟,虽然BaseAdapter是个超级兵器,无奈我功力太弱,仅会“逗比式”一种功法,虽然平常打个地痞流氓是绰绰有余,可面对数据大军的时候就歇菜了。
心有不甘的我四处求学,希望找到一个可以一人独战千军万马的功法,于是我拜入了慕课的门下,找到了一本秘籍 BaseAdapter的使用与优化, 从此学会了一门叫“文艺式”的功法,面对数据的大军,便再也不惧,轻挥衣袖便让对方瞬间溃散。
在外出历练的过程中,偶然间发现了这个秘籍 一种无须设置ViewHolder的ListView写法,果然是天外有天,仅用八成力量达到了十成的效果,此等神功我必须要学来。
正在我因为得到一门神功欣喜之时,在慕课的藏书阁中发现了一本名为 打造万能适配器 的秘籍。心生疑惑,世间居然有此等神功,便迫不及待的打开看看,这一看之下,便是犹如被雷劈一般的震惊了,原来我看的上一门功法仅仅是这一本秘籍中的一部分,如若修习完此等功法,仅需一两成的力道便可与之前十成力道想媲美,果然是门神功。
就目前来说,我能看到的巅峰就在这里了,也许存在着更加厉害的功法,我会不懈的追求更加好的功法的。作为一个无私奉献的人,我把所有看过的秘籍分享给诸位,你看或者不看,秘籍就在那里。
自定义View这块讲解的不是很透彻
存在中文注释,且编码为utf-8。
指定编译字符集为utf-8。
在所在项目之下的build.gradle中添加:
tasks.withType(JavaCompile) { options.encoding = “UTF-8” }
注:由于Gradlev2.2.1的升级,语法不向下兼容。之前解决这个问题的方法是添加:
tasks.withType(Compile) { options.encoding = “UTF-8” }
现在的手机 平板屏幕都已经支持了触摸笔,支持压感绘图(我说的效果其实就是在屏幕上写毛笔字),显示出来笔锋效果,我查过资料 有一些api 没看明白,希望作者讲解一下,让大家都学习一下最好可以配上简单的demo
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gcssloop.canvas.MainActivity">
<ImageView
android:layout_centerInParent="true"
android:id="@+id/view_gety_test"
android:background="#CCC"
android:layout_width="200dp"
android:layout_height="200dp"/>
</RelativeLayout>
setContentView(R.layout.activity_gety_getrawy);
View view = findViewById(R.id.view_gety_test);
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("TAG", event.getY()+" : "+event.getRawY());
return true;
}
});
10-26 17:12:50.805 3581-3581/? E/TAG: 124.38281 : 832.3828
10-26 17:12:50.922 3581-3581/? E/TAG: 124.38281 : 832.3828
10-26 17:12:51.430 3581-3581/? E/TAG: 364.5 : 1072.5
10-26 17:12:51.563 3581-3581/? E/TAG: 364.5 : 1072.5
10-26 17:12:52.019 3581-3581/? E/TAG: 490.53516 : 1198.5352
10-26 17:12:52.169 3581-3581/? E/TAG: 490.53516 : 1198.5352
10-26 17:12:55.735 3581-3581/? E/TAG: 2.3320312 : 710.33203
10-26 17:12:55.862 3581-3581/? E/TAG: 2.3320312 : 710.33203
http://fromwiz.com/share/s/3Hsjaq1-lQ9Q2SChN02Hkyvk09g7H73TokIK2Wsnje1-vRGw
因为这个给不了图
看完你给的错切图 我以为我以前的认知是错的呢
然后就验证了下 发现你这个图是错的 左上点没有动你这个动了 这个图很重要我只想说。。。
好吧,这是一个基础题。
这些与文本有关的几个名词都是我们在开发过程中常见的内容,对其多多少少都有些了解。不过嘛,很少人能真正明白其中几个东西的关系就是了。
首先,CharSequence是一个接口,用于表示有序的字符集合,并提供了一些基本的操作方法。
String StringBuffer StringBuilder都实现了CharSequence这个接口。
关系图如下:
我们了解了他们的关系之后,我们再了解一下他们的区别:
名称 | 说明 |
---|---|
CharSequence | 接口,表示有序的字符集合 |
String | 常量,不可变 |
StringBuffer | 可变长度字符序列,线程安全 |
StringBuilder | 可变长度字符序列,非线程安全 |
Maven 下载地址: http://maven.apache.org
mvn compile //编译
mvn package //打包
解决问题: 链接地址
SDK BuildTool版本有问题,可能为不存在或者不完全。
更改build.gradle中android节点下buildToolsVersion 中的版本号。
用isShown()这个函数判断View是否显示比使用view.getVisibility() == View.VISIBLE要好。
isShown()会层层判断父View的状态设置,
view.getVisibility() == View.VISIBLE只会判断view当前的状态设置。
Matrix m = new Matrix();
m.reset();
m.preTranslate(tx, ty);
m.preScale(sx, sy);
这地方是怎么个顺序
1.是preScale先右乘矩阵 preTranslate再右乘上次的结果。
2.preScale先右乘preTranslate,然后再乘矩阵。
将应用版本号等其他相关信息发送给服务器,服务器进行判断,如果符合升级的标准则返回升级链接
优点:
判断逻辑不在客户端,可以根据需求进行对特定用户进行升级。
例如只升级某一种机型,或只对某一个地区手机进行升级。
Can you please translate this to english, I think it's very interesting :).
测试时坐标往左上偏移,偏移较大
机型:android5.0深度定制机型~
额,文章怎换例子了┑( ̄▽  ̄)┍ ,onDraw方法里canvas.drawPath(circle1,mDeafultPaint);circle1错了
启用Android Support plugin即可.
File -> Settings - > Plugins -> Enable "Android Support" Plugin.
1. 仅用pre:
Matrix m = new Matrix();
m.reset();
m.preTranslate(tx, ty); //使用pre,越靠后越先执行。
m.preScale(sx, sy);
我感觉应该是这样的:
S * T * M
而不是
M * T * S
因为pre是前乘,即参数给出的矩阵乘以当前的矩阵
2. 仅用post:
Matrix m = new Matrix();
m.reset();
m.postScale(sx, sy); //使用post,越靠前越先执行。
m.postTranslate(tx, ty);
应该是:
M * S * T
而不是
T * S * M
命令 | 说明 |
---|---|
adb start-server | 启动服务 |
adb kill-server | 关闭服务 |
adb devices | 显示当前连接的所有设备(如果服务没有开启会自动开启) |
adb install xxx.apk | 将应用安装进设备中 |
adb uninstall <包名> | 卸载应用 |
adb -s <设备名> <命令> | 如果有多个设备,指定某一个设备进行操作 |
adb pull <手机文件> <电脑文件> | 将手机内文件导入到电脑上(文件名均为全称) |
adb push <电脑文件> <手机文件> | 将电脑中文件推送到手机上(文件名均为全称) |
adb shell | 进入手机命令行终端 |
┗ ls | 查看目录列表 |
┗ ls -l | 显示详细信息(权限 用户名 组名 时间 包名) |
┗ ps | 当前正在运行的进程 |
┗ ping | 手机的网络连通性 |
引用后,看不到项目的文档注释,非常不方便使用啊
mPaint.setColor(Color.YELLOW);
mPaint.setStyle(Style.STROKE);
canvas.translate(centerX, centerY);
mPaint.setStrokeWidth(3);
canvas.drawRect(0, 0, 200, -200, mPaint);//笔记中的写法,没有效果
mPaint.setColor(Color.RED);
canvas.drawRect(0, -200, 200, 0, mPaint);//有效果,在预定的坐标系原点右上角
大神我转载了你一篇文章
程序员需要了解的版权协议
转载地址为:
版权问题相关
如有问题请联系,谢啦
原文地址:http://developer.android.com/guide/topics/graphics/hardware-accel.html
译文地址:http://blog.chenming.info/blog/2012/09/18/android-hardware-accel/
Android 3.0 (API level 11), 开始支持
所有的View 的canvas都会使用GPU,但是硬件的加速会占有一定的RAM。
在API >= 14上,默认是开启的,如果你的应用只是标准的View和Drawable,全局都打开硬件加速,是不会有任何问题的。
然而,硬件加速并不支持所有的2D画图的操作,这时开着它,可能会影响到你的自定义控件或者绘画,出现异常等行为,
所以android对于硬件加速提供了可选性
如果你的应用执行了自定义的绘画,可以通过在真机上测试开启硬件加速查找问题
<application
android:hardwareAccelerated="false"
...>
</application>
<application
android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Note: 你可以关闭View级别的硬件加速,但是你不能在View级别开启硬件加速,因为它还依赖其他的设置
View.isHardwareAccelerated() //returns true if the View is attached to a hardware accelerated window.
Canvas.isHardwareAccelerated() //returns true if the Canvas is hardware accelerated
如果必须进行这样的验证,建议你在draw的代码块中使用:Canvas.isHardwareAccelerated(),因为如果一个View被attach到一个硬件加速的Window上,
即使没有硬件加速的Canvas,它也是可以被绘制的。比如:将一个View以bitmap的形式进行缓存
操作类型 | 相关API | 备注 |
---|---|---|
绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布 相关链接: 【基础☆颜色】 【Canvas☆颜色与基本形状】 |
绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧 相关链接 : 【Canvas☆颜色与基本形状】 |
绘制图片 | drawBitmap, drawPicture | 绘制位图和图片 相关链接: 【Canvas☆图片与文字】 |
绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字 相关链接: 【Canvas☆图片与文字】 |
绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数 相关链接: 【Path☆常用操作】 |
顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 |
画布剪裁 | clipPath, clipRect | 设置画布的显示区域 |
画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 会滚到指定状态、 获取保存次数 相关链接: 【Canvas☆画布操作】 |
画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、倾斜 相关链接: 【基础☆坐标系】 【基础☆角度与弧度】 【Canvas☆画布操作】 |
Matrix(矩阵) | getMatrix, setMatrix, concat | 实际画布的位移,缩放等操作的都是图像矩阵Matrix,只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 |
如题,弧度和角度的转换公式貌似写反了
比如我画了这样两个圆,
canvas.drawCircle(20, 20, 10, mPaint);
canvas.drawCircle(40, 40, 10, mPaint);
我想要点击两个圆都有不同的是事件触发该如何实现。求教~谢谢
受益匪浅。 发现一个小笔误,反馈一下: 0在外,非零在内
可以在预览中添加册数数据使用,如TextView的Text属性,把前面的android换位tools之后,仅在预览中能看到text,不会影响实际运行。
你的教程文章什么时候出现在你的博客上啊,我都等不及转载一下了- -
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.