Android wiki

Posted by Mio4kon on 2014-12-01

Wiki

不定时更新(深坑,太监)

Paint

抗锯齿
Paint paint = new Paint (Paint.ANTI_ALIAS_FLAG);
只画边框
paint.setStyle(Paint.Style.STROKE);

Canvas

translate

移动原点,默认的原点(0,0)是在屏幕左上角的,通过translate(x,y)把点(x,y)作为原点.
canvas.translate(float dx, float dy)

布局完成的回调

1
2
3
4
5
6
7
8
mSbv.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener () {
@Override
public void onGlobalLayout() {
mSbv.getViewTreeObserver().removeGlobalOnLayoutListener (this);
}
});

Cliping

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
private void drawScene(Canvas canvas) {
canvas.clipRect(0, 0, 100, 100);
canvas.drawColor(Color.WHITE);
mPaint.setColor(Color.RED);
canvas.drawLine(0, 0, 100, 100, mPaint);
mPaint.setColor(Color.GREEN);
canvas.drawCircle(30, 70, 30, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawText("Clipping", 100, 30, mPaint);
}
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.GRAY);
canvas.save();
canvas.translate(10, 10);
drawScene(canvas);
canvas.restore();
canvas.save();
canvas.translate(160, 10);
canvas.clipRect(10, 10, 90, 90);
canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);//DIFFERENCE第一次不同于第二次的部分显示出来
drawScene(canvas);
canvas.restore();
canvas.save();
canvas.translate(10, 160);
mPath.reset();
canvas.clipPath(mPath); // makes the clip empty
mPath.addCircle(50, 50, 50, Path.Direction.CCW);//逆时针
canvas.clipPath(mPath, Region.Op.REPLACE); //REPLACE显示第二次的
drawScene(canvas);
canvas.restore();
canvas.save();
canvas.translate(160, 160);
canvas.clipRect(0, 0, 60, 60);
canvas.clipRect(40, 40, 100, 100, Region.Op.UNION);//全部显示
drawScene(canvas);
canvas.restore();
canvas.save();
canvas.translate(10, 310);
canvas.clipRect(0, 0, 60, 60);
canvas.clipRect(40, 40, 100, 100, Region.Op.XOR);//就是全集的减去交集生育部分显示
drawScene(canvas);
canvas.restore();
canvas.save();
canvas.translate(160, 310);
canvas.clipRect(0, 0, 60, 60);
canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE); //第二次不同于第一次的部分显示
drawScene(canvas);
canvas.restore();
}

Animation

自定义动画效果

  1. 重写Animation applyTransformation (float interpolatedTime, Transformation t)
  2. 重写Animation initialize (int width, int height, int parentWidth, int parentHeight)

tips:
1.绘制动画的过程中会反复的调用applyTransformation 函数,每次调用参数interpolatedTime值都会变化,该参数从0渐变为1,当该参数为1时表明动画结束。

  1. 通过参数Transformation 来获取变换的矩阵(matrix),通过改变矩阵就可以实现各种复杂的效果.
  2. initialize,这是一个回调函数告诉Animation目标View的大小参数,在这里可以初始化一些相关的参数,例如设置动画持续时间、设置Interpolator、设置动画的参考点等。

插值器

AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator 动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前甩一定值后再回到原来位置

Nineoldandroids APIs

垂直移动

ObjectAnimator anmi1 = ObjectAnimator.ofFloat (iv, "y", 0f, 500).setDuration (500);

复制动画

ObjectAnimator anmi2 = anmi1.clone ();
动画合集

AnimatorSet anmiSet1 = new AnimatorSet ();
anmiSet1.playSequentially (anmi1,anmi2);

addUpdateListener使用

1
2
3
4
5
6
7
8
ObjectAnimator anmi1 = ObjectAnimator.ofFloat (iv, "ss", 0f, 1f).setDuration (10000);
anmi1.addUpdateListener (new ValueAnimator.AnimatorUpdateListener () {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float v = (Float) animation.getAnimatedValue ();
iv.setAlpha (v);
}
});

颜色渐变

ValueAnimator colorAnim = ObjectAnimator.ofInt(iv, "backgroundColor", /*Red*/0xFFFF8080, /    *Blue*/0xFF8080FF);
   colorAnim.setDuration(3000);
   colorAnim.setEvaluator(new ArgbEvaluator ());
   colorAnim.setRepeatCount(ValueAnimator.INFINITE);
   colorAnim.setRepeatMode(ValueAnimator.REVERSE);
   colorAnim.start();

属性

rotationX | rotationY | rotation | translationX | translationY | scaleX | scaleY | alpha

获取通知栏高度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static int getStatusBarHeight(Context context){
Class<?> c = null;
Object obj = null;
Field field = null;
int x = 0, statusBarHeight = 0;
try {
c = Class.forName("com.android.internal.R$dimen");
obj = c.newInstance();
field = c.getField("status_bar_height");
x = Integer.parseInt(field.get(obj).toString());
statusBarHeight = context.getResources().getDimensionPixelSize(x);
} catch (Exception e1) {
e1.printStackTrace();
}
return statusBarHeight;
}

自定义属性步骤

1.在res/values文件下定义

1
2
3
<declare-styleable name="customView">
<attr name="customtextSize" format="dimension"/>//自定义属性,format属性表示该属性的单位
</declare-styleable>

2.在自定义View中获取

1
2
3
TypedArray typedArray = context.obtainStyledAttributes (attrs, R.styleable.customView);
float customtextSize = typedArray.getDimension (R.styleable.customView_customtextSize, 18);
typedArray.recycle ();

3.Layout中使用

记得加上命名空间:

1
2
3
4
5
6
<com.arrts.ArrtView
xmlns:mio="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
mio:customtextSize="50sp"
/>

Activity切换动画

overridePendingTransition(int enterAnim, int exitAnim)
第一个参数是:进入的Activity的动画
第二个参数是:当前要退出的Activity的动画

自定义View获取子View的宽高

1
2
3
4
View child = getChildAt(0);
LayoutParams st = child.getLayoutParams ();
//st.width, st.height