学习笔记(二)

布局与优化

我们初学者在刚开始学习Android时,通常都是往上罗列控件,但实际上我们有很多的布局方式,通过这些布局我们可以让我们的App更加优美,同时可以帮助我们适配不同分辨率的机型。在Android中,常见的布局有五种:

l LinearLayout(线性布局)

l RelativeLayout(相对布局)

l FrameLayout(帧布局或框架布局)

l AbsoluteLayout(绝对布局)

l TableLayout(表格布局)

其中前三个布局在日常中最常使用,剩下的两个布局很少用到。

线性布局:顾名思义就是像一条线一样排列,谁先来就在谁的前面;其中,重要的属性:


其中,vertical是垂直排列属性(从上到下排列),horizontal水平排列属性;(从左到右排列);另一重要的特点,在线性布局中,子控件有Layout_weight属性,Layout_weight是水平所占比重


如果我们想让两个TextView各占这个屏幕的一半,我们可以用layout_weight属性;



此时,我们可以看到TextView的宽度各占一半。

相对布局:就是该控件相对于其他控件的位置。相对布局提供了非常灵活的布局方式,允许根据父元素或其他视图的位置定义每个元素在布局中的位置。其中,后定义的控件默认会盖住前面的控件(类似于z轴)。

相对布局的属性非常多,而且都非常常用,相对布局常用属性介绍

这里将这些属性分成组,便于理解和记忆:

1)属性值为true或false

android:layout_centerHrizontal

水平居中

android:layout_centerVertical

垂直居中

android:layout_centerInparent

相对于父元素完全居中

android:layout_alignParentBottom

贴紧父元素的下边缘

android:layout_alignParentLeft

贴紧父元素的左边缘

android:layout_alignParentRight

贴紧父元素的右边缘

android:layout_alignParentTop

贴紧父元素的上边缘 

2)属性值必须为id的引用名“@id/id-name

android:layout_below

在某元素的下方

android:layout_above

在某元素的的上方

android:layout_toLeftOf

在某元素的左边

android:layout_toRightOf

在某元素的右边

android:layout_alignTop

本元素的上边缘和某元素的的上边缘对齐

android:layout_alignLeft

本元素的左边缘和某元素的的左边缘对齐

android:layout_alignBottom

本元素的下边缘和某元素的的下边缘对齐

android:layout_alignRight

本元素的右边缘和某元素的的右边缘对齐

3)属性值为具体的像素值,如30dip,40px

android:layout_marginBottom

离某元素底边缘的距离

android:layout_marginLeft

离某元素左边缘的距离

android:layout_marginRight

离某元素右边缘的距离

android:layout_marginTop

离某元素上边缘的距离

我们可以通过组合这些属性来实现各种各样的布局。

帧布局:是最简单的布局了。所有放在布局里的控件,都按照层次堆叠在屏幕的左上角。后加进来的控件覆盖前面的控件,定义任何空间的位置相关的属性都毫无意义。



绝对布局:指的是指定组件的左上角绝对坐标来指定组件的布局。通过layout_x和layout_y来定义控件在屏幕的位置,这种布局在Android中不常使用,因为android屏幕分布率太多。

表格布局:表格布局模型以行列的形式管理子控件,每一行为一个TableRow的对象,当然也可以是一个View的对象。TableRow可以添加子控件,每添加一个为一列。因为在平常不常用,有兴趣大家可以自行百度哈!

我们知道布局是可以嵌套的,但是过多的布局层次嵌套可能会影响并产生程序的性能问题,所以我们要尽可能减少布局层次。Google官方建议布局层次最多10层,这就要求我们要熟练掌握相对布局,相对布局非常灵活,我们可以一层相对布局可以替代多层的其他布局。

和布局有关的还有一些重要的标签,<include/>,<merge/>,<ViewStub/>等。

<include/>:可以引用相同的布局设计。在一个项目中我们难免会遇到要使用相同的布局格式,但是重复的代码会使我们的文件显得很冗余,我们可以把相同的布局代码单独写成一个模块,然后用的时候可以通过<include/>标签来重用,使用layout="@layout/child_layout"就可以了。但是在引用include标签会有很多注意事项:

1.Include可以使用layout属性来设置布局文件的宽高和位置,但需要注意的是:必须要复写android:layoutwidthandroid:layoutheight属性才能使用其它属性(比如:android:layoutgrivity、android:layoutalign...、android:id等)

2.建议将给include标签调用布局设置宽高、位置、ID等属性放在调用布局的根标签中。

<merge/>:会减少视图的层级。通常用在假如需要在LinearLayout里面嵌入一个布局(或者视图),而恰恰这个布局(或者视图)的根节点也是LinearLayout,这样就多了一层没有用的嵌套,无疑这样只会拖慢程序速度。而这个时候如果我们使用merge根标签就可以避免那样的问题。

<viewstub>:需要时才加载。里面的一些视图先进行预加载,使用的时候在加载,也可以帮助我们优化性能。

有一些小技巧也可以帮助我们进行优化布局,不要嵌套多个使用layout_weight属性的LinearLayout,其次,还可以借助Android lint(帮你删除无用的资源)和Hierarchy View(帮分析所有的层级和怎么进行优化)工具等等。

总之,我们要进行优化布局,就是要减少布局的层次,删除无用的布局,布局结构要清晰,还有选择合适的布局。

无比重要的ListView

Listview可以算是android中非常重要的控件,ListView里面的每个子项Item可以使一个字符串,也可以是一个组合控件。

ListView的显示需要三个元素:

1. ListVeiw用来展示列表的View。

2.适配器用来把数据绑定到ListView。

3.数据具体的将被映射的字符串,图片,或者基本组件。

我们通过一个模仿通讯录例子来说明ListView的相关属性;

1)创建listview标签

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

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通讯录"/>
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</LinearLayout>


2)创建适配器类(PhoneBook_Adapter.java)

importandroid.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import java.util.ArrayList;import java.util.List;public class PhoneBook_Adapter extends BaseAdapter { private Contextcontext;//上下文 private LayoutInflater mLayoutinflater;//解析layout,把布局读出来 private List<UserInfo> mUserInfo=new ArrayList<>();//把对象作为适配器的数据源 public PhoneBook_Adapter(Context context,List<UserInfo> userInfos) { this.context = context; mLayoutinflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mUserInfo=userInfos; } @Override public int getCount() { //有多少个数据 return mUserInfo.size(); } @Override public Object getItem(int i) { //返回某一条的数据对象 return mUserInfo.get(i); } @Override public long getItemId(int i) { return i; } //getView是让每一行数据显示在界面,用户能够看到的 @Override public View getView(int i, View view, ViewGroup viewGroup) { //返回一个视图,i是它的位置,view指的是这个视图,viewGroup是属于哪个ViewGroup ViewHolder viewHolder; if(view==null) { view = mLayoutinflater.inflate(R.layout.item_phone_book, null);//把这个布局读出来 viewHolder=new ViewHolder(); viewHolder.name= (TextView) view.findViewById(R.id.text_name);//从布局中找到TextView viewHolder.age=(TextView)view.findViewById(R.id.text_age); viewHolder.imageView=(ImageView)view.findViewById(R.id.image); view.setTag(viewHolder); } else{ viewHolder= (ViewHolder) view.getTag(); } viewHolder.name.setText(mUserInfo.get(i).getUsername()); //和数据之间进行绑定 viewHolder.age. setText(mUserInfo.get(i).getAge()+" "); viewHolder.imageView.setImageResource(R.mipmap.ic_launcher); return view; } public void refreshData(List<UserInfo> userInfos){ mUserInfo=userInfos;//把旧的列表指向新的列表 notifyDataSetChanged();//列表刷新数据 }}class ViewHolder{ TextView name; TextView age; ImageView imageView;}

UserInfo.java(ListView里面的Item的类)

importjava.io.Serializable;public class UserInfo implements Serializable{ private String username; private int age; public UserInfo(String username, int age) { this.username = username; this.age = age; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}

3)List_View.java

import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class List_View extends Activity{ private ListView phoneBook; private List<UserInfo> userInfos; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview); phoneBook=(ListView)findViewById(R.id.list_view); userInfos = new ArrayList<>(); userInfos.add(new UserInfo("one",21)); userInfos.add(new UserInfo("two",30)); userInfos.add(new UserInfo("three",49)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("one",21)); userInfos.add(new UserInfo("two",30)); userInfos.add(new UserInfo("three",49)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); userInfos.add(new UserInfo("four",28)); final PhoneBook_Adapter phoneBook_adapter=new PhoneBook_Adapter(List_View.this, userInfos); phoneBook.setAdapter(phoneBook_adapter);//将列表与内容进行绑定,adapter是适配器 phoneBook_adapter.notifyDataSetChanged();//通知数据被改变了,数据是和Adapter相关联的 phoneBook.setOnItemClickListener(new AdapterView.OnItemClickListener() {//元素被点击 @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { //i是点击的位置,即position,view是视图 if(i==0){ //新建一批新的数据 //替换掉旧的数据 //刷新listview,更新自己的视图 userInfos.clear(); userInfos.add(new UserInfo("我是新的数据1",1)); userInfos.add(new UserInfo("我是新的数据2",2)); userInfos.add(new UserInfo("我是新的数据3",3)); userInfos.add(new UserInfo("我是新的数据4",4)); phoneBook_adapter.refreshData(userInfos); } Toast.makeText(List_View.this,userInfos.get(i).getUsername(),Toast.LENGTH_SHORT).show(); } });
 }}

至于xml文件,都是一些很简单的控件;

Activity_listview.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="通讯录"/> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:fastScrollEnabled="true"></ListView></LinearLayout>

Item_phone_book.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher"/> <TextView android:id="@+id/text_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_toRightOf="@+id/image" android:text=""/> <TextView android:id="@+id/text_age" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/text_name" android:layout_toRightOf="@+id/image" android:text=""/></RelativeLayout>

然后我们就可以试着运行一下我们的程序啦!


除了上面所提到的一些方法以外,ListVie还有listSelectorscrollingCache,cacheColorHint,fastScrollEnabled等常用属性,addHeaderView和addFooterview方法分别是下拉刷新,上拉加载更多的实现方法。大家在下面可以自己更加深入的学习;

GridView和ScrollView

GridView和ListView没有太大区别,同样也是要借助适配器来实现数据和View的绑定。但是GridView在布局上有些特殊的属性,比如:

android:numColumn=”3”(显示三列,也可以是auto_fit自动适应)

android:columnWidth(每列的宽度)

android:verticalSpacing(垂直边距)

android:horizontalSpacing(水平边距)

ScrollView:当内容超过了整个屏幕或者容器的时候需要使用ScrollView,并且ScrollView的直接子元素只能有一个,若有多个的话系统会报错。ScrollView只支持垂直滚动,,若要支持水平滚动,则要使用HorizontalScrollView。

以上就是我第二章学习笔记,个人能力有限,难免有些不足,请大家多多包涵。

更多相关文章

  1. Android常用的intent action汇总
  2. Android(安卓)应用程序退出后不在运行列表中显示的方法
  3. Android入门第十六篇之Style与Theme
  4. 关于 Android(安卓)程序使用 Support Library 属性的几点说明
  5. Android中_TextView属性的XML详解 包括单行显示等等。
  6. Android中的四种布局
  7. Android(安卓)使用LayerDrawable自定制SeekBar的外观
  8. TextView属性大全+单行显示长文本
  9. android动画效果

随机推荐

  1. master-worker常驻型程序代码修改哪些需
  2. 归并排序
  3. 你要的 Spark AI Summit 2020 PPT 我已经
  4. 一口气搞懂MySQL索引所有知识点
  5. Markdown基本语法解析
  6. Playwright自动化测试工具之元素定位实战
  7. Nginx之_源码编译安装
  8. Hadoop 3.0磁盘均衡器(diskbalancer)功能
  9. Linux之文件目录作用
  10. 实证文章写作常用到的50篇名家经验帖, 学