第三章内容主讲UI,View控件和ViewGroup布局
一、View的一些琐碎知识:
Button中的所有英文字母自动进行大写转换,如果要禁用这一默认特性,属性:android:textAllCaps="false"
ProgressBar通过style属性可以改变其样式,比如:
style="?android:attr/progressBarStyleHorizontal"
AlertDialog的构建方式:通过AlertDialog.Builder创建一个AlertDialog实例
ProgressDialog和AlertDialog有些类似,只不过ProgressDialog会在对话框中显示一个进度条,注意,如果在setCancelable(boolean)方法中传入了false,就表示ProgressDialog是不能通过返回键取消掉的。
二、四大布局中的百分比布局:
除了LinearLayout以外,其他两种布局都不支持按比例指定控件大小,所以出现了百分比布局,可以不使用wrap_content和match_parent来指定控件的大小,而直接指定控件在布局中所占的百分比,轻松实现平分布局甚至是任意比例分割布局。
PercenntFrameLayout和PercentRelativeLayout这两个全新的布局,放在了support库当中,需要添加依赖。
compile 'com.android.support:percent:26.+'
注意:如果使用百分比布局,要写全包名,还必须定义一个app的命名空间,才能使用百分比布局的属性:使用
app:layout_widthPercent和app:layout_heightPercent来指定布局所占的百分比。
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="button1"
app:layout_heightPercent="50%"
app:layout_widthPercent="50%" />
<Button
android:text="button2"
android:layout_alignParentRight="true"
app:layout_heightPercent="50%"
app:layout_widthPercent="50%" />
<Button
android:text="button3"
android:layout_alignParentBottom="true"
app:layout_heightPercent="50%"
app:layout_widthPercent="50%" />
<Button
android:text="button4"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
app:layout_heightPercent="50%"
app:layout_widthPercent="50%"/>
</android.support.percent.PercentRelativeLayout>
三、简单的自定义View相关内容:
首先,所有控件都是直接或者间接继承自View的,所有布局都是直接或间接继承自ViewGroup的。
View是Android中最基本的一种UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域内的各种事件,ViewGroup是一种特殊的View,包含了很多子View和子ViewGroup.
填充布局使用LayoutInflater的from()方法构建出一个LayoutInflater对象,然后调用inflate()方法就可以动态加载一个布局文件,inflate()方法接收两个参数,第一个参数是要加载的布局文件的id,第二个参数是给加载好的布局再添加一个父布局。
四、ListView:
这里inflate()方法接受三个参数,前两个已经知道了什么意思,第三个参数是boolean值,如果是false,表示只让我们在父布局中声明的layout的属性生效,但不为这个View添加父布局。
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
我们仔细看这个方法,下面分两种情况:
1.root为null:
不管你attachToRoot为何值,效果都是一样的,root为null表示不需要将resource的布局添加到任何容器中,所以resource布局中根节点的layout属性不会生效,同时需要我们手动调用addView()方法添加布局
2.root不为null:
如果attachToRoot=true,表示将resource布局添加到root中,添加过程中resource所指定的布局的根节点的属性都是有效的,而且不需要写addView()就能将布局添加进来(如果写了addView()会报错);
如果attachToRoot=false,表示不将resource指定的布局添加到root中,为何会这样写,以为layout_width和layout_height表示一个控件在容器中的大小,必须在容器中才有意义。所以如果我想让resource指定的布局的根节点有效,但是又不想为其添加父布局,那么就是这样写了。这是ListView的标准写法。
ListView提升效率:
在Adapter的getView()方法中有一个covertView参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用。
新增一个内部类ViewHolder,用于对控件的实例进行缓存,当convertView为null的时候,创建一个ViewHolder对象,并将控件放在ViewHolder里,然后调用View的setTag()方法,然后将ViewHolder对象存储在View中。当convertView不为null的时候,则调用View的getTag()方法,把ViewHolder重新取出。这样所有控件的实例都缓存在了ViewHolder中,就没必要每次都通过fidnViewById()来获取了。
五、RecyclerView:
RecyclerView定义在了support库当中,需要添加依赖
然后需要为RecyclerView准备适配器,该适配器继承自RecyclerView.Adapter,并指定泛型为xxxAdapter.ViewHolder,这个ViewHolder是我们在XXXAdapter中定义的一个内部类。
横向滚动布局
很简单,只需要改动一行代码(可能需要改动item布局):
瀑布流
ListView的布局排列是由自身去管理的,而RecyclerView是交给了LayoutManager,LayoutManager中制定了一套可扩展的布局排列接口,子类只要按照接口的规范来实现,就能定制出不同的排列方式的布局了。
除了LinearLayoutManager之外,RecyclerView还提供了GridLayoutManager和StaggeredGridLayoutManager这两种内置的布局排列方式。GridLayoutManager用于实现网格布局,StaggeredGridLayoutMannager用于实现瀑布流布局。
我们只需要创建StaggeredGridLayoutManager的实例,它的构造方法接收两个参数,第一个参数用于指定布局的列数,第二个参数用于指定布局的排列方向。
RecyclerView的点击事件
在onCreateViewHolder()方法中注册点击事件就可以了,我们可以通过holder.getAdapterPosition();来获取点击的是哪一个item
小技巧:
制作Nine-Patch图片,在Android sdk目录下有一个tools文件夹,在该文件夹下找到draw9patch.bat文件,我们要使用它来制作Nine-Patch图片,如果要打开这个文件,必须要将JDK的bin目录配置到环境变量当中才行。双击打开draw9patch.bat文件,在导航栏点击File-->Open 9-patch将png文件加载进来
。在图片的四个边框绘制一个个的小黑点,上、左部分表示需要拉伸时就拉伸黑点标记的区域,下、右表示内容放置的区域,按住shift拖动可以进行擦除。最后点击导航栏File-->Save 9-patch把绘制好的图片进行保存
。
RecyclerView添加数据:给adapter的数据源List添加了一个数据后,要调用adapter.notifyItemInserted(data.size() - 1);这样会刷新列表的显示,然后可以调用recyclerView.scrollToPosition(data.size()-1);让RecyclerView定位到最后一行