第一行代码读书笔记___3章

第三章 UI

3.1 简介UI重要性
3.2 常见控件使用方法
3.2.1 TextView
3.2.2 Button
点击事件三种实现方式:内部类,外部类,接口

3.2.3 TextView
hint:提示信息
maxLines:最大行数,超出部分文本向上滚动
获取信息: getText().tostring

3.2.4 ImageView
动态设置资源文件:

imageView.setImageResource(R.drawable.img);

3.2.5 ProgressBar
默认为环形进度条
水平进度条:

style="?android:attr/progressBarStyleHorizontal"
android:max="100" //这里设置最大值为100

可以通过以下进行相关操作:

progressBar.getProgress();
progressBar.setProgress(progress);
progressBar.getVisibility() 

3.2.6 AlertDialog
基本用法:

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.button:
        AlertDialog.Builder dialog = new AlertDialog.Builder(context);
        dialog.setTitle("This is a Dialog");
        dialog.setMessage("Something important.");
        dialog.setCancelable(false);
        dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
            }
        });
        dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
            }
        });
        dialog.show();
        break;
    default: 
        break;
    }
}

3.2.7 ProgressDialog

ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("This is ProgressDialog");
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(true);
progressDialog.show();

如果在 setCancelable()中传入了 false, 表示 ProgressDialog 是不能通过 Back 键取消,数据加载完成后用 ProgressDialog 的dismiss()关闭对话框。


3.3四种基本布局
3.3.1 LinearLayout

  • layout_gravity:
    如LinearLayout中的控件如button使用了layout_gravity,如LinearLayout的orientation是Verticle,则layout_gravity只在orientation方向起作用,反之同理。

  • layout_weight:
    1.LinearLayout里的控件宽度设为0,所占空间按照layout_weight比例显示。
    2.如果一个控件A的layout_weight为1,另一个B宽度为wrap_content则A填满除了B所用空间外的所有空间,可用于屏幕适配。例图如下:
    这里写图片描述

3.3.2 RelativeLayout
layout_toLeftOf 表示让一个控件位于另一个控件的左侧
layout_alignLeft 表示让一个控件的左边缘和另一个控件的左边缘对齐

3.3.3 FrameLayout
所有的控件都会摆放在布局的左上角

3.3.4 TableLayout

  • 行、列:
    在 TableLayout 中每加入一个 TableRow 就表示在表格中添加了一行,然后在 TableRow 中每加入一个控件,就表示在该行中加入了一列, TableRow 中的控件是不能指定宽度的。

  • 合并单元格(控件级)
    如button合并前两列android:layout_span=”2”

  • 拉伸宽度,屏幕适配(TableLayout级)
    因为在 TableRow 中我们无法指定控件的宽度。这时使用android:stretchColumns 将 TableLayout 中的某一列进行拉伸,以达到自动适应屏幕宽度的作用。stretchColumns的value是数字,从0算起,如1表示第二列。


3.4自定义控件
这里写图片描述
我们所用的所有控件都是直接或间接继承自 View ,ViewGroup 则是一种特殊的 View, 它可以包含很多的子 View 和子 ViewGroup,是一个用于放置控件和布局的容器。

3.4.1引入布局(重复使用布局)

<include layout="@layout/title" />
//引入一个title.xml布局文件,title.xml编写内容和普通布局一样

3.4.2自定义控件(重复使用布局和代码)
以引入标题布局为例,如果在每一个活动中都需要重新注册一遍返回按钮的点击事件, 无疑又是增加了很多重复代码,这种情况最好是使用自定义控件的方式来解决。

public class TitleLayout extends LinearLayout {
    public TitleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInfalter.from(context).infate(R.layout.title,this);

        Button titleBack = (Button) findViewById(R.id.title_back);
        Button titleEdit = (Button) findViewById(R.id.title_edit);
        titleBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                ((Activity) getContext()).finish();
            }
        });
        titleEdit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "Edit", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
/*通过 LayoutInflater 的 from()方法可以构建出一个 LayoutInflater
对象,然后调用 inflate()方法就可以动态加载一个布局文件, inflate()方法接收两个参数,第一个参数是要加载的布局文件的 id,这里我们传入R.layout.title,第二个参数是给加载好的布局再添加一个父布局,这里我们想要指定为 TitleLayout,于是直接传入 this。*/

xml中:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.uicustomviews.TitleLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
    ></com.example.uicustomviews.TitleLayout>
</LinearLayout>

3.5 ListView
ListView.setSelection(msgList.size()); // 将ListView定位到最后一行。

ArrayAdapter:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(
MainActivity.this, android.R.layout.simple_list_item_1, data);
listview.setAdapter(adapter);
//String可以是泛型,布局文件可以自定义,这里用系统提供的,data是数据集。

泛型例子:

public class FruitAdapter extends ArrayAdapter<Fruit> {
    private int resourceId;
    public FruitAdapter(Context context, int textViewResourceId, List<Fruit> objects) {
        super(context, textViewResourceId, objects);
        resourceId = textViewResourceId;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Fruit fruit = getItem(position); // 获取当前项的Fruit实例
        View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
        ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
        TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
        fruitImage.setImageResource(fruit.getImageId());
        fruitName.setText(fruit.getName());
        return view;
    }
}

MainActivity中

initFruitsList(); // 初始化水果数据
FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);
listView.setAdapter(adapter);

3.5.3 提升ListView的运行效率
目前我们 ListView的运行效率是很低的, 因为在 FruitAdapter的 getView()方法中每次都将布局重新加载了一遍,当 ListView 快速滚动的时候这就会成为性能的瓶颈。
优化:
getView()方法中还有一个 convertView 参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用

@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);
    View view;
    if (convertView == null) {
        view = LayoutInflater.from(getContext()).inflate(resourceId, null);
    } else {
        view = convertView;
    }
    ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
    TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
    fruitImage.setImageResource(fruit.getImageId());
    fruitName.setText(fruit.getName());
    return view;
}

继续优化:
每次在 getView()方法中还是会调用 View的 findViewById()方法来获取一次控件的实例。
我们可以借助一个 ViewHolder 来对这部分性能进行优化

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Fruit fruit = getItem(position);
    View view;
    ViewHolder viewHolder;
    if(convertView == null) {
        view = LayoutInflater.from(getContext()).inflate(resourceId,null);
        viewHolder = new ViewHolder();
        viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
        viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);
        view.setTag(viewHolder);// 将ViewHolder存储在view中
    } else {
        view = convertView;
        viewHolder = (ViewHolder) view.getTag();
    }
    viewHolder.fruitImage.setImageResource(fruit.getImageId());
    viewHolder.fruitName.setText(fruit.getName());
    return view;
}
class ViewHolder {
    ImageView fruitImage;
    TextView fruitName;
}

3.5.4 ListView的点击事件
在MainActivity中:

listView.setOnItemClickListener(new OnClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //do something by position
    }
})

3.6 单位和尺寸
px、 pt、 dp 、 sp

3.6.1 px 和 pt
px是像素的意思,是屏幕中可以显示的最小元素单位
pt是磅数的意思,1磅等于1/72英寸,一般pt都会作为字体的单位来使用
这两种单位在不同分辨率的屏幕上显示的效果是完全不同的,一般不使用。

3.6.2 dp 和 sp
dp是密度无关像素的意思,也称为dip,在不同密度的屏幕中显示比例一样。
sp是可伸缩像素的意思,采用和dp同样的设计理念,解决了文字大小的适配。
密度:

android中的密度是屏幕每英寸所包含的像素数,通常以dpi为单位,比如一个手机屏幕的宽是 2 英寸长是 3 英寸,如果它的分辨率是 320*480 像素,那这个屏幕的密度就是 160dpi,如果它的分辨率是 640*960,那这个屏幕的密度就是 320dpi, 因此密度值越高的屏幕显示的效果就越精细。

获取密度值代码:

float xdpi = getResources().getDisplayMetrics().xdpi;
float ydpi = getResources().getDisplayMetrics().ydpi;

根据 Android 的规定,在 160dpi 的屏幕上, 1dp 等于 1px,而在 320dpi 的屏幕上, 1dp就等于 2px。因此,使用 dp 来指定控件的宽和高,就可以保证控件在不同密度的屏幕中的显示比例保持一致。
sp 的原理和 dp 是一样的,它主要是用于指定文字的大小。


3.7 编写界面的最佳实践
3.7.1 制作 Nine-Patch 图片
Nine-Patch 图片是一种被特殊处理过的 png 图片, 能够指定哪些区域可以被拉伸而哪些区域不可以。

  • 工具位置
    在 Android sdk 目录下有一个 tools 文件夹,在这个文件夹中找到 draw9patch.bat 文件,我们就是使用它来制作 Nine-Patch 图片的。 双击打开之后, 在导航栏点击 File→Open 9-patch将 message_left.png 加载进来,绘制完成后点击导航栏 File→ Save 9-patch 把绘制好的图片进行保存,此时的文件名就是message_left.9.png。

  • 绘制方法:
    我们可以在图片的四个边框绘制一个个的小黑点, 在上边框和左边框绘制的部分就表示当图片需要拉伸时就拉伸黑点标记的区域, 在下边框和右边框绘制的部分则表示内容会被放置的区域。


3.7.2 编写精美的聊天界面
利用.9图做LInearLayout背景,LinearLayout里包含textview,用msg实例定义收发控制左右显示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值