3. UI界面

3.1 常见控件

3.1.1 TextView

显示一段文本信息。默认左上角对齐。
属性 释义
android:layout_width 宽度(所有控件都有) match_parent:当前控件大小与父布局一致
fill_parent:同match_parent一样,官方推荐match_parent
wrap_content:当前控件大小正好能包含内容(由内容来决定)
android:layout_height 高度 (所有控件都有) 同上
android:gravity 文字对齐方式 top、bottom、left、right、center等 , 可 以 用 “ | ” 来 同 时 指 定 多 个 值
android:textSize 文字大小 -
android:textColor 文字颜色 -

3.1.2 Button

按钮

3.1.3 EditText

输入框控件
属性 释义
android:hint 输入框的提示信息(相当于H5的placeholder) -
android:maxLines 指定最大行数 数字

3.1.4 ImageView

展示图片控件
属性 释义
android:src 指定图片 -
通过以下代码来动态的为图片控件指定图片资源:
imageView.setImageResource(R.drawable.test);

3.1.5 ProgressBar

进度条
属性 释义
android:visibility 控件是否可见(所有控件都有) visible:可见,默认值
invisible:不可见,但仍然占据原来的位置和大小(可理解为透明)
gone:不仅不可见,而且不占用原有任何空间
android:max 在给进度条添加如下属性的时候:
style="?android:attr/progressBarStyleHorizontal",
该进度条就成了一个水平进度条。
此时设置此max属性表示最大值为多少,比如100
-
//设置可见性,还有View.GONE、View.INVISIBLEprogressBar.setVisibility(View.VISIBLE);//设置进度progressBar.setProgress(60);

3.1.6 AlertDialog

对话框,置顶于所有控件之上,屏蔽他们的交互能力。
/** * 1.首先通过AlertDialog.Builder来创建一个AlertDialog实例 * 2.然后设置标题、内容、可否取消等属性 * 3. setPositiveButton()方法为对话框确定按钮设置文本以及事件 * 4. setNegativeButton()方法则为取消按钮设置文本及事件 */AlertDialog.Builder dialog=new AlertDialog.Builder(MainActivity.this);dialog.setTitle("This is a dialog");dialog.setMessage("Some thing want to show");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();

3.1.7 ProgressDialog

对话框进度条
/** * 1.先创建一个ProgressDialog对象 * 2.同样设置标题、内容、是否可取消 * 3.设置setCancelable(false)后则不能按Back键关闭对话框 */ProgressDialog dialog=new ProgressDialog(MainActivity.this);dialog.setTitle("This is a progress dialog");dialog.setMessage("Please Loading ....");dialog.setCancelable(false);dialog.show();//可以调用此方法来关闭对话框//dialog.dismiss();

3.2 基本布局



3.2.1 线性布局(LinearLayout)

将所有其包含的控件在线性方向上依次排列,是一种非常常用的布局。
属性 释义
android:orientation 线性排列方向 horizontal(水平方向)、vertical(垂直方向)
android:layout_gravity 控件在布局中的对齐方式 注意:当布局方向为horizontal时,只有垂直方向的对齐方式起作用
同理,当为vertical时,只有水平方向的起作用。
android:layout_weight 使用比例来指定控件大小 比如一共有2个控件,一个设为3,另一个设为2,则第一个占3/5,第二个占2/5;
同理如果两个都想占一半,则每个设为1即可,即1/2

3.2.2 相对布局(RelativeLayout)

相对布局更加随意,通过相对定位的方式让控件出现在布局的任何位置。因此相对布局属性非常多,但有规律可循。
属性 释义
android:layout_alignParentLeft 相对父布局向左 true、false
android:layout_alignParentTop 相对父布局向上 true、false
android:layout_alignParentRight 相对父布局向右 true、false
android:layout_alignParentBottom 相对父布局向下 true、false
android:layout_centerInParent 相对父布局居中 true、false
android:layout_above 让控件位于另一个控件上方,注意!该控件需要定义在另一个控件
后面,下同
需要指定参考的控件id引用,如:@id/button1
android:layout_below 让控件位于另一个控件下方 同上
android:layout_toLeftOf 让控件位于另一个控件左侧 同上
android:layout_toRightOf 让控件位于另一个控件右侧 同上
android:layout_alignLeft 让控件左边缘和另一个控件左边缘对齐 控件id的引用
android:layout_alignRight 让控件右边缘和另一个控件右边缘对齐 同上
android:layout_alignTop 让控件上边缘和另一个控件上边缘对齐 同上
android:layout_alignBottom 让控件下边缘和另一个控件下边缘对齐 同上

3.2.3 FrameLayout

这种布局没有任何的定位方式,所有的控件都会摆放在布局的左上角。

3.2.4 TableLayout

使用表格的方式来排列控件。 TableRow:一个标签代表一行,而在一行中的每一个控件都代表一列。但是在TableRow中无法指定控件的宽度,所以可能不会完全利用屏幕的宽度。 android:stretchColumns(属于布局的属性):将TableLayout中的某一列进行拉伸,以达到自动适应屏幕宽度的目的。指定0,表示将第1列拉伸,指定1表示将第2列拉伸。

3.3 自定义控件



所以控件都直接或间接的继承View;所以布局都直接或间接的继承ViewGroup。

3.3.1 引入布局

(1)新建一个布局title.xml (2)在主布局文件中添加引用,如下: (3)别忘了隐藏系统自带的标题栏:
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    // 窗口无标题(别忘了继承自Activity才起作用)    requestWindowFeature(Window.FEATURE_NO_TITLE);    setContentView(R.layout.activity_main);}

3.3.2 创建自定义控件

         当一些布局中的控件要求能够响应事件时,比如标题栏的返回按钮,不管在哪个活动中,返回按钮的作用都是销毁当前活动,如果在每一个活动中都注册相同的事件,则又增加了冗余代码,此时自定义控件可以解决此问题。 (1)创建一个自定义控件布局类(这里还是使用标题栏TitleLayout),继承自LinearLayout类
package com.jastar.uicustomviews.layout;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.widget.LinearLayout;import com.jastar.uicustomviews.R;public class TitleLayout extends LinearLayout {    /**     * 重写带有两个参数的构造函数,在布局中引入TitleLayout就会调用这个函数     *     * @param context     * @param attrs     */    public TitleLayout(Context context, AttributeSet attrs) {        super(context, attrs);        /**         * 1.通过LayoutInflater.from()方法构造一个LayoutInflater对象         * 2.通过该对象的inflate()来动态加载title.xml布局         * 3.inflater(要加载的布局文件id,给加载好的布局再指定一个父布局这里使用TitleLayout)         */        LayoutInflater.from(context).inflate(R.layout.title, this);    }}

(2)在布局文件中添加这个自定义控件
添加自定义控件和添加普通控件方式一样,只不过需要指定完整类名 (3)给按钮添加点击事件
public TitleLayout(Context context, AttributeSet attrs) {    super(context, attrs);    /**     * 1.通过LayoutInflater.from()方法构造一个LayoutInflater对象     * 2.通过该对象的inflate()来动态加载title.xml布局     * 3.inflater(要加载的布局文件id,给加载好的布局再指定一个父布局这里使用TitleLayout)     */    LayoutInflater.from(context).inflate(R.layout.title, this);    //同样获取到按钮对象    Button btnBack = (Button) this.findViewById(R.id.title_back);    Button btnEdit = (Button) this.findViewById(R.id.title_edit);    btnBack.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            //返回按钮销毁当前活动            ((Activity) getContext()).finish();        }    });    btnEdit.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            Toast.makeText(getContext(), "您点击了编辑按钮", Toast.LENGTH_SHORT).show();        }    });}
这样的话,每当引入该布局文件,返回按钮和编辑按钮的事件已经写好,将被共用。

3.4 ListView控件(很常用)

3.4.1 简单使用

(1)在布局中添加ListView控件并指定id为list_view,宽高设为match_parent (2)在代码中使用:
package com.jastar.listviewtest;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.ArrayAdapter;import android.widget.ListView;public class MainActivity extends AppCompatActivity {    /**     * ListView的数据是需要提前准备好的,无论是从数据库读的还是从哪里来的;这里模拟一些数据     */    private String[] data = {"Apple", "Banana", "Orange", "Watermelon", "Pear", "Grap", "Pineapple", "Strawberry", "Cherry", "Mango"};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        /**         * 1.Android中的数组是无法直接传递给ListView的,需要借助适配器Adapter来实现         * 2.ArrayAdapter还算是比较好用的,可以指定泛型         * 3.构造函数需要参数,不同场景应该使用不同的构造函数,此处的参数依次为:         * param1:当前上下文         * param2:ListView子项布局id,这是一个安卓内置的子项布局文件,里面只有一个TextView,简单显示文本即可         * param3:要适配的数据         */        ArrayAdapter adapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, data);        ListView listView = (ListView) findViewById(R.id.list_view);        //调用setAdapter方法,将适配器传入        listView.setAdapter(adapter);    }}


3.4.2 定制ListView界面

定制ListView界面就是需要我们自定义ListView子项的布局(下面的例子实现列表名称前显示对应图片的功能) (1)新建Fruit实体类,有两个字段:name(水果名称),imageId(水果对应的图片id) (2)创建自定义子项布局fruit_item.xml
<?xml version="1.0" encoding="utf-8"?>        
(3)创建自定义适配器FruitAdapter类继承自ArrayAdapter类,指定Fruit实体类泛型
package com.jastar.listviewtest.Adapter;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.TextView;import com.jastar.listviewtest.Entity.Fruit;import java.util.List;public class FruitAdapter extends ArrayAdapter {    private int resourceId;    /**     * 重写父类构造方法,用于将上下文、ListView、子项布局的id和数据都传递进来     *     * @param context            上下文     * @param textViewResourceId 子项布局Id     * @param objects            数据     */    public FruitAdapter(Context context, int textViewResourceId, List objects) {        super(context, textViewResourceId, objects);        resourceId = textViewResourceId;    }    /**     * 1.重写getView方法,该方法在每个子项被滚动到屏幕内的时候调用     *     * @param position     * @param convertView     * @param parent     * @return     */    @Override    public View getView(int position, View convertView, ViewGroup parent) {        //通过getItem()获取当前项的实例        Fruit fruit = getItem(position);        //使用LayoutInflater将该子项加载到我们传入的布局        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;    }}
(4)在活动中使用
@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //初始化水果数据,模拟假数据    initFruitList();    FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);    ListView view = (ListView) findViewById(R.id.list_view);    view.setAdapter(adapter);}private void initFruitList() {    Fruit apple = new Fruit("Apple", R.drawable.fruit_apple_pic);    fruitList.add(apple); //....}


3.4.3 提升ListView的运行效率

(1)优化加载布局的次数 在 FruitAdapter的getView()方法中每次都将布局重新加载了一遍,当ListView快速滚动的时候,效率会很低。 其实getView()还有一个参数没用到就是convertView,这个参数用于将之前加载好的布局进行缓存,以便重用。 修改FruitAdapter中的代码:

(2)优化获取控件实例次数 在getView()方法中每次都会去findViewById()控件实例,可以借助ViewHolder来对这个问题优化。

3.4.4 ListView点击事件

@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //...    view.setOnItemClickListener(new AdapterView.OnItemClickListener() {        @Override        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {            Fruit fruit = fruitList.get(position);            Toast.makeText(MainActivity.this, "name:" + fruit.getName() + ",imageid:" + fruit.getImageId(), Toast.LENGTH_SHORT).show();        }    });}

3.5 单位和尺寸

在布局文件中常用的单位有:px、pt、dp、sp px:像素 pt:磅数,1磅等于1/72英寸,一般pt作为字体的单位来使用
px和pt在不同的分辨率手机上显示的效果是完全不相同的,所以这两个单位在手机领域上不适用。 因此,谷歌为Android引入了一套新的单位:dp、sp
dp:密度无关像素的意思,也被称作dip,和px相比,它在不同密度的屏幕中的显示比例保持一致。 sp:可伸缩像素的意思,采用了和dp同样的设计理念,解决文字大小适配问题
密度:         Android 中的密度就是屏幕每英寸所包含的像素数,通常以 dpi为单位。比如一个手机屏幕的宽是 2 英寸长是 3 英寸,如果它的分辨率是 320*480 像素,那这个屏幕的密度就是 160dpi,如果它的分辨率是640*960,那这个屏幕的密度就是 320dpi,因此密度值越高的屏幕显示的效果就越精细。         根据 Android 的规定,在 160dpi 的屏幕上,1dp 等于 1px,而在 320dpi 的屏幕上,1dp就等于 2px。

3.6 编写界面最佳实践

3.6.1 制作Nine-Patch图片(可拉伸图片)

Nine-Patch图片:是一种被特殊处理过的图片,能够指定哪些区域可以延伸。 比如: 有一张图片:

当图片宽度不足以填充整个屏幕时,图片就会被均匀拉伸,成这样:

所以Nine-Patch图片就是为了解决这个问题。 (1)在Android sdk目录tools文件夹下,找到 draw9patch.bat 文件双击打开 (2)点击File→Open 9-patch将图片加载进来,如:

(3)可以在四周绘制黑线 上边框和左边框的黑线:表示当图片需要拉伸时就拉伸黑线部分的区域 有边框和下边框的黑线:可画可不画,表示内容绘制区域,说白了就是当有内容放置的时候只放到此区域内。 (4)点击导航File→Save 9-patch,就会生成一个特殊的后缀为“.9.png”的图片。


更多相关文章

  1. Android(安卓)RelativeLayout布局
  2. AndroidStudio插件:布局文件转化Databinding
  3. Android(安卓)SlidingMenu 布局实现
  4. Android(安卓)关于嵌套listView时onItemClick事件不响应的解决办
  5. 【Android】毫无耦合性,一个Item根布局搞定 item侧滑删除菜单,像IO
  6. Android(安卓)Gradle 指定 Module 打包
  7. API DEMO APPWIGHT 学习
  8. Android基础控件——EditText隐藏软键盘、Enter键隐藏软键盘、点
  9. Android(安卓)自定义Toolbar的Menu菜单

随机推荐

  1. android上传图片和参数(属性)到服务器
  2. Android(安卓)jni调用第三方so库和.h文件
  3. Android中SQLite数据库存储方式 .(转)
  4. ubuntu下Qt之android环境配置以及一些常
  5. Android中Touch手势分发
  6. HTML iframe标签用法案例详解
  7. HTML DOM setInterval和clearInterval方
  8. 利用模糊实现视觉3D效果实例讲解
  9. sass 常用备忘案例详解
  10. 字符串和数组api操作学习实践