Android 《Android群英传》笔记一

第三章:Android控件架构与自定义控件详解

3.1 Android控件架构

控件分为两类:View和ViewGroup,通过ViewGroup整个界面形成一个树形结构,并且ViewGroup负责对子View的测量与绘制以及传递交互事件。通常在Activity中使用的findViewById()方法,就是在控件树中以树的深度优先遍历来查找对应元素。在每颗控件树的顶部,都有一个ViewParent对象,这就是整棵树的控制核心,所有的交互管理事件都由它来统一调度和分配。

阅读更多

Android 自定义 View 实现可拖拽的 GridView 控件

在网易新闻中有一个新闻栏目管理,其中GridView的item是可以拖拽的,效果十分炫酷。具体效果如下图:

这里写图片描述

是不是也想自己也想实现出相同的效果呢?那就一起来往下看吧。

首先我们来梳理一下思路:

  1. 当用户长按选择一个item时,将该item隐藏,然后用WindowManager添加一个新的window,该window与所选择item一模一样,并且跟随用户手指滑动而不断改变位置。
  2. 当window的位置坐标在GridView里面时,使用pointToPosition (int x, int y)方法来判断对应的应该是哪个item,在adapter中作出数据集相应的变化,然后做出平移的动画。
阅读更多

Android AlertDialog 中 EditText 无法弹出键盘的解决方案

之前在做项目的过程中,有一个需求就是在AlertDialog中有EditText,可以在EditText中输入内容。但是在实际开发的过程中却发现,点击EditText却始终无法弹出键盘。因为之前在使用AlertDialog的时候,布局中并没有EditText,因此没有发现这个问题。这次算是填了一个隐藏的坑。

例如下面给出了一个例子,首先贴上AlertDialog的layout.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="200dp"
android:background="@android:color/white"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello friend!"/>

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="input content" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="submit"/>

</LinearLayout>
阅读更多

Android 自定义 ViewGroup 实现流式布局

首先流式布局相信大家都见到过,比如说下图中的京东热搜就是流式布局的应用。还有更多应用的地方在这里就不一一举例了。

这里写图片描述

下面我们就来看看是如何实现的。首先新建一个class,继承自ViewGroup。在generateLayoutParams(AttributeSet attrs)里直接返回MarginLayoutParams就行了。

1
2
3
4
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
阅读更多

Android LayoutInflater 解析

前言

今天要讲的主角就是LayoutInflater,相信大家都用过吧。在动态地加载布局时,经常可以看见它的身影。比如说在Fragment的onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)方法里,就需要我们返回Fragment的View。这时就可以用inflater.inflate(R.layout.fragment_view, container, false)来加载视图。那么下面就来探究一下LayoutInflater的真面目吧。

阅读更多

Android View getLeft() 和 getTop() 研究

在今天的开发中,遇到了一个之前没有关注过的细节。那就是我用view.getTop()来获取view距离屏幕顶部高度,结果发现得到的数值和理论不一致。我们来举个例子吧,比如我们有如下的布局:

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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


<LinearLayout
android:id="@+id/ll_01"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="vertical"
android:background="@android:color/holo_green_light">

<TextView
android:id="@+id/tv_01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="我是第一行文字" />
</LinearLayout>

<LinearLayout
android:id="@+id/ll_02"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="vertical"
android:background="@android:color/holo_blue_light">

<TextView
android:id="@+id/tv_02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="我是第二行文字" />
</LinearLayout>

</LinearLayout>
阅读更多

Android 实现导航 Tab 悬浮

“饿了么”导航Tab栏悬浮的效果图。

这里填写图片的描述

可以看到上图中的“分类”、“排序”、“筛选”会悬浮在app的顶部,状态随着ScrollView(也可能不是ScrollView,在这里姑且把这滑动的UI控件当作ScrollView吧)的滚动而变化。像这种导航Tab栏悬浮的作用相信大家都能体会到,Tab栏不会随着ScrollView等的滚动而被滑出屏幕外,增加了与用户之间的交互性和方便性。

看到上面的效果,相信大家都跃跃欲试了,那就让我们开始吧。

好了,根据上面的就得到了对ScrollView滑动的监听了。接下来要思考的问题就是如何让Tab栏实现悬浮的效果呢?这里给出的方法有两种,第一种就是使用WindowManager来动态地添加一个View悬浮在顶部;第二种就是随着ScrollView的滑动不断重新设置Tab栏的布局位置。

阅读更多

Android 实现水波纹动画

效果:

这里填写图片描述

是不是觉得有新意多了呢?那就一起来看看吧,先简单讲述一下思路:首先波浪的形状主要是根据三角函数决定的。三角函数相信大家在中学的课程中学习过吧。通用公式就是f(x)=Asin(ωx+φ) + b。其中A就是波浪的振幅,ω与时间周期有关,x就是屏幕宽度的像素点,φ是初相,可以让波浪产生偏移,最后的b就是水位的高度了。最后根据这公式算出y坐标,用canvas.drawLine(startX, startY, stopX, stopY, paint);来画出竖直的线条,这样就形成了波浪。

阅读更多

Android ListView 实现侧滑删除

效果图:

这里填写图片描述

可以看出来,我们实现的和QQ的效果相差无几。下面就是源码时间了。

先来看一下ListView的item的slip_item_layout.xml

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
<?xml version="1.0" encoding="utf-8"?>
<com.yuqirong.swipelistview.view.SwipeListLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sll_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal" >

<TextView
android:id="@+id/tv_top"
android:layout_width="80dp"
android:layout_height="match_parent"
android:background="#66ff0000"
android:gravity="center"
android:text="置顶" />

<TextView
android:id="@+id/tv_delete"
android:layout_width="80dp"
android:layout_height="match_parent"
android:background="#330000ff"
android:gravity="center"
android:text="删除" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="#66ffffff"
android:orientation="horizontal" >

<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:src="@drawable/head_1" />

<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:text="hello" />
</LinearLayout>

</com.yuqirong.swipelistview.view.SwipeListLayout>
阅读更多

Android ORM框架 GreenDAO

在Android开发中,我们都不可避免地要使用SQLite数据库来存储数据。但是Android提供给我们的API在操作数据库中并不简洁,而且更重要的一点是,在读取数据时无法把读到的字段直接映射成对象。于是在这种情况下,产生了许多ORM (对象关系映射 英语:Object Relational Mapping) 的第三方框架,比如greenDAO、ActiveAndroid、ormlite等。说到ORM,在web开发中就有Hibernate、MyBatis等框架提供使用。

根据 greenrobot 官方的介绍,greenDAO是一款轻量,快速,适用于Android数据库的ORM框架。具有很高的性能以及消耗很少的内存。其他的优点和特性就不在这里一一介绍了,想要了解的人可以去访问它的项目地址:https://github.com/greenrobot/greenDAO

阅读更多