第二篇 界面开发 (Android学习笔记)

第二篇 界面开发 php

第5章 探索界面UI元素 html

The Android View Class java

 

 

●△Widget设计步骤 android

须要修改三个XML,以及一个class程序员

1)第一个xml是布局XML文件(如:main.xml),是这个widget的。通常来讲若是用这个部件显示时间,那就只在这个布局XML中声明一个textviewOK了。 算法

2)第二个xmlwidget_provider.xml,主要是用于声明一个appwidget的。其中,Layout就是指定上面那个main.xmlshell

3)第三个xmlAndroidManifest.xml,注册broadcastReceiver信息。 数据库

4)最后那个class用于作一些业务逻辑操做。让其继承类AppWidgetProviderAppWidgetProvider中有许多方法,通常状况下咱们只是覆写onUpdate(Context,AppWidgetManager,int[])方法。编程

 

●颜色表达 windows

RGB颜色查询:http://www.atool.org/colorpicker.php

 

 

 

●几个概念的关系

1.widget并非实际存在的类,它是一个包,而VIew等就是实际存在的类,因此首字母大写。在引用时,一般:

import android.view.View;

import android.widget.TextView;

由于widget是包,因此首字母小写

 

2.在该包内放的是UI Elements, 包括TextView,ListView,可是这些元素都继承自ViewViewGroup。以下图所示:

 

其中各类layout继承自ViewGroup

 

Direct: extend directly from the super class.

Indirect: extend from a super class that directly extends the class in question.

※ 注意ViewGroup的派生类中有几个类和View的几个类重名.

 

 

View对象是Android平台中用户界面体现的基础单位。

This class represents the basic building block for user interface components. A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The ViewGroup subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.

 

View派生了TextView, EditText, ScrollView一部分UI组件类, widget(窗口小部件, widget不是类的名称).

View还派生了ViewGroup, ViewGroup类下面AbsoluteLayout, GridLayout, LinearLayout等子类, 它们是容纳、布局各类widget的容器; ViewGroup类下面还有 另外一部分UI组件类, ListView这一UI组件:

java.lang.Object

    android.view.View

          android.view.ViewGroup

               android.widget.AdapterView<T extends android.widget.Adapter>

                    android.widget.AbsListView

                         android.widget.ListView

 

android.view和android.widget是两个包;

android.view包 包括View类和ViewGroup(但不包括ViewGroup类的AbsoluteLayout等子类);

android.widget包 包括TextView, EditText, ScrollView, ListViewUI组件类, 以及ViewGroup类的AbsoluteLayout等子类.

 

android.view: Provides classes that expose basic user interface classes that handle screen layout and interaction with the user.

android.widget: The widget package contains (mostly visual) UI elements to use on your Application screen. You can also design your own.

 

●预知 Activity

一个Activity一般就是一个单独的屏幕.

 

Android项目里的proguard.cfg的做用

这是代码混淆用的

代码混淆是为了防止你的apk被反编译而代码所有暴露.不过目前的代码混淆只是把命名修改了一下而已,真正反编译时仍是能够想办法还原出来的,因此不能真正的混淆.

 

AndroidMVC模式

MVC模式-- "模型-视图-控制器"模式:

MVC是一种"架构模式"architectural pattern),不是设计模式(design pattern),属于编程的方法论。

1)最上面的一层--"视图层"View--负责给用户提供操做界面,即程序的外壳。

2)最底下的一层--"模型层"Model--负责提供数据(data),或者业务逻辑(business logic)

3)中间的一层--"控制层"Controller--负责根据用户从"视图层"输入的指令,选取"数据层"中的数据,而后对其进行相应的操做,产生最终结果,从而控制用户界面数据显示和更新Model层对象的状态。    

 

A model stores data that is retrieved according to commands from the controller and displayed in the view; also, a model contains business logic.

Business Logic is comprised of Business Rules(业务规则) and Workflow(工做流程).

A view generates new output to the user based on changes in the model.

A controller can send commands to the model to update the model's state (e.g. editing a document). It can also send commands to its associated view to change the view's presentation of the model (e.g. by scrolling through a document).

 

A typical collaboration of the MVC components:

 

MVC的做用:

一、从开发者的角度来讲:

MVC 模式不只实现了功能模块和显示模块的分离,也就是说, 界面设计人员能够直接参与界面开发,程序员就能够把精力集中放在逻辑层和控制层上。

同时它还提升了应用系统的可维护性、可扩展性、可移植性和组件的可复用性

二、从用户的角度来讲:

用户能够根据本身的需求,选择本身合适的浏览数据的方式。好比说,对于一篇在线文档,用户能够选择以HTML网页的方式阅读,也能够选择以pdf的方式阅读。

 

Android中界面部分也采用了当前比较流行的MVC框架,在Android中:

1) 模型层(Model--数据和业务逻辑--程序员负责

对数据库的操做、对网络等的操做都应该在Model里面处理,对业务计算等操做也是必须放在的该层的。

2) 视图层(View--UI --界面设计人员负责

通常采用XML文件进行界面的描述。使用的时候能够很是方便的引入。固然,如何你对Android了解的比较的多了话,就必定能够想到在Android中也可使用JavaScript+HTML等的方式做为View层,固然这里须要进行JavaJavaScript之间的通讯,幸运的是,Android提供了它们之间很是方便的通讯实现。

3) 控制层(Controller--Activity--让模型层和视图层相分离--程序员负责

Android的控制层的重任一般落在了众多的Acitvity的肩上,这句话也就暗含了不要在Acitivity中写代码,要经过Activity交割Model业务逻辑层处理,这样作的另一个缘由是Android中的Acitivity的响应时间是5s,若是耗时的操做放在这里,程序就很容易被回收掉。

 

AndroidM就是应用程序中二进制的数据,V就是用户界面,CActivity, Activity负责控件的事件绑定以及业务流的程控制。Activity能够有多个界面,只须要将视图的ID传递到setContentView(),就指定了以哪一个视图显示模型层中的数据。

 

参考阅读:

MVC (Model-View-Controller):M是指逻辑模型,V是指视图模型,C则是控制器。

一个逻辑模型能够对于多种视图模型,好比一批统计数据你能够分别用柱状图、饼图来表示。

一种视图模型也能够对于多种逻辑模型。使用MVC的目的是将MV的实现代码分离,从而使同一个程序可使用不一样的表现形式。

C存在的目的则是确保MV的同步,一旦M改变,V应该同步更新,这与《设计模式》中的观察者模式是彻底同样。

 

Android SDK中的数据绑定,也都是采用了与MVC框架相似的方法来显示数据。在控制层上将数据按照视图模型的要求(也就是Android SDK中的Adapter)封装就能够直接在视图模型上显示了,从而实现了数据绑定。好比显示Cursor中全部数据的ListActivity,其视图层就是一个ListView,将数据封装为ListAdapter,并传递给ListView,数据就在ListView中现实。

 

Android UI开发的三种方法: XML; Java代码; XMLJava代码混合

XML: 比较方便、快捷,可是该方法有失灵活;

Java代码: 虽然比较灵活,可是开发过程比较烦琐;

XMLJava代码混合: 习惯上把变化小、行为比较固定的组件放在XML布局文件中,把变化较多、行为控制比较复杂的组件交给Java代码来管理。

 

●详细理解以下代码

package com.wes.helloworld;

 

import android.app.Activity;

import android.os.Bundle;

 

public class mainActivity extends Activity {

    //重写继承与父类Activity的函数onCreate()

    @Override

    public void onCreate(Bundle savedInstanceState) {

    // Android系统用一个Activity来初始化一个程序

    //这个Activity始于一个onCreate()回调方法

    //Bundle型的savedInstanceState保存了当前Activity的状态信息

    //Bundle类是一个key-value对,相似于Map

 

        super.onCreate(savedInstanceState);

        //调用父类的onCreate()函数

        //之因此要写super,是由于上面有个被重写的父类的onCreate()方法

        //这一条语句用来初始化Activity,即生成一个空白的Activity

        setContentView(R.layout.main);

        //这句话的意思是 设置 这一条语句所在的Activity 采用 R.layout下的main布局文件进行布局

        //对于R.layout.mainlayoutR.java里面的public static final class layout

        //mainlayout类里面的public static final int 类数据成员

    }

}

各类图片, raw资源→布局→代码

一个Activity的基本代码布局

    派生一个Activity{

        声明已经在.xml文件中定义的控件;

        声明本Activity自带的数据(能够从项目的res目录中得到);

        声明用于更新UI界面的Handler;

        protected void onCreate(Bundle savedInstanceState){

            super.onCreate(savedInsatanceState);

            setContentView(R.layout.*);

 

            状况1://若是要下面的代码要操做相关数据, 将获取数据的代码写在这儿

            //不一样于第②步中声明的本Activity自带的数据, 这里的数据通常是从其它Activity得到, 或者                是用户本身在本Activity内输入的

            //例如, 要获取其它Activity传来的数据, 可在此获取Inten类对象, 例如:

            Intent intent=getIntent();

            状况2://若是要使用bindService()方法启动Service, 须要在此声明一个ServiceConnection对象

            并将ServiceConnection()这一构造方法里的onServiceDisconnected()onServiceConnected()这两            个回调方法完成

 

            状况1:获取布局中设置的控件(要先在layout里为相关控件赋予R文件里的id, 不然文件源文件                一直出错), 并赋值给第②步中获取的控件;    

            状况2:获取ContentResolver对象

            .(接着, 在获取Uri, 注册ContentObserver,

            并在onCreate()方法以外的区域实现自定义的ContentResolver)

 

            //若是这里获取了一个ListView控件, mListView, 接着建立一个自定义的Adapter类的实例,

             //mAdapter, 而后设置Adapter, 例如mListView.setAdapter(mAdapter);

            //自定义的Adapter类的实如今第⑤步

            //注意, 咱们也多是在某个onCreate()的一个新定义的方法内操做这一步

 

            //若是这里有个initView()方式, 那么事件监听的相关代码、以及对获取并赋值控件的代码在

            onCreate()方法以外的区域里的

            //initView()方法里实现

 

            //最后通常是使用BroadbandcastReceiver4个步骤中的前三步:

            1. 新建一个Intent过滤器

            2. 新建一个BroadcastReceiver

            3. 注册广播接收器

 

            编写与控件相关的监听器内的各类回调函数(onClick())代码;

            //startService(), stopService(), bindService(), unbindService()等服务组件的回调方法在onClick

            //回调函数内实现

        }

        

        //下面都是onCreate()方法以外的区域

        //若是onCreate()onClick()等回调函数的函数体内若是调用了自定义的方法, 可在此具体实现;

        //其它任何具体具体的函数都在此定义

        //使用BroadbandcastReceiver的最后一步: 4. 注销广播接收器

}

//另外注意:

1. ContentResolver可能出如今子线程的某个自定的方法里, 也可能出如今主线程的onClick()等回调方法里;

2. 每启动一个应用进程,都会建立与之对应的ActivityThread类的实例,它是应用程序的UI线程,Android进程启动时会创建消息循环;

3. 子线程通常在onCreate()方法内, 或者是onCreate()里面嵌套的其它方法内建立

4. 通常来讲, Activity类不用具体实现构造方法

一个ContentProvider的基本代码布局:

1. 新建一个类,继承自ContentProvider

2. 重写onCreate(), delete(), getType(), insert(), query(), update()等方法, 可增长自定义的方法

  • 在开发中一般使用常量来定义URI,以下面的CONTENT_URI

public static final String AUTHORITY = "com.alexzhou.provider.NoteProvider";

public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");

一个BroadcastReceiver基本代码布局:

1. 新建一个类,继承自BroadcastReceiver类

2. 重写onReceive()方法; 可增长自定义的方法

一个Service基本代码布局:

1. 新建一个类,继承自Service

2. 重写Service的几个重要方法;可增长自定义的方法

 

 

●回调函数()

A callback function is a function which is:

passed as an argument to another function, and,

is invoked after some kind of event.

 

 

当程序跑起来时,通常状况下,应用程序(application program)时常会 经过API 调用库里所预先备好的函数。可是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。

对于C/C++而言,函数名就是函数的地址,就是函数的指针,不须要在进行取地址操做函数名就是函数的地址,就是函数的指针,不须要在进行取地址操做.

回调函数就是一个经过函数指针调用的函数。

若是你把一个函数指针(地址)做为参数传递给另外一个函数,当这个指针被用来调用其所指向的函数时,咱们就说这个被指向的函数是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

例如:

你到一个商店买东西,恰好你要的东西没有货,因而你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,而后你接到电话后就到店里去取了货。

上面整个案例是一个主程序(Main program

"通知到货"这个商店提供的服务是库函数(Library function

你的电话号码是回调函数(Callback function这个回调函数的函数体就是让"你"去商店取货

你把电话留给店员就叫登记回调函数(咱们还能够登记其它回调函数, 例如微信号,QQ号等)

店里后来有货了叫作触发了回调关联的事件

店员(店员是回调函数的调用者 Caller)给你打电话叫作调用回调函数(不必定要通话)

("你"是事件监听器 Event Listener)到店里去取货叫作响应回调事件

至于我怎么去取货,即我怎么完成电话号码这个回调函数,我能够骑自行车去取,坐出租车去取,或者叫别人去取,这叫重写回调函数

 

店员是调用者他不用在乎被调用者(即回调函数)究竟是什么, 能够是电话号码, 能够是微信号, QQ号等。若是使用电话号码这个回调函数, 咱们就不用总是去问到没到货, 等电话就好了。

能够看到,回调函数一般和应用处于同一抽象层(由于传入什么样的回调函数是在应用级别决定的)。而回调就成了一个高层调用底层,底层再回过头来调用高层的过程。(我认为)这应该是回调最先的应用之处,也是其得名如此的缘由。

回调函数不是由程序员主动在程序中指定函数名来调用, 而是由系统根据某些特定条件的触发(例如点击). Android系统决定调用对应的回调函数, 实行对应的功能.

typedef void (*CALLBACK)(int a,int b)

定义一个函数指针CALLBACK,它返回void类型,有两个参数,分别为,a,b.

callback的几种解释:

A "callback" is any function that is called by another function which takes the first function as a parameter. A lot of the time, a "callback" is a function that is called when something happens. That something can be called an "event" in programmer-speak(程序员说的"事件").

 

A callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time. The invocation may be immediate as in a synchronous callback, or it might happen at a later time as in an asynchronous callback.

//请看下面的伪代码

// The callback method

function meaningOfLife() 

{

log("The meaning of life is: 42");

}

 

 

// A method which accepts a callback method as an argument

// takes a function reference to be executed when printANumber completes

function printANumber(int number, function callbackFunction)

{

print("The number you provided is: " + number);

}

 

// Driver method

function event() //例如在Android, 因为触摸(Touch)而触发的事件会使回调函数被调用

{

printANumber(6, meaningOfLife);    

    //C语言中, A函数作B函数的参数的方法是定义A函数的函数指针

}

 

●为何要用回调函数?

由于能够把调用者与被调用者分开。调用者不关心谁是被调用者,全部它需知道的,只是存在一个具备某种特定原型、某些限制条件(如返回值为int)的被调用函数。

若是想知道回调函数在实际中有什么做用,先假设有这样一种状况,咱们要编写一个库,它提供了某些排序算法的实现,如冒泡排序、快速排序、shell排序、shake排序等等,但为使库更加通用,不想在函数中嵌入排序逻辑,而让使用者来实现相应的逻辑;或者,想让库可用于多种数据类型(intfloatstring),此时,该怎么办呢?可使用函数指针,并进行回调。

回调可用于通知机制,例如,有时要在程序中设置一个计时器,每到必定时间,程序会获得相应的通知,但通知机制的实现者对咱们的程序一无所知。而此时,就需有一个特定原型的函数指针,用这个指针来进行回调,来通知咱们的程序事件已经发生。实际上,SetTimer()API使用了一个回调函数来通知计时器,并且,万一没有提供回调函数,它还会把一个消息发往程序的消息队列。

另外一个使用回调机制的API函数是EnumWindow(),它枚举屏幕上全部的顶层窗口,为每一个窗口调用一个程序提供的函数,并传递窗口的处理程序。若是被调用者返回一个值,就继续进行迭代,不然,退出。EnumWindow()并不关心被调用者在何处,也不关心被调用者用它传递的处理程序作了什么,它只关心返回值,由于基于返回值,它将继续执行或退出。

 

  • 更接近问题本质的答案:

根据面向对象设计的封装性要求,模块间要解耦,模块内要内聚.

 

  • Android, 回调函数实际上就起到了消息循环的做用,由于在SDK中只有经过回调函数来发送各自的处理消息.

 

Callback最本质的特征包括两点:注册和触发

Callback函数是你提供给系统调用的函数。不少状况下,系统某个状况下,定义须要执行某个操做,而操做自己由有用户的程序来提供,这时,就要用到回调函数了。因此,简单地说。回调函数,就是你写一个函数,在系统定义的地点提供给系统调用。

 

C语言回调函数案例

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/* callback.c */

#include<stdio.h>

#include"reg_callback.h"

   

/* callback function definition goes here */

void my_callback(void)

{

printf("inside my_callback\n");

}

   

int main(void)

{

/* initialize function pointer to

my_callback */

callback ptr_my_callback=my_callback;

printf("This is a program demonstrating function callback\n");

/* register our callback function */

register_callback(ptr_my_callback);

printf("back inside main program\n");

return 0;

}

1

2

3

/* reg_callback.h */

typedef void (*callback)(void);

void register_callback(callback ptr_reg_callback);

1

2

3

4

5

6

7

8

9

10

11

/* reg_callback.c */

#include<stdio.h>

#include"reg_callback.h"

   

/* registration goes here */

void register_callback(callback ptr_reg_callback)

{

printf("inside register_callback\n");

/* calling our callback function my_callback */

(*ptr_reg_callback)();

}

This is a program demonstrating function callback

inside register_callback

inside my_callback

back inside main program

 

JAVA中不容许直接操做指针,那它的回调是如何实现的呢?

答案:它是经过接口或者内部类来实现的。

 

JAVA方法回调是功能定义和功能实现分享的一种手段,是一种耦合设计思想。做为一种架构,必须有本身的运行环境,而且提供用户的实现接口。

1. 定义接口 Callback ,包含回调方法 callback()
2.
在一个类Caller 中声明一个Callback类型的引用变量(不是接口对象) mCallback
3.
在程序中赋予 Caller对象的接口成员(mCallback) 一个内部类对象如
interface Callback(){
    callback
(){
    //
函数的具体实现
    }
}

 

Class Caller{

    Callback mCallback;

}

 

这样,在须要的时候,可用Caller对象的mCallback接口成员 调用callback()方法,完成回调。

接口是不能实例化,可是,接口能够声明引用变量。

接口的引用能够指向凡是实现了该接口的类的实例(多态)。

下面的语句并不是直接实例化接口, 由于new Runnable(){}中的花括号里面具体实现了接口的方法:

Runnable task = new Runnable() {

    public void run() {

    

    }

};

 

●监听器

A、什么是监听器?

您须要记住如下几点:

1监听器其实是一个接口,它包含了一个事件触发时系统会去调用的回调函数

二、在实现接口的类中,根据您项目的须要重写这个回调函数

3、派生后的监听器须要绑定到按钮上,就像一个耳机能够发出声音,但您不去戴它,您是听不到它发出的声音的。通常的状况是这个按钮可能须要这个监听器,而另一个按钮须要另一个监听器,每一个监听器各司其职,但功能类似时,也能够多个按钮共同绑定一个监听器。

4、各类控件,都有经常使用的事件,如点击按钮,拖动一个滚动条,切换一个ListView的选项等等,它的绑定监听器的函数命名规则是setOn****Listener

 

B、为控件绑定监听器主要分为如下步骤:

① 获取表明控件的对象

② 定义一个类,实现监听器接口

③ 生成监听器对象

④ 为控件绑定监听器对象

 

Android程序中,设置View点击事件监听共有四种

1)在布局文件中为控件设置onClick属性指定点击方法;

2)建立一个内部类实现OnClickListener接口并重写onClick()方法,

以后须要为控件设置setOnClickListener(Listener listener)

3)主类中实现OnclickListener接口,而后重写onClick()方法;

4)建立匿名内部类,即在为控件设置监听时直接建立一个

OnClickListener实例,不为该实例指定名称。

 

以"用户触碰(touch)"这一动做來說,当组件要处理用户触碰的事件时,组件做为事件源要注册一个事件监听器对象,即:

void setOnClickListener(View.OnClickListener l) //注册单击事件

再如:

void setOnLongClickListener(View.OnLongClickListener l)    //注册长按事件

void setOnKeyListener(View.OnKeyListener l)    //注册键盘事件

void setOnFocusChangeListener(View.OnFocusChangeListener l)    //注册焦点改变事件

void setOnTouchListener(View.OnTouchListener l)        //注册触摸事件

void setOnCreateContextMenuListener(View.OnCreateContextMenuListener l)    //注册上下文菜单事件当这样当"touch"事件发生时,Android框架便回调事件监听器里的回调函數。

 

View.OnClickListener是click listener,即UI控件的Click动做监听器;当用户对View进行Click操做时(即触控上的UI组件),Android框架便会回调这个View.OnClickListener的回调函數,即onClick()

  • 另一种UI事件的机制为事件处理器(event handler),event handler与event listener是不同的处理机制,下文会讲到。

 

●View与ViewGroup触摸事件传递机制

触摸事件有:ACTION_DOWN, ACTION_MOVE, ACTION_UP 。一个简单的触摸动做触发了一系列Touch事件,如:

 

1ACTION_DOWN -> ACTION_MOVE->..-> ACTION_MOVE-> ACTION_UP

 

2ACTION_DOWN -> ACTION_UP

 

TouchEvent发生时,首先ActivityTouchEvent传递给最顶层的ViewTouchEvent最早到达最顶层ViewdispatchTouchEvent,而后由dispatchTouchEvent方法进行分发,若是dispatchTouchEvent返回TRUE,则交给这个ViewonTouchEvent处理;若是dispatchTouchEvent返回false,则交给这个ViewOninterceptTouchEvent方法来决定是否要拦截这个事件,若是OninterceptTouchEvent返回true,也就拦截了,则交给它的onTouchEvent来处理;若是OninterceptTouchEvent返回false,那就传递给子View,由子ViewdispatchTouchEvent再来开始这个事件的分发,若是事件传递到某一层ViewonTouchEvent了,这个方法返回false,那么这个事件从这个View往上传递,都是onTouchEvent来接收,而若是传递到onTouchEvent返回是false,这个事件"消失",并且接收不到下一次事件。

 

其分发和传递的过程以下:

 

 

 

●There are following three concepts related to Android Event Management

(Android事件管理的3种机制)

  • Event Listeners (事件监听器)− An event listener is an interface in the View class that contains a single callback method. These methods will be called by the Android framework when the View to which the listener has been registered is triggered by user interaction with the item in the UI.
  • Event Listeners Registration (事件监听器注册)− Event Registration is the process by which an Event Handler gets registered with an Event Listener so that the handler is called when the Event Listener fires the event.
  • Event Handlers (事件处理器)− When an event happens and we have registered an event listener for the event, the event listener calls the Event Handlers, which is the method that actually handles the event.

 

(不用掌握, 掌握书上的方法便可)为控件绑定监听器主要分为如下步骤:

1、获取表明控件的对象

2、生成监听器对象

3、为控件绑定监听器对象

4、定义一个类,实现监听器接口

protected void onCreate(Bundle savedInstanceState) { 

 super.onCreate(savedInstanceState); 

 setContentView(R.layout.activity_main); 

 textView =(TextView)findViewById(R.id.textView); 

 textView.setText("set text success"); 

 //1.获取表明控件的对象 

 button =(Button)findViewById(R.id.button); 

 //2.生成监听器对象 

 ButtonListener buttonListener =new ButtonListener(); 

 //3.为控件绑定监听器对象 

 button.setOnClickListener(buttonListener); 

 } 

 

 //4.定义监听类,实现监听器接口 

 class ButtonListener implements OnClickListener{ 

 

 @Override 

 public void onClick(View arg0) { 

 // TODO Auto-generated method stub 

 textView.setText("onclick ok"); 

 } 

 

}

 

●接口与内部匿名类

接口不能实例化,可是接口类型的引用变量能够引用一个实现了接口的类的对象.

 

接口 对象=new 接口的实现类()

 

//这里可使用匿名内部类实现接口

(new 接口(){

//实现方法

});

//其中, FilenameFilter是一个接口, 上面实现的是FilenameFilter接口的匿名内部类, 并非FileNameFilter的实例化.

 

该代码等效于

class A implements FileNameFilter{    //这里给上面的匿名内部类起了个名字A

    public void accept(File f,String s)

    {

        //实现了accept()这个回调函数

    }

}

 

dir.list(new A())

 

●问题

设有下面两个赋值语句:

a = Integer.parseInt("123");

b = Integer.valueOf("123").intValue();

下述说法正确的是( d )。

A、a是整数类型变量,b是整数类对象。

B、a是整数类对象,b是整数类型变量。

C、ab都是整数类对象而且值相等。

D、ab都是整数类型变量而且值相等。

注意, 若是b = Integer.valueOf("123").intValue();中没有intValue(), 那么a是基本数据类型int, bInteger包装类类型.

 

Integer.valueOf() 和 String.valueOf()

既有Integer.valueOf()函数, 也有String.valueOf()函数

 

●为何定义在类头上的控件变量须要是final

由于在安卓中 不少监听器之内部类的形式去访问定义在类头上的控件(如一个Button)变量,这就造成了内部类与外部类变量的访问;注意,这里的控件变量须要加final关键字 。

由于若是不加final,那个变量的生命将在方法结束时结束,但那个匿名内部类的对象仍然存在,它就须要访问一个已经不存在了的变量。加了final后生命周期延长,就不会有这个问题了。

 

GridViewListView

 

MainActivity.this 和直接用 this有区别吗?

MainActivity.this表示的就是MainActivity这个类对象自己,这种写法通常用在内部类里,由于在外部类中直接能够用关键字this表示本类,而内部类中直接写this的话表示的是内部类自己,想表示外部类的话就得加上外部类的类名.this

※ 对于包含内部类的类来讲,它就是其内部类的外部类。

 

具体来讲, 某个控件 setOnClickListener(); 在括号里面new 一个OnClickListener (这就建立了上面说的内部类),而后在onClick方法里面处理的时候必需要用MainActivity.this 而不能用this

 

※ 下面有关风格和主题的讲述比较杂乱

Android应用开发中的风格和主题(style,themes)

风格和主题都是资源, 存放在res/values 文件夹下,你能够用android提供的一些默认的风格和主题资源,你也能够自定义你本身的主题和风格资源。

如何新建自定义的风格和主题:

1. 在res/values 目录下新建一个名叫style.xml的文件。增长一个<resources>根节点。

2. 对每个风格和主题,给<style>element增长一个全局惟一的名字,也能够选择增长一个父类属性。在后边咱们能够用这个名字来应用风格,而父类属性标识了当前风格是继承于哪一个风格。

3. 在<style>元素内部,申明一个或者多个<item>,每个<item>定义了一个名字属性,而且在元素内部定义了这个风格的值。

4. 你能够应用在其余XML定义的资源。

 

Android提供的默认的主题样式

Android的Style设计就是提高用户体验的关键之一。Android上的Style分为了两个方面:

1,Theme(主题)是针对窗体级别的(Activity),用来改变窗体样式;

2,Style(风格)是针对窗体元素级别的,改变指定控件或者Layout的样式。

 

Android系统的themes.xmlstyle.xml(位于系统源代码frameworks\base\core\res\res\values\)包含了不少系统定义好的style,建议在里面挑个合适的,而后再继承修改。

好比说android:theme="@android:style/Theme.Dialog"可让你的Activity变成一个窗口风格,

android:theme="@android:style/Theme.Light"则让你的整个Activity具备白色的背景,而不是黑色那么沉闷。

详见:http://www.cnblogs.com/SharkBin/p/3596525.html

 

具体使用方法很简单, Androidmanifest.xml文件中对你的Activity节点上加入些代码,以下图所示:

 

●△引用主题属性:

另一种资源值容许你引用当前主题中的属性的值。这个属性值只能在样式资源和XML属性中使用;它容许你经过将它们改变为当前主题提供的标准变化来改变UI元素的外观,而不是提供具体的值。

 

android:textColor="?android:textDisabledColor"

 

当你使用这个标记时,你就提供了属性资源的名称,它将会在主题中被查找--由于资源工具知道须要的属性资源,因此你不须要显示声明这个类型(若是声明,其形式就是?android:attr/android:textDisabledColor)。除了使用这个资源的标识符来查询主题中的值代替原始的资源,其命名语法和"@"形式一致:?[namespace:]type/name,这里类型可选。

 

The question mark means it's a reference to a resource value in the currently applied theme.(问号的意思是它是当前被应用的主题中的资源值的引用)

 

●适配器 Adapter

Android适配器是数据和视图之间的桥梁,能够看做是将界面和数据绑定的工具,以便于数据在视图上显示。咱们经常使用的适配器一共有三个:ArrayAdapterSimpleAdapterSimpleCursorAdapter 这三个,他们都是继承于BaseAdapter

 

 

※ 现实中的适配器有不少, 如显卡(Video cardGraphics card/显示适配器。

 

ArrayAdapter的第二个参数还有以下几个参数能够设置

  • 1)android.R.layout.simple_list_item_1:由文字组成的列表项。
  • 2)android.R.layout.simple_list_item_2:由稍大的文字组成的列表项。
  • 3)android.R.layout.simple_list_item_checked:由CheckBox组成的列表项。
  • 4)android.R.layout.simple_list_item_multiple_choice:有多选框组成的列表项
  • 5)android.R.layout.simple_list_item_single_choice:有单选框组成的列表项。

 

●Android系统中提供了两种图片浏览方式

图片浏览器是智能设备中使用很是普遍的组件,Android系统中提供了两种图片浏览方式,

① 最为普通的ImageView浏览,

② 使用GridView实现网格式的图片浏览,

 

 

 

 

 

 

 

第6章 使用程序资源

●资源(

Resources

本质上, 资源是一种共享、反复利用元素、属性的机制(mechanism)

 

●资源的图示

 

资源类型

文件夹名称

文件名

字符串

/res/values/

strings.xml

字符串数组

/res/values/

arrays.xml

颜色

/res/values/

colors.xml

样式

/res/values/

styles.xml

主题

/res/values/

themes.xml

图片

/res/drawable/

*.png*.jpg*.gif

布局

/res/layout/

mylayout.xml

动画

/res/anim/

*_anim.xml

菜单

/res/menu/

menu1.xml

原始文件

/res/raw/

audio.mp3video.mp4

XML文件

/res/xml/

自定义的xml文件

 

 

"@+id/""@type/name""@+android:id/title "

1、引用自定义资源

1.引用自定义资源。格式:@[package:]class/name

例如:

android:text="@string/hello"

android:layout_toRightOf="@id/btnLogin"

注:idR.java里也是一种class

 

@表示对资源的引用,package是包名,若是在相同的包内,则包名能够省略。

"@string/hello"的意思是引用在strings.xml里面定义的字符串,属性(引用变量)为hello,值(引用变量指向的对象)为Hello World

 

2.引用系统资源。格式:@android:type/name

android:textColor="@android:color/opaque_red"

 

2、 新建一个资源id

<EditText

android:id="@+id/edit"

.../>

edit这个id表明EditText这个UI控件,系统会在R.java文件中自动生成int edit = 十六进制的value

咱们能够在Java代码中使用edit这个id,例如:

EditText et=(EditText)findViewById(R.id.edit);

//id是R.java文件里的,即public static final class idedit是这个类的成员。

加上android:表示引用android.R.id里面定义的id资源,若是android.R.id里面确实有title这个id资源,就直接使用它,若是没有的话就在当前应用的R.id中产生一个title标识.

 

※ 可是如今我发现apps/settings/res/layout/preferenc_progress.xml中有个"@+android:id/title",怎么理解它?

"@+android:id/title"表示在系统的R.java文件中自定义一个名为titleid

 

再如:

系统布局文件是:android.R.layout.xxx;

而用户自定义布局文件是:R.layout.xxx;

 

id是控件的一个基本属性,这并不表明每一个控件的id都不同,其实控件的id属性是能够相同的

全部的控件被加载到内存之后就会造成一个控件树形结构,当查找控件的时候,只返回第一个id匹配的控件,因此若是一个页面中有相同id的控件,好比ListViewitem,当查找控件的时候要从它最邻近的一个父节点开始查找,这样才会命中.

 

res/rawassets

res/raw和assets的相同点:

二者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。


res/raw和assets的不一样点:
1.
 res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID

即R.类名.数据成员名

//类名如:attr, color, drawable, id, layout, raw, string

//(有的类名采用的是文件夹名,如res/layout/, 有的类名采用的是.xml文件里面的标签名,如res/values/.strings.xml文件里的string标签名)

assets文件夹下的文件不会被映射到R.java中,访问的时候须要AssetManager类。
2.res/raw
不能够有目录结构,而assets则能够有目录结构,也就是assets目录下能够再创建文件夹

 

3.读取文件资源的方式

①读取res/raw下的文件资源,经过如下方式获取输入流来进行写操做

  1. InputStream is = getResources().openRawResource(R.类名.数据成员名);

②读取assets下的文件资源,经过如下方式获取输入流来进行写操做

  1. AssetManager am = null;
  2. am = getAssets();
  3. InputStream is = am.open("filename");

 

补充一下:在未知目录下有一些文件,那么该怎么获取这些文件的名称并把文件拷贝到目标目录中呢?(用于内置文件但不知道文件名称,须要筛选出想要的文件而后拷贝到目标目录中,推荐内置在assets文件夹中)
1.res/raw
目录:
经过反射的方式获得R.java
里面raw内部类里面全部的资源ID的名称,而后经过名称获取资源ID的值来读取咱们想要的文件。(这个方法我没试过,有用过的同窗麻烦发一段代码看看)。
2.assets
目录:
getAssets().list("");
来获取assets目录下全部文件夹和文件的名称,再经过这些名称再读取咱们想要的文件。

 

raw目录先放置一个MP3文件

 

R.java文件与res文件的对应关系:

除了string.xml, res/value/文件下可能包含的xml文件:

arrays.xml for resource arrays, and accessed from the R.array class.

integers.xml for resource integers, and accessed from the R.integer class.

bools.xml for resource boolean, and accessed from the R.bool class.

colors.xml for color values, and accessed from the R.color class.

dimens.xml for dimension values, and accessed from the R.dimen class.

strings.xml for string values, and accessed from the R.string class.

styles.xml for styles, and accessed from the R.style class.

没有保存,系统不会知道你已经添加了新控件,新资源,

所以,在每次添加新资源或者更改内容后,ctrl+s保存一下,R.java才会自动生成相关代码

 

Android中度量单位含义

dip: device independent pixels(设备独立像素). 不一样设备有不一样的显示效果,这个和设备硬件有关,通常咱们为了支持WVGAHVGAQVGA 推荐使用这个,不依赖像素。

dp: 和dip是同样的

px: pixels(像素). 不一样设备显示效果相同,通常咱们HVGA表明320x480像素,这个用的比较多。

pt: point,是一个标准的长度单位,1pt1/72英寸,用于印刷业,很是简单易用;

sp: scaled pixels(放大像素). 主要用于字体显示best for textsize

in(英寸):长度单位。

mm(毫米):长度单位。

 

分辨率能够从显示分辨率与图像分辨率两个方向来分类。

显示分辨率(屏幕分辨率)是屏幕图像的精密度,是指显示器所能显示的像素有多少。

图像分辨率则是单位英寸中所包含的像素点数,其定义更趋近于分辨率自己的定义。

单位

标记

说明

毫米

mm(milli meters)

实际的物理测量单位,在屏幕上以毫米为单位显示

英寸

in(inch)

实际的物理测量单位,在屏幕上以英寸为单位显示,1英寸约为2.54厘米

像素

px(pixels)

像素是构成数码影像的基本单元,一般以像素每英寸PPI(pixels per inch)为单位来表示影像分辨率的大小。

pt(point)

实际的物理测量单位,1点等于1/72英寸,经常使用于印刷业

密度独立像素

dp(density independed pixels) 

虚拟像素,也就是说每一个设备都有其独立的像素。

1dp=1*像素密度/160=实际像素数

例如:一个手机的像素密度为230dpi(严格来讲是ppi),那么1dp=1sp=1*320/160=2px.

刻度独立像素

sp(scale independed pixels)

虚拟像素,实际长度与dp相同,只是常被用于字体的显示,Android字体大小默认单位为sp

 

ppiPixel Per Inch每英寸像素数):指每英寸屏幕的像素密度

 

dpi(Dot Per Inch,每英寸点数):指每英打印的点密度

 

若是你以600dpi打印一张150ppi的照片,那么每一个像素包含16个点。(600 dots/150 "pixels" = 4 rows of 4 dots per "pixel").

Android而言,dpi等价于ppidpi最先是用于印刷行业,跟PPI仍是有本质不一样的,Android应该是误用了DPI这个概念。

 

屏幕尺寸是手机屏幕对角线的长度

 

例如:华为荣耀7的配置以下:

屏幕像素密度=(√1920^2+1080^2)÷5.2424ppi

 

一个像素的尺寸是可变的,屏幕密度有关:

若是像素密度为72ppi,那么每英寸里有72个像素,每像素就是1/72英寸;

若是屏幕精度为300ppi,每像素就是1/300英寸了;

在一样尺寸下,例如都是5厘米,300ppi精度的更清晰

 

分辨率能够从显示分辨率与图像分辨率两个方向来分类。

显示分辨率(屏幕分辨率)是屏幕图像的精密度,是指显示器所能显示的像素有多少。

图像分辨率则是单位英寸中所包含的像素点数,其定义更趋近于分辨率自己的定义。

 

精度/分辨率(resolution)是水平像素数*垂直像素数,常见的Android手机分辨率以下:

VGA(Video Graphics Array,即视频图形阵列):480*640,标准的视频接口分辨率

QVGA(Quarterly~):240*320,只有VGA的四分之一

HVGA(Half~):480*320,只有VGA的二分之一,使用的比较少了,开发使用

WVGA(Wide~):480*800

FWVGA(Full Wide~):480*854

 

※ 像素是Android屏幕显示的默认单位,

 

 

●为何Androidres文件夹要分别存放mdpildpihdpi文件?

在以前的版本中,只有一个drawable

而从2.1版本之后,res中开始有drawable-mdpidrawable-ldpidrawable-hdpi三个,

这三个主要是为了支持多分辨率。

drawable- hdpi、drawable- mdpidrawable-ldpi的区别:

(1)drawable-hdpi里面存放高分辨率的图片,WVGA (480x800),FWVGA (480x854)分辨率的机型;

(2)drawable-mdpi里面存放中等分辨率的图片,HVGA (320x480) 分辨率的机型;

(3)drawable-ldpi里面存放低分辨率的图片,QVGA (240x320) 分辨率的机型;

系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。

 

 

具体来讲:

ldpi 120dpi如下

mdpi 120dpi ~ 160dpi

hdpi 160dpi ~ 240dpi

xhdpi 240dpi ~ 320dpi

xxhdpi 320dpi ~ 480dpi

xxxhdpi 480dpi ~ 640dpi

 

不一样分辨率的图片可同名, 例如:

Android系统定义了四种像素密度:低(120dpi)、中(160dpi)、高(240dpi)和超高(320dpi),它们对应的dppx的系数分别为0.7511.52,这个系数乘以dp长度就是像素数。

例如界面上有一个长度为"80dp"的图片,那么它在240dpi的手机上实际显示为80x1.5=120px,在320dpi的手机上实际显示为80x2=160px

若是你拿这两部手机放在一块儿对比,会发现这个图片的物理尺寸"差很少",这就是使用dp做为单位的效果,见下图:

 

●对于不一样像素密度的图片,Android系统给定了其对应比例和倍数以下

分类目录

ldpi

mdpi

hdpi

xhdpi

xxhdpi

xxxhdpi

密度(dpi)

~160

~240

~320

~480

~640

  

图片比例

1.5

2

3

4

6

8

倍数

0.75x

1x

1.5x

2x

3x

4x

 

 

 

●不一样分辨率手机的比例调查(201211月数据)

 

ldpi

mdpi

hdpi

xhdpi

   

Pequeña

1,7%

 

1%

 

xxhdpi

xxxhdpi

Normal

0,4%

11%

50,1%

25,1%

~640

 

Grande

0,1%

2,4%

 

3,6%

6

8

Extra grande

 

4,6%

   

3x

4x

 

 

 

Java中方法调用方法

例如: f.getToolkit().getScreenSize()

f.getToolkit()获得一个Toolkit对象

f.getToolkit().getScreenSize() 是Toolkit对象调用getScreenSize(),这个方法是有返回值的。

 

 

 

 

 

 

 

第7章 设计界面布局

The ViewGroup is the base class for layouts and views containers.

咱们常常编写Layout文件,经过Layout文件咱们能够看到全部的View在界面上均占有一矩形区域,而咱们能够把这种矩形区域(View)大体分为两类,即:

① 单一的矩形区域(View),

② 包含有小矩形区域的大矩形区域(ViewGroup)

这种大小矩形相套的格局自顶向下造成一种树形结构,咱们能够将其称为View.

下图是简略的View树:

 

 

The standard Layouts (标准布局类):

Layout

Description

LinearLayout

(Horizontal)

(Vertical)

LinearLayout is a view group that aligns all children in a single direction, vertically or horizontally.

RelativeLayout

RelativeLayout is a view group that displays child views in relative positions.

相对布局一般有两种形式,一种是相对于容器而言的,一种是相对于控件而言的。

TableLayout

TableLayout is a view that groups views into rows and columns.

GridLayout

GridLayout uses a grid of infinitely-thin lines to separate its drawing area into: rows, columns, and cells. It supports both row and column spanning, which together allow a widget to occupy a rectangular range of cells that are next to each other.

FrameLayout

The FrameLayout is a placeholder on screen that you can use to display a single view.

AbsoluteLayout

AbsoluteLayout enables you to specify the exact location of its children. Arrange the children views according coordinates x, y.

 

relative layout

 

TableLayout GridLayout

有了TableLayout又搞个GridLayout的缘由以下:

1. TableLayout不能同时向水平和垂直方向作控件的对齐

TableLayout继承了LinearLayout,所以只能向一个方向作控件的对齐。

 

2.不能跨行跨列

由于TableLayout,不明确指定包含多少行,多少列,而是经过向TableRow里面添加其余组件,每添加一个组件该表格就增长一列。

若是向TableLayout里面添加组件,那么该组件就直接占用一行。因此这种方式形成控件不能跨行跨列。

GridLayout,则用columnCount设置列数后,增长的控件在超过列数后自动换行进行排列。

 

The standard Views Containers(视图容器):

A container is a view used to contain other views.

Container

 

RadioGroup

ListView

GridView

ExpandableListView

ScrollView

HorizontalScrollView

SearchView

TabHost

VideoView

DialerFilter

 

●注意事项

因为GridLayoutAndroid4.0以后有的新功能,若是要在项目中使用这种布局,须要把SDK的最低版本指定为Android4.0API14—)以上。

AndroidManifest.xml中,配置SDK兼容的最低版本和最高版本示例代码以下:

<uses-sdk

android:minSdkVersion="14"

android:targetSdkVersion="17" />

绝对布局多用于游戏开发中,因为多分辨率兼容麻烦,绝对布局在Android1.5后被Google弃用,所以应用开发通常状况下不推荐使用绝对布局。

 

setContentView( )方法

setContentView(R.layout.main)在Android里面,这句话是什么意思?

R.layout.main是个布局文件即控件都是如何摆放如何显示的,setContentView就是设置一个Activity的显示界面,这句话的意思是 设置 这一条语句所在的Activity 采用 R.layout下的main布局文件进行布局

 

LayoutParams(布局参数类)

LayoutParams类的 继承关系 为:

Android.View.ViewGroup.LayoutParams.

LayoutParams类至关于一个Layout的信息包,它封装了Layout的位置、高、宽等信息。假设在屏幕上一块区域是由一个Layout占领的,若是将一个View添加到一个Layout中,最好告诉Layout用户指望的布局方式,也就是将一个承认的layoutParams传递进去。

能够这样去形容LayoutParams,在象棋的棋盘上,每一个棋子都占据一个位置,也就是每一个棋子都有一个位置的信息,如这个棋子在44列,这里的"44列"就是棋子的LayoutParams

//建立一个线性布局

    private LinearLayout mLayout;

    mLayout = (LinearLayout) findViewById(R.id.layout);

//如今我要往mLayout里边添加一个TextView

//你可能会想直接在布局文件里边配置不就O 了 那是 可是这里为了说明问题咱们用代码实现

    TextView textView = new TextView(Activity01.this);

    textView.setText("Text View " );

//这里请不要困惑这里是设置 这个textView的布局 FILL_PARENT WRAP_CONTENT 和在xml文件里边设置是同样的如

/**<TextView

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:text="Text View"/>*/

//xml里边怎么配置高宽你们都会的。

//第一个参数为宽的设置,第二个参数为高的设置。

    LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(

    LinearLayout.LayoutParams.FILL_PARENT,

    LinearLayout.LayoutParams.WRAP_CONTENT

    );

//调用addView()方法增长一个TextView到线性布局中

    mLayout.addView(textView, p);

//比较简单的一个例子

 

●书中169面的main.xml文件编写完成后, 须要在源文件中进行以下设置:

 

FrameLayout(框架布局)

框架布局是最简单的布局形式。全部添加到这个布局中的视图都以层叠的方式显示。第一个添加的控件被放在最底层,最后一个添加到框架布局中的视图显示在最顶层,上一层的控件会覆盖下一层的控件。这种显示方式有些相似于堆栈。

 

通常不多使用,因此只是做为一个知识点列出来。借鉴于前人的样例

 

TabActivity实现多页显示效果

http://158067568.iteye.com/blog/941338

 

●探讨一下TabActivity

作个假定先: 好比咱们最外面的ActivityMainActivity, 第一个tabFirstActivty, 第二个tabSecondActivity .

相信你们都用过TabActivity, 它是一个特殊的Activity,它特殊的地方在哪里?有如下几点为证:

a. 它看起来违反了Activity的单一窗口的原则。由于它能够同时加载几个Activity 当用户点击它上面的tab时,就会跳到相应的Activity上面去。

b. 用户首先进去FirstActivity,而后进去SecondActivity,再点击返回键的时候。它返回的界面不是FirstActivity,而是退出咱们的应用程序。

c. 当用户在FirstActivity按返回键的时候,若是MainActivityFirstActivity经过重写onKeyDown()方法,那么收到事件回调的只有FirstActivity

 

(二)TabActivity存在必要性以及google当时的困扰

a. 首先咱们要明白一点,android系统是单窗口系统,不像windows是多窗口的(好比在windows系统上,咱们能够一边聊QQ,一边斗地主等等)。也就是说,在一个时刻,android里面只有一个activity能够显示给用户。这样就大大下降了操做系统设计的复杂性(包括事件派发等等).

b. 可是像TabActivity那种效果又很是必要,由于用户体验也比较好。因此我以为当时google开发人员确定很纠结。。 因而,一个畸形的想法产生了,就是在单窗口系统下加载多个activity,它就是TabActivity

 

TabActivity已通过时,Android4.0 之后直接使用fragment 便可,而最新版的安卓sdk ,一般已经将兼容包配置好了,不过,须要注意的是Eelipse 提醒的时候import 依然会提示老版本的 fragment v4Fragment(version 4 fragment)

一部当心,会选到第一个,程序运行不出来

 

TabActivity图示

- TabActivity - This is a specialized view that acts as a container for a TabHost (described below).

- TabHost - This is a container for the tabbed UI, hosting two children: a list of tab labels (选项卡标签) (i.e., tab widget) and a FrameLayout displaying the contents of the Activities or Views - When a tab (选项卡) is selected, it displays either an Activity or a View in the FrameLayout .

 

TabWidget - This control displays a list of tab labels, one for each tab in the TabHost . Each tab in a TabHost is represented by a TabHost.TabSpec object. This object contains the meta-data for each tab. When the user selects a tab, the TabHost responds to the selection by displaying the appropriate tab.

FrameLayout - A tabbed UI must have a FrameLayout contained inside of a TabHost . It is used to display the contents for the tab.

 

TabHost is an old API that has been deprecated by Google. Developers are encouraged to build tabbed applications using the ActionBar.

 

TabSpec(在代码中实现, 不在xml文件中实现, Spec指的是Specify)

表明了选项卡界面, 添加一个TabSpec便可添加到TabHost;

-- 建立选项卡 : newTabSpec(String tag), 建立一个选项卡;

-- 添加选项卡 : addTab(tabSpec);

 

※ 案例

远程音乐列表和本地音乐列表为两个不一样的按钮,在TabActivity中它们同属于一个TabWidget,

而下面的两个列表都是在各自的Activity中设置,而后在将每个Activity添加到TabActivityFrameLayout中。

也就是说在TabActivity的布局文件中必须包含TabWidgetFrameLayout两种控件。

这里值得一提的是,必须为TabActivity的布局文件的根节点设置为:TabHost

<?xml version="1.0" encoding="utf-8" ?>

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@android:id/tabhost"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<LinearLayout

     android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:padding="5dp">

    <TabWidget android:id="@android:id/tabs"

    android:layout_width="fill_parent"

android:layout_height="wrap_content" />

    <FrameLayout

android:id="@android:id/tabcontent"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:padding="5dp" />

</LinearLayout>

</TabHost>

 

参考阅读:

咱们在ActionBar中进行Fragment之间的切换:

http://blog.csdn.net/xiaodongvtion/article/details/8775142

 

TabActivity & ActivityGroup & Fragment 比较

Android里面Tab分页,经常使用的方法有两种:

一、采用TabActivityTabHost的结合

二、采用ActivityGroupGridView的结合。

 

※ 若是Tab选项过多,能够采用Gallery+ActivityGroup结合的实现方式。

 

(2012年的说法)ActivityGroup在实际的开发中是十分常见的,在我使用过的Android应用中,十个应用里面有九个应用的主界面都是使用ActivityGroup的。

提及ActivityGroup,在国内好像直接使用它开发的并很少,基本都是使用TabActivity,它是ActivityGroup惟一的一个子类。

Android端新浪微博的主界面就是用TabActivity来实现的,还有其它的一些应用也几乎都用TabActivity来实现。在我眼里,TabActivityGoogle提供的一个很是失败的API(至少我如今这么认为,下文我会说它失败在哪里),但中国几乎全部的应用都使用TabActivity,我不由在思考这是巧合仍是复制粘贴的产物。

每一个选项卡均可以对应多个子Activity,这个是普通TabActivity作不到的。

TabActivity

ActivityGroup

Fragment

 

LayoutInflater

LayoutInflater这个类的做用相似于findViewById()

不一样点是

LayoutInflater是用来找res/layout/下的xml布局文件,而且实例化;

findViewById()是找xml布局文件下的具体widget控件(如ButtonTextView)

LayoutInflater 是一个抽象类,在文档中以下声明:

public abstract class LayoutInflater extends Object

 

LayoutInflater的实例的具体做用:

一、对于一个没有被载入或者想要动态载入的界面,都须要使用LayoutInflater.inflate()来载入;

二、对于一个已经载入的界面,就可使用Activiyt.findViewById()方法来得到其中的界面元素。

得到 LayoutInflater 实例的三种方式:

LayoutInflater inflater = getLayoutInflater(); //调用ActivitygetLayoutInflater()

 

LayoutInflater localinflater =

(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

 

LayoutInflater inflater = LayoutInflater.from(context);

1 LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE); 

2 View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test)); 

3  

4 //EditText editText = (EditText)findViewById(R.id.content);// error  

5  

6 EditText editText = (EditText)view.findViewById(R.id.content);

 

ListActivity

一个含有一个ListView组件的Activity类。

也就是说,若是咱们直接在一个普通的Activity中本身加一个ListView也是彻底能够取代这个ListActivity的,只是它更方便而已。

package com.teleca;

 

 

Create Table like this put some space before INTEGER ....

 

"CREATE TABLE "+TABLE_NAME+" ("+KEY_ID+" INTEGER PRIMARY KEY AUTOINCREMENT)";

Sqlite中,一个自增加字段定义为INTEGER PRIMARY KEY AUTOINCREMENT或者INTEGER PRIMARY KEY时 ,那么在插入一个新数据时,只须要将这个字段的值指定为NULL,便可由引擎自动设定其值。

相关文章
相关标签/搜索