Android 实现侧滑菜单

从早期的 SlidingMenu 再到 AndroidResideMenu 最后到Android自带的DrawerLayout,无处不体现着侧滑菜单的诱人魅力。侧滑菜单可以拓展app的内容,充分利用手机屏幕,增加程序的可玩性。

这里写图片描述

看完了上面的gif,想不想自己也写一个呢,那还等什么,一起来看看喽。

阅读更多

Android 实现微信满屏表情下落动画

效果:

这里写图片描述

看完上面的效果图,大家一定都迫不及待地想要试一试了,那就让我们来动手吧。

首先我们定义一个实体类DropLook:

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
/**
* 下落的表情
*/
public class DropLook {

// x轴坐标
private float x;
// y轴坐标
private float y;
// 初始旋转角度
private float rotation;
// 下落速度
private float speed;
// 旋转速度
private float rotationSpeed;
// 宽度
private int width;
// 高度
private int height;
// 图片
private Bitmap bitmap;

public float getX() {
return x;
}

public void setX(float x) {
this.x = x;
}

public float getY() {
return y;
}

public void setY(float y) {
this.y = y;
}

public float getRotationSpeed() {
return rotationSpeed;
}

public void setRotationSpeed(float rotationSpeed) {
this.rotationSpeed = rotationSpeed;
}

public float getRotation() {
return rotation;
}

public void setRotation(float rotation) {
this.rotation = rotation;
}

public float getSpeed() {
return speed;
}

public void setSpeed(float speed) {
this.speed = speed;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public Bitmap getBitmap() {
return bitmap;
}

public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}

}
阅读更多

Android onTouch 事件传递机制解析

大家都知道一般我们使用的UI控件都是继承自共同的父类——View。所以View这个类应该掌管着onTouch事件的相关处理。那就让我们去看看:在View中寻找Touch相关的方法,其中一个很容易地引起了我们的注意:dispatchTouchEvent(MotionEvent event)。根据方法名的意思应该是负责分发触摸事件的,下面给出了源码:

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
/**
* Pass the touch screen motion event down to the target view, or this
* view if it is the target.
*
* @param event The motion event to be dispatched.
* @return True if the event was handled by the view, false otherwise.
*/
public boolean dispatchTouchEvent(MotionEvent event) {
// If the event should be handled by accessibility focus first.
if (event.isTargetAccessibilityFocus()) {
// We don't have focus or no virtual descendant has it, do not handle the event.
if (!isAccessibilityFocusedViewOrHost()) {
return false;
}
// We have focus and got the event, then use normal event dispatch.
event.setTargetAccessibilityFocus(false);
}

boolean result = false;

if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}

final int actionMasked = event.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Defensive cleanup for new gesture
stopNestedScroll();
}

if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}

if (!result && onTouchEvent(event)) {
result = true;
}
}

if (!result && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
}

// Clean up after nested scrolls if this is the end of a gesture;
// also cancel it if we tried an ACTION_DOWN but we didn't want the rest
// of the gesture.
if (actionMasked == MotionEvent.ACTION_UP ||
actionMasked == MotionEvent.ACTION_CANCEL ||
(actionMasked == MotionEvent.ACTION_DOWN && !result)) {
stopNestedScroll();
}

return result;
}
阅读更多

Android ScrollView 设置滑动距离监听器

ScrollView是我们经常使用的一个UI控件,也许你在使用ScrollView的过程中会发现,当你想监听ScrollView滑动的距离时却没有合适的监听器!当然在API 23中有setOnScrollChangeListener(View.OnScrollChangeListener l)可以使用,但是并不兼容低版本的API。那怎么办呢?只好重写ScrollView来实现对滑动距离的监听了。

话不多说,直接上代码:

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
public class MyScrollView extends ScrollView {

private OnScrollListener listener;

/**
* 设置滑动距离监听器
*/
public void setOnScrollListener(OnScrollListener listener) {
this.listener = listener;
}

public MyScrollView(Context context) {
super(context);
}

public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}

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

// 滑动距离监听器
public interface OnScrollListener{

/**
* 在滑动的时候调用,scrollY为已滑动的距离
*/
void onScroll(int scrollY);
}

@Override
public void computeScroll() {
super.computeScroll();
if(listener!=null){
listener.onScroll(getScrollY());
}
}
}
阅读更多

Android ScrollView 嵌套 ListView 问题的解决办法

在平常的Android开发中我们经常会碰到ScrollView嵌套ListView或者是GridView的情况,若按照一般的流程我们会发现在ScrollView中的ListView显示不全的问题,其实我们可以重写ListView的onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法来解决。

以下是重写ListView的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 重写ListView,解决与ScrollView的冲突
*/
public class MyListView extends ListView {

public MyListView(Context context) {
super(context);
}

public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
阅读更多

Android AsyncTask 分析

前言

在初学 Android 的时候,AsyncTask 应该是大家都比较熟悉的。我们都知道 AsyncTask 可以在后台开启一个异步的任务,当任务完成后可以更新在 UI 上。而在 AsyncTask 中,比较常用的方法有: onPreExecute 、 doInBackground 、 onPostExecute 和 onProgressUpdate 等。而上述的方法中除了 doInBackground 运行在子线程中,其他的都是运行在主线程的,相信大家对这几个方法也了如指掌了。

class

1
2
3
public abstract class AsyncTask<Params, Progress, Result> {
...
}
阅读更多

Android 使用 Handle 处理异步消息

在学习Android的路上,大家肯定会遇到异步消息处理,Android提供给我们一个类来处理相关的问题,那就是Handler。相信大家大多都用过Handler了,下面我们就来看看Handler最简单的用法:

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
public class FirstActivity extends AppCompatActivity {

public static final String TAG = "FirstActivity";
private static Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
Log.i(TAG, "handler receive msg.what = " + msg.what);
break;
default:
break;
}
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
new Thread(new Runnable() {
@Override
public void run() {
//这里做相关操作
handler.sendEmptyMessage(0);
}
}).start();
}

}
阅读更多

Android Activity 生命周期

Activity作为四大组件之一,几乎是每个人开始学习Android最先接触到的。常见的生命周期方法大家肯定都是非常熟悉的,所以Activity生命周期的顺序在这就不必过多叙述了。今天讲一下由FirstActivity启动SecondActivity而调用生命周期方法的顺序问题。

首先我们创建一个如下图的FirstActivity:
这里写图片描述
很简单,LinearLayout里只有一个Button,用于启动SecondActivity。

以下为FirstActivity的布局 activity_first.xml:

阅读更多