Xinspace


  • 首页

  • 归档

  • 搜索

自定义View画文字时居中于一个点

发表于 2016-11-19 | 分类于 Android

============================
自定义View用Canvas画文字时,需要让整个字符串在某个点居中显示,比如字符串的中心点必须位于坐标(50,50)处。

下面是一个简单的自定义TextView,以此来说明如何让字符串居中显示。代码中的注释笔记详细了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* Created by Rockon.
* 自定义TextView,字符串能根据一个点居中显示。
* 比如,居中点坐标为(300, 300),则整个字符串的中心点处于这个居中点上。
* 为了显示明显,在居中点画一个蓝色的圆点,字符串则对这个圆点居中显示。
*/

public class CustomTextview extends View {

/**
* 画文字的paint
*/
private Paint mTextPaint;

/**
* 画文字中心点的paint
*/
private Paint mPointPaint;

/**
* 字符串
*/
private String mText = "Hello, I'm Rockon here. Nice to meet you.";

/**
* 字符串居中点的横坐标
*/
private int mCenterX;

/**
* 字符串居中点的纵坐标
*/
private int mCenterY;

/**
* 字符串居中点的圆点的半径
*/
private int mCenterRadius;

/**
* 字符串文字大小
*/
private int mTextSize;

public CustomTextview(Context context) {
this(context, null);
}

public CustomTextview(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public CustomTextview(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 在(mCenterX,mCenterY)坐标出画一个蓝色的圆点,用于标记字符串的中点
canvas.drawCircle(mCenterX, mCenterY, mCenterRadius, mPointPaint);
Rect bounds = new Rect();
// 获取字符串的大小, bounds.width就是字符串的宽度
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
// 字符串在X轴的中点
int strCenterX = bounds.width() / 2;
// 字符串在X轴的起点
int strStartX = mCenterX - strCenterX;
// 字符串在Y轴的中点,因为字符串的高不仅仅只包含字符串,还会包含字符串周围的空白,所以不是除以2。
int strCenterY = bounds.height() / 4;
// 字符串在Y轴的起点,起点是字符串左上角的点的Y坐标,要让字符串处于居中点上,则需要下移Y坐标。
int strStartY = mCenterY + strCenterY;
// 画字符串,在(mCenterX,mCenterY)坐标出居中显示
canvas.drawText(mText, strStartX, strStartY, mTextPaint);
}

/**
* 初始化变量
* <br/>
*/
private void init() {
// 初始化居中点坐标、居中点半径和文字大小
mCenterX = 300;
mCenterY = 300;
mCenterRadius = 10;
mTextSize = 30;

// 初始化字符串画笔
mTextPaint = new Paint();
mTextPaint.setColor(Color.RED);
mTextPaint.setTextSize(mTextSize);
mTextPaint.setAntiAlias(true);

// 初始化居中点画笔
mPointPaint = new Paint();
mPointPaint.setAntiAlias(true);
mPointPaint.setColor(Color.BLUE);
}
}

效果图:


原创,转载请指明出处(http://blog.xinspace.xin)。

Activity弹自定义Dialog,有输入框时键盘顶起后面的Activity

发表于 2016-11-16 | 分类于 Android

============================
原创,转载请指明出处(http://blog.xinspace.space)。

问题

Dialog的需求:需要背景是白色,不是Android的默认透明半黑色。

于是Dialog使用了自定义主题,并用Dialog的自定义View覆盖整个屏幕,修改自定义View根布局的背景为白色半透明。此时如果Dialog中输入框,弹出键盘后,会导致背后的Activity被顶上去(因为背景是白色半透明,因此能看到背后的Activity)。

尝试过的解决方案有:

  1. 在AndroidManifest.xml文件中,定义相关Activity处添加属性android:windowSoftInputMode的值为adjustPan或adjustResize。
  2. 考虑到Dialog是自定义的,弹出后导致背后Activity的windowSoftInputMode属性失效,在Dialog中尝试添加了dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);和dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);。但是都不奏效。

解决方案

  1. 在AndroidManifest.xml文件Activity定义处添加属性android:windowSoftInputMode的值为adjustNothing。
  2. 在Dialog定义的代码中,添加dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);

具体的原因还未分析出来。

Https相关文章推荐

发表于 2016-11-14

最近遇到了Andorid客户端验证Https服务器证书的问题,所以在网上找了一些资料。

Https中的Http指的是Http协议,s指的是SSL/TLS协议。SSL/TLS协议位于Http协议和TCP协议之间,主要两点作用:
1.用于判断数据是否到达了正确的服务器或/和客户端,这主要是验证的功能。

2. 将HTTP协议的数据加密,即在TCP传输过程中时密文。

具体的细节信息请阅读参考文章。

Https验证分为单向验证和双向验证。单向验证,顾名思义,是一方验证另一方是否值得信任。如Android客户端验证服务器证书是否可信任,或者服务器验证发送请求的客户端是否值得信任。双向验证,就是双方互相验证。只有验证通过了,后续通信才能继续进行。

单向验证,以Android客户端验证服务器为例。服务器需要一份证书,作为公钥。客户端请求服务器后,服务器将证书发送给客户端。客户端从自己的信任列表中查找是否存在服务器发送的证书,如果存在,说明该服务器值得信任,继续传输数据,如果不存在,直接关闭连接。同理,服务器验证客户端的过程也是一样,只不过这次是客户端有证书,服务器没有。单向验证需要一对证书(公钥)和私钥,公钥和私钥是匹配的,即一份公钥只能匹配一份私钥,反之一样。

双向验证,需要有两对公钥和私钥。即服务器有证书1,客户端有证书2。客户端验证服务器的证书1,服务器验证客户端的证书2。只有两次验证都信任,通信才能继续,否则中断连接。

简单概述先写到这里。

#参考文章:

  1. Android Https相关完全解析 当OkHttp遇到Https,简单介绍Https原理,以及如何用Android验证自签名证书。
  2. HTTPS理论基础及其在Android中的最佳实践,介绍了Https的理论和原理,并介绍在Android中如何验证证书。
  3. Android 偶遇HTTPS,纯Andorid代码。
  4. Android HTTPS详解,简单理论配合Android代码。
  5. 公钥,私钥和数字签名这样最好理解,介绍公钥、私钥和签名这些概念。
  6. 谷歌官网, 如何在Andorid中验证服务器证书,以及一些常见的证书出错问题。

Agera库入门文章

发表于 2016-05-12 | 分类于 Android

============================

参考:要做一个有冒险精神的人!开启漫漫的agera之旅

这篇文章可以作为了解Agera开源库的入门文章看一下,文章中也涉及到了一些源代码。

我花了一段时间学习了Agera库,虽然与RxJava & RxAndroid都是响应式编程库,逻辑相对于嵌套要简单,但是对我而言,RxJava & RxAndroid理解起来要比Agera库要简单一些。可能因为RxJava & RxAndroid比Agera的概念要少一些。但是Agera库的源代码少,轻量级,专注于Android开发,可以观察一段时间再上手。

解决Volley在重试次数为0时,超时后仍然会重试的问题

发表于 2016-05-07 | 分类于 Android

============================

参考:Google Group:Duplicated POST -request with slow request

再用Volley请求服务器时,设置的请求策略为:

1
2
3
4
5
//请求策略是超时时间为3秒,重试次数为0
RetryPolicy retryPolicy = new DefaultRetryPolicy(3000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
request.setRetryPolicy(retryPolicy);

queue.add(request);

重试次数为0,表示不允许Volley重试。但是抓包发现,在超时之后,volley还会再次发起相同的请求,即重试。
在网络上查了一下,发现很多人都说这是Volley本身的问题,目前还没有修复。解决方法也比较简单,代码如下:

1
2
3
4
5
//超时时间为0,重试次数为-1
DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
request.setRetryPolicy(retryPolicy);

queue.add(request);

详细的情况可以去看参考的地址。

Eclipse用Proguard导出签名包时遇到greenrobot eventbus Subscriber class and its super classes have no public methods with the @Subscribe annotation

发表于 2016-05-07 | 分类于 Android

============================
原创,转载请指明出处(http://blog.xinspace.space)。

参考:EventBus exception when proj is built - Subscriber class has no public methods called onEvent

Eclipse导出签名包,用Proguard。项目中用到了org.greenrobot.eventbus.EventBus库,在导出过程中,遇到了如下问题:

1
java.lang.RuntimeException: Unable to create application xxx.xxx.xxx.MyApplication: org.greenrobot.eventbus.i: Subscriber class xxx.xxx.xxx.MyApplication and its super classes have no public methods with the @Subscribe annotation

错误提示说订阅类没有用@Subscribe注解的public方法,导致EventBus出错,从而导致应用出错。
但是在EventBus的订阅类中,有如下方法:

1
2
3
4
@Subscribe
public void onEventMainThread(MyEvent event) {
dispatchEvent(event);
}

该公用方法用于接收EventBus的事件,并且用EventBus的@Subscribe明确注解了。这与错误提示有冲突啊。经过多番查找,终于找到了原因。

阅读全文 »

Eclipse用Proguard导出签名包遇到Can't read [xxx/rt.jar]的解决办法

发表于 2016-05-06 | 分类于 Android

============================
原创,转载请指明出处(http://blog.xinspace.space)。

Eclipse导出签名包时,用Proguard,遇到了几个错误,下面记录一下错误和解决方法。

Eclipse的JDK版本不一致导致的rt.jar问题

1
Error:ProGuard: [MyApp] java.io.IOException: Can't read [xxxx/jdk1.8.0/jre/lib/rt.jar] (Can't process class [apple/applescript/AppleScriptEngine.class] (Unsupported class version number [52.0] (maximum 51.0, Java 1.7)))
阅读全文 »

Android strings.xml文件中字符串添加空格符

发表于 2016-05-03 | 分类于 Android

============================

参考:How to put space character into a string name in XML?

空格符的转义字符为&#160;,所以可以在strings.xml文件中添加空格符:

1
<string name="test_string_with_space">&#160;&#160;This is a line with two spaces.</string>

在这一行的开头加入了两个空格符。

Android Studio 编译时报 com.github.dcendents.android-maven not found 错误

发表于 2016-05-03 | 分类于 Android

============================

参考: How to fix Plugin with id ‘com.github.dcendents.android-maven’ not found. in android studio

Android Studio在编译时会报这个错误,很可能是因为当前项目所用的Gradle版本太高,比如我当时编译时的Gradle使用的是最新的支持Instant Run的版本:com.android.tools.build:gradle:2.1.0。修改为com.android.tools.build:gradle:1.3.0即可。

Android Studio代码乱码导致Gradle编译报错

发表于 2016-05-03 | 分类于 Android

============================

参考:Android Studio编译时Gradle报乱码

从Github上下载的开源库,代码中的注释全都是乱码,在gradle编译过程中,因为乱码报错而无法安装和打包,找到了参考文章,解决了这个问题。

具体来说有2步:

1.Android Studio->File->Others Settings->Default Settings->File Encodings,在对话框中的File Encoding和Project Encoding都设置为UTF-8;

2.如果项目的Gradle的版本低于gradle2.0,那么在module(比如app模块)下的build.gradle文件中加如下配置:

1
2
3
tasks.withType(Compile) {  
options.encoding = "UTF-8"
}

如果Gradle版本大于等于gradle2.0,那么在相应的文件中改为加入如下的配置:

1
2
3
tasks.withType(JavaCompile) {  
options.encoding = "UTF-8"
}

仅仅是tasks.withType()的参数变化了,因为在gradle2.0及以后Compile已经被重命名为JavaCompile了。

123…17

Xinspace

Personal blog from xin.

170 日志
6 分类
1 标签
© 2019 Xinspace
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4