1. 布局与优化
1.1五大布局
LinearLayout ——线性布局;
RelativeLayout ——相对布局;
RrameLayout ——帧布局;
AbsoulteLayout——绝对布局(被废弃);
TableLayout ——表格布局;
1.2 布局原理
UI = 布局 + 控件;
· 系统怎么把图形画出来:读取xml文件——> 解析标签 ——> 绘图(控件);
· 嵌套布局的情况:先处理第一层,绘制完第一层的控件,在处理下一层。层次越多,花费时间越多,加载慢,出现性能问题。
1.3优化布局的技巧
- 减少布局层次
搭建view时,一定要留意屏幕右上角的组件树(Component Tree)。嵌套的view越深,组件数就越复杂,渲染起来就越浪费时间。
- 不要嵌套多个使用layout_weight的LinearLayout
<merge/>
什么情况下考虑使用Merge?
子视图不需要任何指定父视图的布局属性,如一个TextView只需要直接添加在父视图中用于显示即可。
例子:
未优化的代码:
此时的组件图:
用<merge/>
语句:
优化后的组件图:
<ViewStub/>
标签—— 一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文件。- 使用相对布局对控件进行组合来减少布局层次。
(1.3小节的内容来自一位同学的博客)
2. ListView的用法和优化
ListView的四要素:listView、适配器Adapter、数据源、Item Layout
四要素的关系:ListView相当于一个柜子;
Item Layout就是柜子里的每个抽屉,它定义了每个抽屉里有几个格子,这些格子怎么布局,分别放对应类型的数据;
数据源,把数据源的每组数据按照格子放在一个抽屉里;
Adapter适配器,它是连接后端数据和前端显示的接口,数据和UI (View )之间的重要纽带。
2.1 用法步骤
1. 新建ListView
在activity的布局页面上,添加ListView控件,设置id、大小、位置等属性;
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/imageButton"
android:layout_above="@+id/linearLayout">
</ListView>
2. 新建Adapter
创建一个Adapter类,在类的构造函数中解析Item Layout布局,得到一个视图,获取视图中的每个控件,用每个控件引用对应的数据,从而把控件和数据进行绑定。
这就相当于制造了一个Adapter接口:数据 ——> 控件 ——> 视图(view) ——> 布局(xml)
public class FunctionAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mLayoutInflater;
private List<String> mFunctions = new ArrayList<>();
//如果这里有多项内容,也可以扩展为public FunctionAdapter(Context context,List<String> names,
//List<String> ages,List<String> genders)。下面也要添加代码:mNames = names;mAges = ages;mGender = genders;
public FunctionAdapter(Context context,List<String> functions) {
mContext = context;
mFunctions = functions;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mFunctions.size();
}
@Override
public Object getItem(int i) {
return mFunctions.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
// 用ViewHolder进行视图的重用,避免每次数据变化都要运行视图和获取控件的程序,节约运行时间
// 返回一个视图
ViewHolder viewHolder;
if(view == null) {
view = mLayoutInflater.inflate(R.layout.item_funtion,null);
viewHolder = new ViewHolder();
// 获取控件
viewHolder.functionTextView = (TextView) view.findViewById(R.id.item_list_view);
view.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) view.getTag();
}
// 和数据绑定
viewHolder.functionTextView.setText(mFunctions.get(i));
return view;
}
class ViewHolder {
TextView functionTextView;
}
3. 在代码文件中输入数据,并用Adapter连接数据和视图
//Adapter的数据输入
mFunctionListView = (ListView) findViewById(R.id.list_view);
mFunctions = new ArrayList<>();
mFunctions.add("去评分");
mFunctions.add("功能介绍");
mFunctions.add("系统通知");
mFunctions.add("帮助与反馈");
mFunctions.add("检查新版本");
//连接数据和视图
mFunctionAdapter = new FunctionAdapter(MainActivity.this,mFunctions);
mFunctionListView.setAdapter(mFunctionAdapter);
//当Adapter的数据更新时,通知视图刷新页面
mFunctionAdapter.notifyDataSetChanged();
2.2 ListView的优化
1. 视图的重用
因为ListView中的每一项的视图(Item Layout)基本差不多的,为了避免每次数据变化都要运行视图和获取控件的程序,节约运行时间,我们可以把视图的不变的控件都提取出来并交给一个视图(ViewHolder)管理,作为一个固定的视图。当数据变化时,可以直接引用ViewHolder的视图,从而达到了视图重用的目的。
2. Item不同怎么办?
用getItemViewType()方法
3. 如何做风格迥异的分割线?
android:footerDividersEnabled="ture"/"false" 设置分割线的存在与否;
android:divider="@color/divider_color" 设置分割线的颜色;
android:dividerHeight="1px" 设置分割线的粗细
课堂拾遗:
代码的前后顺序很重要,比如:
下面一段添加数据的代码
public List<String> s ;
s = new ArrayList<>();
s.add("Jaca");
s.add("Tom");
s.add("Frank")
若是将 代码给成这样,运行就会终止,因为第二行的数据没有容易让它放。
public List<String> s ;
s.add("Jaca");
s = new ArrayList<>();
s.add("Tom");
s.add("Frank")