zoukankan      html  css  js  c++  java
  • $《第一行代码:Android》读书笔记——第3章 UI基础

      (一)Android常用控件及简单用法

      1、如下图:

      2、补充:

      (1)margin:外边距;padding:内边距。

      (2)gravity:子元素的位置;layout_gravity:子元素在父元素中的位置。

      (3)当布局方向为横向时,不能指定子元素在横向上的对齐方式;竖向同理。

      (二)四种布局

      1、布局与控件的嵌套关系:

      2、四种基本布局

      (三)自定义控件的使用  

      1、Android中控件和布局的继承结构图:

      2、在xml文件中引入布局

      假如新建了一个名为title.xml的布局文件,作为标题栏,然后在activity_main.xml中可以用<include layout="@layout/title" />这样的方法引入title.xml的布局。

      3、创建自定义控件并为控件中的元素添加点击事件:

      (1)title_base.xml和color.xml(用于保存常用颜色)

      title_base.xml:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="wrap_content"
     5     android:background="@drawable/TitleBaseBg"
     6     android:orientation="horizontal" >
     7 
     8     <LinearLayout
     9         android:layout_width="0dp"
    10         android:layout_height="wrap_content"
    11         android:layout_gravity="center"
    12         android:layout_weight="1"
    13         android:gravity="left"
    14         android:orientation="vertical" >
    15 
    16         <ImageButton
    17             android:id="@+id/title_base_left_ib"
    18             android:layout_width="wrap_content"
    19             android:layout_height="wrap_content"
    20             android:background="@drawable/Transparent"
    21             android:padding="5dp"
    22             android:src="@drawable/back1_64" />
    23     </LinearLayout>
    24 
    25     <LinearLayout
    26         android:layout_width="0dp"
    27         android:layout_height="wrap_content"
    28         android:layout_gravity="center_vertical"
    29         android:layout_weight="1"
    30         android:gravity="center"
    31         android:orientation="vertical" >
    32 
    33         <TextView
    34             android:id="@+id/title_base_middle_tv"
    35             android:layout_width="wrap_content"
    36             android:layout_height="wrap_content"
    37             android:text="我的App"
    38             android:textColor="@drawable/White"
    39             android:textSize="20sp" />
    40     </LinearLayout>
    41 
    42     <LinearLayout
    43         android:layout_width="0dp"
    44         android:layout_height="wrap_content"
    45         android:layout_gravity="center"
    46         android:layout_weight="1"
    47         android:gravity="right"
    48         android:orientation="vertical" >
    49 
    50         <ImageButton
    51             android:id="@+id/title_base_right_ib"
    52             android:layout_width="wrap_content"
    53             android:layout_height="wrap_content"
    54             android:background="@drawable/Transparent"
    55             android:padding="5dp"
    56             android:src="@drawable/add4_64" />
    57     </LinearLayout>
    58 
    59 </LinearLayout>

      color.xml:

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <resources>
    3 
    4     <drawable name="TitleBaseBg">#ff272636</drawable>
    5     <drawable name="Transparent">#00ffffff</drawable>
    6     <drawable name="White">#ffffffff</drawable>
    7 
    8 </resources>

      (2)BaseTitleLayout.java,是个抽象类,继承自LinearLayout:

     1 public abstract class BaseTitleLayout extends LinearLayout {
     2     protected ImageButton titleBaseLeftIb;
     3     protected TextView titleBaseMiddleTv;
     4     protected ImageButton titleBaseRightIb;
     5 
     6     public BaseTitleLayout(Context context, AttributeSet attrs) {
     7         super(context, attrs);
     8         LayoutInflater.from(context).inflate(R.layout.title_base, this);
     9 
    10         titleBaseLeftIb = (ImageButton) findViewById(R.id.title_base_left_ib);
    11         titleBaseMiddleTv = (TextView) findViewById(R.id.title_base_middle_tv);
    12         titleBaseRightIb = (ImageButton) findViewById(R.id.title_base_right_ib);
    13 
    14         changeUI();
    15         onLeftClick();
    16         onRightClick();
    17     }
    18 
    19     // 改变标题栏按钮、文字、背景等
    20     protected abstract void changeUI();
    21 
    22     // 标题栏左边按钮的点击事件
    23     protected abstract void onLeftClick();
    24 
    25     // 标题栏右边按钮的点击事件
    26     protected abstract void onRightClick();
    27 
    28 }

      (3)MainActivityTitleLayout.java,继承自BaseTitleLayout:

     1 public class MainActivityTitleLayout extends BaseTitleLayout {
     2 
     3     public MainActivityTitleLayout(Context context, AttributeSet attrs) {
     4         super(context, attrs);
     5 
     6     }
     7 
     8     @Override
     9     protected void changeUI() {
    10         titleBaseLeftIb.setVisibility(View.INVISIBLE);
    11     }
    12 
    13     @Override
    14     protected void onLeftClick() {
    15 
    16     }
    17 
    18     @Override
    19     protected void onRightClick() {
    20         titleBaseRightIb.setOnClickListener(new OnClickListener() {
    21 
    22             @Override
    23             public void onClick(View v) {
    24                 Toast.makeText(getContext(), "点击了添加按钮", Toast.LENGTH_SHORT)
    25                         .show();
    26             }
    27         });
    28     }
    29 
    30 }

      (4)activity_main.xml:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:orientation="vertical" >
     5 
     6     <com.easydo.layout.MainActivityTitleLayout
     7         android:layout_width="match_parent"
     8         android:layout_height="wrap_content" >
     9     </com.easydo.layout.MainActivityTitleLayout>
    10 
    11 </LinearLayout>

      (5)MainActivity:

    1 public class MainActivity extends Activity {
    2 
    3     @Override
    4     protected void onCreate(Bundle savedInstanceState) {
    5         super.onCreate(savedInstanceState);
    6         requestWindowFeature(Window.FEATURE_NO_TITLE);
    7         setContentView(R.layout.activity_main);
    8     }
    9 }

      (6)运行效果:

     

      (四)ListView的用法

      1、最简单的用法

      (1)xml文件:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:orientation="vertical" >
     5 
     6     <ListView
     7         android:id="@+id/content_lv"
     8         android:layout_width="match_parent"
     9         android:layout_height="match_parent" >
    10     </ListView>
    11 
    12 </LinearLayout>

      (2)MainActivity(详细步骤见注释)

     1 public class MainActivity extends Activity {
     2     // 1.创建数据数组
     3     private String[] animalList = { "猫", "狗", "狐狸", "小熊", "鱼", "老虎",
     4             "长颈鹿", "象", "龙猫" };
     5 
     6     ListView listView;
     7 
     8     @Override
     9     protected void onCreate(Bundle savedInstanceState) {
    10         super.onCreate(savedInstanceState);
    11         setContentView(R.layout.activity_main);
    12 
    13         // 2.创建以数据列表元素类型为泛型的适配器
    14         // 构造函数:第一个参数为上下文;第二个参数为列表项的布局,这里用Android自带的布局;第三个参数为第1步中准备好的数据数组.
    15         // simple_list_item_1:单行显示,其中只有一个TextView
    16         // simple_list_item_2:双行显示,有两个TextView,两行字大小不一样
    17         // two_line_list_item:双行显示,有两个TextView,两行字大小一样
    18         ArrayAdapter<String> adapter = new ArrayAdapter<String>(
    19                 MainActivity.this, android.R.layout.simple_list_item_1,
    20                 animalList);
    21         // 3.获取xml中的ListView实例
    22         listView = (ListView) findViewById(R.id.content_lv);
    23 
    24         // 4.用第2步创建好的适配器来设置ListView实例的内容
    25         listView.setAdapter(adapter);
    26     }
    27 }

      (3)运行结果:

      2、定制的ListView界面

      上面的ListView每个项只能显示一个文本,太单调了,下面通过定制的方式让它丰富起来。实现左边显示一个图片,右边显示动物名字的效果。

      步骤如下:

      (1)创建一个实体类Animal,作为ListView适配器的类型:

     1 public class Animal {
     2     private String name;
     3     private int imageId;
     4 
     5     public Animal(String name, int imageId) {
     6         this.name = name;
     7         // 对应的图片ID
     8         this.imageId = imageId;
     9     }
    10 
    11     public String getName() {
    12         return name;
    13     }
    14 
    15     public int getImageId() {
    16         return imageId;
    17     }
    18 
    19 }

      (2)创建animal_item.xml文件,其中包含一个ImageView和一个TextView:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical" >
     6 
     7     <ImageView
     8         android:id="@+id/animal_img_iv"
     9         android:layout_width="wrap_content"
    10         android:layout_height="wrap_content" />
    11 
    12     <TextView
    13         android:id="@+id/animal_name_tv"
    14         android:layout_width="wrap_content"
    15         android:layout_height="wrap_content"
    16         android:layout_gravity="center"
    17         android:layout_marginLeft="10dp" />
    18 
    19 </LinearLayout>

      (3)创建自定义适配器类AnimalAdapter,以Animal类为泛型,继承自ArrayAdapter<Animal>,重写父类的构造方法和getView方法,getView方法会在每个子项被滚动到屏幕内的时候调用:

     1 public class AnimalAdapter extends ArrayAdapter<Animal> {
     2 
     3     private int resourceId;
     4 
     5     public AnimalAdapter(Context context, int textViewResourceId,
     6             List<Animal> objects) {
     7         super(context, textViewResourceId, objects);
     8         // textViewResourceId:ListView子项布局的id;objects:数据
     9         resourceId = textViewResourceId;
    10     }
    11 
    12     // getView方法会在每个子项被滚动到屏幕内的时候调用
    13     @Override
    14     public View getView(int position, View convertView, ViewGroup parent) {
    15         // 1.获取当前项的Animal实例
    16         Animal animal = getItem(position);
    17 
    18         // 2.为这个子项加载传入的布局
    19         View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
    20 
    21         // 3.用view的findViewById方法获取到子项布局控件的实例
    22         ImageView animalImage = (ImageView) view
    23                 .findViewById(R.id.animal_img_iv);
    24         TextView animalName = (TextView) view.findViewById(R.id.animal_name_tv);
    25 
    26         // 4.设置相应控件的内容
    27         animalImage.setImageResource(animal.getImageId());
    28         animalName.setText(animal.getName());
    29 
    30         // 5.返回view
    31         return view;
    32     }
    33 }

      注:在getView方法里还可以为item的子控件添加点击事件。

      (4)MainActivity:

     1 public class MainActivity extends Activity {
     2     // 1.创建动物名字数组和动物数据列表
     3     private String[] animalNameList = { "猫", "狗", "狐狸", "小熊", "鱼", "老虎", "长颈鹿",
     4             "象", "龙猫" };
     5     private List<Animal> animalList = new ArrayList<Animal>();
     6     // 为简单起见,把所有动物的图片都设置为ic_launcher
     7     private int animalImageResourceId = R.drawable.ic_launcher;
     8 
     9     ListView listView;
    10 
    11     @Override
    12     protected void onCreate(Bundle savedInstanceState) {
    13         super.onCreate(savedInstanceState);
    14         setContentView(R.layout.activity_main);
    15 
    16         // 2.初始化动物数据
    17         initAnimals();
    18 
    19         // 3.创建自定义的适配器实例
    20         // 构造函数:第一个参数:当前上下文;第二个参数:子项布局xml文件;第三个参数:动物数据List
    21         AnimalAdapter adapter = new AnimalAdapter(MainActivity.this,
    22                 R.layout.animal_item, animalList);
    23 
    24         // 4.获取ListView实例
    25         listView = (ListView) findViewById(R.id.content_lv);
    26 
    27         // 5.设置适配器
    28         listView.setAdapter(adapter);
    29 
    30     }
    31 
    32     private void initAnimals() {
    33         for (int i = 0; i < animalNameList.length; i++) {
    34             Animal animal = new Animal(animalNameList[i], animalImageResourceId);
    35             animalList.add(animal);
    36         }
    37     }
    38 }

      (5)运行效果:

      3、提升ListView的效率

      在AnimalAdapter的getView方法中,每次都将布局重新加载一遍,当快速滚动屏幕时候就会带来性能问题,为此要做一些优化。修改如下:

     1 public class AnimalAdapter extends ArrayAdapter<Animal> {
     2 
     3     private int resourceId;
     4 
     5     public AnimalAdapter(Context context, int textViewResourceId,
     6             List<Animal> objects) {
     7         super(context, textViewResourceId, objects);
     8         // textViewResourceId:ListView子项布局的id;objects:数据
    9 resourceId = textViewResourceId; 10 } 11 12 // getView方法会在每个子项被滚动到屏幕内的时候调用 13 @Override 14 public View getView(int position, View convertView, ViewGroup parent) { 15 Animal animal = getItem(position); 16 17 // 用于提升性能 18 View view; 19 ViewHolder viewHolder; 20 if (convertView == null) { 21 view = LayoutInflater.from(getContext()).inflate(resourceId, null); 22 viewHolder = new ViewHolder(); 23 viewHolder.animalImage = (ImageView) view 24 .findViewById(R.id.animal_img_iv); 25 viewHolder.animalName = (TextView) view 26 .findViewById(R.id.animal_name_tv); 27 28 // 将viewHolder存储在View中 29 view.setTag(viewHolder); 30 } else { 31 view = convertView; 32 33 // 重新获取viewHolder 34 viewHolder = (ViewHolder) view.getTag(); 35 } 36 37 viewHolder.animalImage.setImageResource(animal.getImageId()); 38 viewHolder.animalName.setText(animal.getName()); 39 40 return view; 41 } 42 43 // 创建内部类用于缓存,优化性能 44 class ViewHolder { 45 ImageView animalImage; 46 TextView animalName; 47 } 48 }

      4、为ListView的子项添加点击事件

      使用ListView对象的setOnItemClickListener方法,如:

     1      ...
     2         listView.setAdapter(adapter);
     3 
     4         listView.setOnItemClickListener(new OnItemClickListener() {
     5 
     6             @Override
     7             public void onItemClick(AdapterView<?> parent, View view,
     8                     int position, long id) {
     9                 Animal animal = animalList.get(position);
    10                 Toast.makeText(MainActivity.this, animal.getName(),
    11                         Toast.LENGTH_SHORT).show();
    12             }
    13 
    14         });

       5、补充:

      (1)xml中设置ListView的分割线颜色:android:divider="#000"

      (2)将ListView定位到最后一行:listView.setSelection(dataList.size());

      (五)单位和尺寸

      1、像素密度:每英寸所包含的像素数,单位为dpi.

      x方向像素密度值的获取方法:float xdpi = getResources().getDisplayMetrics().xdpi;

      y方向像素密度值的获取方法:float ydpi = getResources().getDisplayMetrics().ydpi;

      2、使用dp为单位来设置控件的宽和高,就可以保证控件在不同像素密度的屏幕上显示的比例是一致的。使用sp来设置字体大小同理。

      

      (六)制作Nine-Patch图片

       详见另一篇博文:Android制作和使用Nine-Patch图片

  • 相关阅读:
    RabbitMQ学习之:(一)初识、概念及心得
    给Eclipse_Android添加智能提示功能
    C#异步编程之:(三)使用TaskScheduler.UnobservedTaskException
    类设计技巧
    初始化块
    子类构造器
    静态域与静态方法
    构造器中调用另一个构造器
    重载
    无参数的构造器
  • 原文地址:https://www.cnblogs.com/jiayongji/p/5332477.html
Copyright © 2011-2022 走看看