布局技巧与列表控件

1. 布局与优化

1.1五大布局

LinearLayout ——线性布局;
RelativeLayout ——相对布局;
RrameLayout ——帧布局;
AbsoulteLayout——绝对布局(被废弃);
TableLayout ——表格布局;

1.2 布局原理

UI = 布局 + 控件;

· 系统怎么把图形画出来:读取xml文件——> 解析标签 ——> 绘图(控件);
· 嵌套布局的情况:先处理第一层,绘制完第一层的控件,在处理下一层。层次越多,花费时间越多,加载慢,出现性能问题。

1.3优化布局的技巧

  1. 减少布局层次
    搭建view时,一定要留意屏幕右上角的组件树(Component Tree)。嵌套的view越深,组件数就越复杂,渲染起来就越浪费时间。
    这里写图片描述
  2. 不要嵌套多个使用layout_weight的LinearLayout
  3. <merge/>

    什么情况下考虑使用Merge?
    子视图不需要任何指定父视图的布局属性,如一个TextView只需要直接添加在父视图中用于显示即可。
    例子:
    未优化的代码:
    这里写图片描述
    此时的组件图:
    这里写图片描述
    <merge/>语句:
    这里写图片描述
    优化后的组件图:
    这里写图片描述

  4. <ViewStub/>标签—— 一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文件。

  5. 使用相对布局对控件进行组合来减少布局层次。
    (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")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值