使用Android Studio進行安卓開發教程

本教程介紹如何建立Android應用程序。它基於Android5.0(Lollipop)介紹Android Studio的用法。html


安卓介紹

Android是基於Linux內核的操做系統。負責開發Android系統的項目被爲Android Open Source Project (AOSP) ,由谷歌領導。java

Android系統支持後臺處理,提供了豐富的用戶界面庫,使用的OpenGL標準支持2-D和3-D圖形,並容許訪問文件系統以及嵌入式SQLite數據庫。python

Android應用包含可見和不可見組件,並可重用其餘應用程序的組件。android

 

在Android中重用其餘應用組件即任務的(Task),好比調用圖片管理應用。事件流以下:c++

Defining an Android tasks

安卓平臺組件以下:程序員

Android software layers

  •     應用 - Android開源項目包含幾個默認的應用程序,如瀏覽器,相機,圖庫,音樂,電話等。web

  •     應用程序框架 - Android應用與Android系統高層交互API。數據庫

  •     庫和運行時 - 應用程序框架和Dalvik運行時的經常使用功能的庫(如:圖形渲染,數據存儲,網頁瀏覽等)和運行Android應用的核心Java庫。編程

  •     Linux內核 - 底層硬件的通訊層。數組

谷歌提供的Google Play是程序員能夠提供他們的Android應用給用戶的市場。客戶使用谷歌Play可購買和安裝應用程序。

Google Play還提供了更新的服務。若是程序員上傳本身的應用程序的新版本時,該服務將通知現有用戶有更新可用並容許他們來安裝更新。

Google Play提供服務和庫訪問,好比谷歌地圖和Android設備之間同步的服務。這些服務對舊版安卓也可用,不依賴安卓版本

安卓開發工具

Android Software Development Kit (Android SDK): 包含來建立,編譯和打包Android應用的工具。這些工具大部分基於命令行。主要基於Java編程語言,也涉及Python和c++等。

Android debug bridge (adb):能鏈接到虛擬或真實的Android設備以管理設備或調試應用。

Gradle和Android Gradle 插件:Android的工具使用Gradle做爲構建系統。 Android團隊提供了Gradle插件用於構建Android應用,Android項目的根目錄的build.gradle文件是輸入。好比:


// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.4.0'

        // NOTE: Do not place your application dependencies here; they belong        
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

不一樣版本的插件參見https://jcenter.bintray.com/com/android/tools/build/gradle/。

 Android Studio基於IntelliJ IDE。Android工具爲Android特定文件提供了專門的編輯器。多數Android的配置文件都基於XML。編輯器能夠在XML表示和用於輸入數據的結構化UI之間進行切換。


安卓5.0的運行時爲Android RunTime (ART)ART使用提早編譯。應用程序的部署時代碼翻譯成機器代碼。編譯代碼大30%的,但執行更快,只編譯一次,也會更省電。dex2oat工具編譯.dex文件爲可執行和連接格式(ELF文件Executable and Linkable Format)。該文件包含DEX代碼,編譯的本地代碼和元數據。保持.dex代碼容許現有的工具仍然能夠工做。ART的垃圾收集進行了優化,減小了應用凍結時間。

Android應用主要用Java編程語言。開發人員建立了Android特定的配置文件,並用Java寫應用邏輯。

Android的工具將這些應用程序文件打包成爲Android應用。在IDE部署時,整個Android應用程序被編譯,打包,部署並啓動。Java源文件是由Java編譯器轉換成Java類文件。
Android SDK的dx工具把Java類文件轉換到.dex(Dalvik的可執行文件)文件同時去除冗餘內容。所以,這些.dex文件的遠小於相應的類文件。
.dex文件和Android項目的資源文件,例如圖像和XML文件的,打包成一個apk文件(Android Package)文件。aapt (Android Asset Packaging Tool)完成此步驟。 
而後adb能夠部署.apk到Android設備。


安裝Android Studio

硬件建議,在2.6 GHz CPU,8 GB的內存。 SSD硬盤更佳。

Android SDK的是32位的,所以64位的Linux系統須要安裝包ia32-libs庫。好比Ubuntu:。

apt-get install ia32-libs

在Ubuntu 13.04還必須安裝OpenGL支持。

# install OpenGL support
# sudo apt-get install libgl1-mesa-dev


下載http://developer.android.com/sdk/installing/studio.html

Windows安裝很簡單,只需啓動你下載的.exe文件。在Max OSX拖放Android Studio到應用程序文件夾。
在Linux上解壓縮下載的ZIP文件到一個合適的位置,在android-studio/bin/中執行studio.sh。


Android SDK Manager 

Tools → Android → SDK Manager   或下面的快捷方式:           

Android SDK manager in Android Studio

支持庫能夠在較低的Android版本提供更高的Android版本的功能。

在Android SDK管理器中選擇Extras並安裝Android支持庫。 Android的支持庫爲Eclipse ADT工具使用。

Android目前有幾個版本的庫中,V4,V7和V13版本對應安卓的各個API。高版本支持庫的Android設備也須要較低的版本一塊兒使用。例如,支持庫V7須要V4庫。

 

在谷歌開發團隊着力於Android Studio的發展,因此這是目前Android應用程序最好的發展環境。目前的ADT工具使用特殊的Eclipse構建系統,而不是新的Gradle構建系統,構建時可能產生不一致,另外也不支持AAR文件。


虛擬機與真機測試

Android的工具包含Android設備模擬器(emulator)。該模擬器可用於運行Android虛擬設備(AVD Android Virtual Device),它模擬真正的Android手機。

AVD讓你不訪問真機的狀況下對不一樣的Android版本和配置Android應用進行測試。即便你有真正的Android設備,也應該熟悉AVDS的建立和使用。

在建立AVD時定義爲虛擬設備的配置。這包括分辨率、Android的API版本和顯示密度。

您能夠定義多個有不一樣配置的AVD,並同時運行,一次測試不一樣的設備配置。
注意若是在啓動過程中止,AVD可能會損壞。舊機器上第一次啓動可能須要長達10分鐘的。通常須要1-3分鐘的啓動新的AVD。

你能夠用鼠標控制的圖形用戶界面。右側仿真器的菜單還能夠訪問手機的按鈕。

 

在Android設備安裝以前,Android應用程序都必須進行簽名。Eclipse使用debug key自動簽名。此調試證書有365天有效期。當證書過時後,刪除debug.keystore文件j就會從新生成。默認存儲位置在OS X和Linux是在~/.android/,Windows XP:C:\Documents andSettings\[username]\.android\中,在Windows Vista和Windows 7:C:\Users\[username]]\.android\。快捷方式以下:

 

Shortcut Description
Alt+Enter Maximizes the emulator.
Ctrl+F11 Changes the orientation of the emulator from landscape to portrait and vice versa.
F8 Turns the network on and off

 

 

AVD能夠模擬Android設備或谷歌的設備。前者包含Android開源項目的程序。後者AVD包含附加谷歌特有的代碼,可使用新谷歌地圖API或新的位置服務。

快照或主機GPU功能只能選擇一個。前者第二次啓動啓動速度很是快。後者渲染速度更快。

AVD能夠運行基於ARM的CPU體系結構或基於英特爾CPI。後者在Intel / AMD的硬件快,由於模擬器不須要翻譯ARM CPU指令到Intel / AMD的CPU。

Intel image API(不是每一個版本都有)

能夠經過Android SDK管理器進行安裝,在Android Studio建立設備時自動安裝。經過包詳細信息可進行配置。

Intel emulator

驅動安裝:

Intel emulator

下載以後Android安裝目錄下的extras/intel文件夾包含驅動程序。你須要經過運行啓動.exe文件來安裝驅動程序。

下載後,您能夠建立基於英特爾模擬器新的AVD。模擬器啓動速度不變,但Android應用程序的執行過程更快。

Linux須要一個更復雜的設置,參見https://software.intel.com/en-us/android/articles/intel-hardware-accelerated-execution-manager。

 

在設備上打開USB調試(Settings → Development Options)可使用真機,Windows一般須要安裝驅動程序,參見http://developer.android.com/guide/developing/device.html。

注意Android版本的設備須要知足Android應用程序的最低版本。

若是鏈接了多臺設備,你能夠選擇。若是隻有一個設備鏈接時,應用程序被自動部署在該設備上。


另外特別推薦仿真器:Genymotion https://www.genymotion.com/


Android Studio入門

啓動頁面點擊"Start a new Android Studio project"啓動新的Android Studio項目。另外,您能夠從菜單File → New Project進入

Property Value
Application name Test App
Company Domain vogella.com
Package Name com.vogella.testapp
API (Minimum, Target, Compile with) Latest
Template Empty Activity

 

選擇「Empty Activity」, 效果以下:

Creating a new Android Studio project

由經過Tools → Android→ AVD Manager管理器定義新的Android虛擬設備(AVD)。

Create a new AVD

啓動模擬器,經過Run → Run 'app' 啓動應用:

Settings for a new AVD

 

Android應用的部件

Android應用是可獨立於其餘Android應用啓動和使用安裝單位。Android應用由Android組件,Java源文件和資源文件組成。

基於Intent對象的任務描述,Android應用組件能夠鏈接到其餘Android應用的組件。這樣能夠建立跨應用的任務。

Android的軟件組件:Application、Activities、Services、Broadcast receivers (short: receivers)、Content providers (short: providers)。

 

Android應用有一個Application類,它最早啓動並最後關閉。若是沒有明確的制定,Android會建立默認Application對象。

activity是Android應用的可視化表示。 Android應用能夠有多個activity。Activity使用 UI工具(Widget)和佈局管理器及fragment來建立用戶界面並與用戶交互。這兩個因素在接下來的章節中介紹。

廣播接收器(Broadcast receiver)能夠註冊爲監聽系統消息和intent。若是指定的事件發生接收器獲得Android系統的通知。例如能夠註冊一個Android系統完成啓動事件的接收器。

服務執行任務,而無需提供用戶界面。它們能夠與其它Android組件通訊,例如,經由廣播接收器通知用戶。

內容提供者(content provider)定義了應用數據的結構化的接口。provider可用於在應用訪問的數據,但也可用於與其餘應用共享數據。SQLite數據庫常常和provider一塊兒使用。 SQLite數據庫存儲數據,provider訪問數據。

類android.content.Context(上下文)的實例鏈接應用和Android系統,也能夠訪問項目資源和應用程序中全局信息。例如,您能夠查看當前設備顯示的大小。上下文類還能夠訪問Android的服務,例如,報警管理器觸發基於時間的事件。Activity和service擴展Context類。

 

Android的基本用戶界面組件

Activity:前面已經介紹。

Fragment:片斷是Activity內運行的context組件。片斷封裝的應用代碼,使得它更容易重用,並支持不一樣大小的設備。

下圖的MainActivity在較小的屏幕,僅顯示一個片斷,並容許用戶導航到另外一片斷。在寬屏幕當即顯示這兩個片斷。

Shows only one Fragment at a time

Two Fragments side by side

 

視圖(View)是用戶界面工具,例如按鈕或文本域。View有可用於配置它們的外觀和行爲的屬性。ViewGroup中負責安排其餘View,也稱爲佈局管理器(layout manager)。佈局管理器的基類是android.view.ViewGroup類(基類android.view.View類)。佈局管理器能夠嵌套建立複雜的佈局。

其餘重要的Android元素

主屏幕和鎖屏小工具:Widget是主要用於Android主屏幕上的交互式組件。它們一般顯示某些種類型數據,並容許用戶執行。例如Widget能夠顯示新電子郵件的簡短摘要,而且若是用戶選擇了電子郵件,能夠開啓對應的電子郵件應用。

爲了不和view(這也稱爲widget)混淆,本文指明是主屏widget
動態壁紙爲Android主屏幕建立背景。


manifest

組件和Android應的設置在AndroidManifest.xml文件描述。此文件被稱爲manifest文件manifest。manifest還指定應用的其餘元數據,例如icon和應用程序的版本號。Android系統安裝的應用時讀取該文件。而Android系統評估這個配置文件,並肯定應用的權限。

應用全部活動,服務和內容提供商組件必須在此文件中靜態聲明。廣播接收器能夠靜態地在manifest文件生命或在運行時動態使用。

Android manifest文件還必須包含應用所需的權限。例如網絡訪問。下面是簡單的manifest文件實例:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.rssreader"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:name="RssApplication"
        android:allowBackup="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="RssfeedActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".DetailActivity"
            android:label="Details" >
        </activity>
        <activity android:name="MyPreferenceActivity" >
        </activity>
        <service android:name="RssDownloadService" >
        </service>
    </application>
</manifest>

 

package屬性定義該文件中Java對象引用的基礎包。若是Java對象在不一樣的包,必須包的全名聲明。

Google Play要求每一個Android應用都使用本身獨特的包名。一般使用反向域名,以免與其餘Android應用衝突。

android:versionName and android:versionCode指定應用的版本。 versionName對用戶可見,而且能夠是任意字符串。android:versionCode必須是整數。而Android市場基於android:versionCode肯定是否安裝執行更新。您一般以從1開始遞加。

 

<application>部分容許定義元數據和選擇性定義一個explicit應用類。是宣佈Android組件的容器。

<activity>標籤訂義activity組件。 name屬性指向類。

intent filter部分Android運行時該activity註冊爲應用可能的入口點,並在Android系統的launcher可見。(android:name="android.intent.action.MAIN" ) 代表能夠啓動,category android:name="android.intent.category.LAUNCHER"代表添加activity到launcher

@string/app_name指向資源文件,包含應用名稱。資源文件的使用很容易地對不一樣的設備提供不一樣的資源(例如,字符串,顏色,圖標),容易地翻譯應用。

相似<activity>,您可使用service,receiver和provider生命其餘Android組件。

 

Value Description
minSdkVersion Define the minimum version of Android your application works on. This attribute is used as a filter in Google Play, i.e., a user cannot install your application on a device with a lower API level than specified in this attribute.
targetSdkVersion Specifies the version on which you tested and developed. If it is not equal to the API version of the Android device, the Android system might apply forward- or backward-compatibility changes. It is good practice to always set this to the latest Android API version to take advantages of changes in the latest Android improvements.                                                                 

uses-configuration能夠指明輸入方式.例如硬鍵盤。

<uses-configuration android:reqHardKeyboard="true"/>

uses-feature容許您指定硬件配置。例如要求具備攝像頭。

<uses-feature android:name="android.hardware.camera" />

installLocation指定安裝位置如果能夠在外部存儲安裝。使用autopreferExternal容許。實際上這個選項不多使用,如安裝在外部存儲,一旦設備被鏈接到計算機做爲USB存儲應用就被中止。

更多資料:http://developer.android.com/intl/zh-cn/guide/topics/manifest/manifest-intro.html


資源

Android能夠建立如圖像和XML配置文件靜態資源。資源文件必須放在應用/res目錄中預約義的子文件夾。

Resource Folder Description
Drawables /res/drawables Images (e.g., png or jpeg files) or XML files which describe a Drawable object. Since Android 5.0 you can also use vector drawables which scale automatically with the density of the Android device.
Simple Values /res/values Used to define strings, colors, dimensions, styles and static arrays of strings or integers via XML files. By convention each type is stored in a separate file, e.g., strings are defined in the res/values/strings.xml file.
Layouts /res/layout XML files with layout descriptions are used to define the user interface for Activities and fragments.
Styles and Themes /res/values Files which define the appearance of your Android application.
Animations /res/animator Defines animations in XML for the animation API which allows to animate arbitrary properties of objects over time.
Raw data /res/raw Arbitrary files saved in their raw form. You access them via an InputStream object.
Menus /res/menu Defines the actions which can be used in the toolbar of the application.                                                                 

下面/res/values/values.xml,它定義了一些字符串常量,字符串數組,顏色和尺寸。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Test</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string-array name="operationsystems">
        <item>Ubuntu</item>
        <item>Android</item>
        <item>Microsoft Windows</item>
    </string-array>
    <color name="red">#ffff0000</color>
    <dimen name="mymargin">10dp</dimen>
</resources>

 

附加限定符到文件夾名稱指示相關的資源應該用於特殊的配置。例如能夠指定佈局文件僅適用於特定的屏幕尺寸。

Android構建系統爲每一個資源分配一個ID。在Android項目gen目錄中包含R.java引用文件,其中包含這些生成的值。這些引用是靜態的整數值。

添加新的資源文件,相應的引用會自動在R.java文件中建立。不須要手工修改。Android系統提供的方法經過這些ID來訪問相應的資源文件。

例如,在源代碼中訪問R.string.yourString ID的字符串,你會使用的上下文類定義getString(R.string.yourString)方法。


而Android SDK使用駝峯表示法大部分的ID,例如,buttonRefresh的。

系統資源在Android命名空間。例如,android.R.string.cancel取消操做定義的平臺字符串。

 

資源文件佈局

Android的activity使用views (widgets)和fragment定義其用戶界面。該用戶界面可在/res/layout文件夾或Java代碼中定義。您也能夠混合使用這兩種方法。經過XML佈局文件定義的佈局是首選方法,可分隔佈局定義和編程邏輯。它也容許爲不一樣的設備定義不一樣的佈局的。

佈局資源文件被稱爲layout。佈局指定ViewGroup和View,好比:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <TextView
        android:id="@+id/mytext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
</RelativeLayout>

setContentView()方法可分配佈局給activity,好比:

package com.vogella.android.first;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}


若是須要經過Java代碼訪問view,須要經過android:id給視圖惟一ID。好比:

<Button
  android:id="@+id/button1"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Show Preferences" >
</Button>

/res/values/ids.xml中定義id是好方法:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="button1" type="id"/>
</resources>

 

在佈局文件可使用ID。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <Button
        android:id="@id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="27dp"
        android:text="Button" />

</RelativeLayout>

注意:若是要在獨立文件中定義id,首先須要刪除在佈局文件中的@+id條目,不然會獲得文件已經建立了的錯誤信息。

計算layout和畫view是資源密集型操做。佈局要可能簡單。例如應該避免嵌套佈局管理器太深。

 

Android view - UI Widget

Android中的view表明widget,例如按鈕或佈局管理器。 Android SDK提供的標準views(widgets,例如,經過按鈕、TextView、EditText類。它還包括複雜的widget,例如ListView。

在Android的全部視圖擴展android.view.View類。這個類是比較大(超過1.8萬行的代碼),併爲子類提供了大量的的基本功能。

view的主包是的基類是android.view命名空間的一部分,android.widget爲Android平臺的默認widget。

Layout Manager和ViewGroup

佈局管理器(layout manager)是ViewGroup的子類,負責自己及其子視圖的佈局。 Android支持不一樣的默認佈局管理器。Android 4.0的最相關的佈局管理器是的LinearLayout、FrameLayout、RelativeLayout的和GridLayout。AbsoluteLayout已不建議使用,TableLayout能夠更有效地經過GridLayout來實現。

全部佈局容許開發者定義的屬性。孩子也能夠定義可被其父親佈局進行評估的屬性。孩子能夠經過如下屬性指定他們但願的寬度和高度。

ttribute Description
android:layout_width Defines the width of the widget.
android:layout_height Defines the height of the widget.


Widget可使用固定尺寸,例如dp定義爲100dp。雖然dp固定大小,可根據設備配置擴展。

match_parent告訴應用最大限度地在父親最大化widget。wrap_content儘可能少使用以保證正確渲染。窗口小部件正確呈現的最低金額。這些元素的效果表如今如下的圖形。

Layout with wrap_content

Layout with match_parent

FrameLayout是在子元素的頂部互相畫。有漂亮的視覺效果。好比Gmail:

FrameLayout

LinearLayout中把全部子元素放入行或者列(基於android:orientation肯定)。可能的屬性爲horizontal或vertical,默認爲horizontal。

horizontal效果以下:

Vertical效果以下:

LinearLayout中能夠嵌套以實現更復雜的佈局。LinearLayout支持經過android:layout_weight分配權重。

RelativeLayout的用於複雜的佈局。好比要居中一個組件,設置android:layout_centerInParent爲true

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
         />
</RelativeLayout>

 

Android 4.0引入了網格佈局(GridLayout)。相似表格,繪圖區域爲行,列和單元格。

你能夠指定每一個視圖要多少列,放置的行和列。若是沒有指定,GridLayout使用默認值,例如:一列一行,視圖的位置取決於聲明的順序。好比:

下面的佈局文件定義了使用GridLayout的佈局。

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/GridLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="4"
    android:useDefaultMargins="true" >
    <TextView
        android:layout_column="0"
        android:layout_columnSpan="3"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="40dp"
        android:layout_row="0"
        android:text="User Credentials"
        android:textSize="32dip" />
    <TextView
        android:layout_column="0"
        android:layout_gravity="right"
        android:layout_row="1"
        android:text="User Name: " >
    </TextView>
    <EditText
        android:id="@+id/input1"
        android:layout_column="1"
        android:layout_columnSpan="2"
        android:layout_row="1"
        android:ems="10" />
    <TextView
        android:layout_column="0"
        android:layout_gravity="right"
        android:layout_row="2"
        android:text="Password: " >
    </TextView>
    <EditText
        android:id="@+id/input2"
        android:layout_column="1"
        android:layout_columnSpan="2"
        android:layout_row="2"
        android:inputType="textPassword"
        android:ems="8" />
    <Button
        android:id="@+id/button1"
        android:layout_column="2"
        android:layout_row="3"
        android:text="Login" />
</GridLayout>

這將建立相似下面的截圖的用戶界面。

GridLayout Activity result

ScrollView或HorizontalScrollView類不是佈局管理器,但要提供可視性,即便在不適合屏幕上。滾動視圖能夠包含一個視圖,例如含有多個視圖的佈局管理器。 若是子view太大,滾動視圖容許滾動的內容。

Scroll view

代碼實例:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="8dip"
        android:paddingRight="8dip"
        android:paddingTop="8dip"
        android:text="This is a header"
        android:textAppearance="?android:attr/textAppearanceLarge" >
    </TextView>
</ScrollView>

 

android:fillViewport="true"屬性保證了滾動視圖設置爲全屏, 哪怕元素比屏幕小。

使用layout和view進行交互

 繼續前面的例子:修改res/layout/activity_main.xml

原文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main" tools:context=".MainActivity">
    <TextView android:text="Hello World!" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

 修改後的文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <EditText
        android:id="@+id/main_input"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentEnd="true" />
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/main_input"
        android:layout_below="@+id/main_input"
        android:layout_marginTop="31dp"
        android:onClick="onClick"
        android:text="Start" />
</RelativeLayout>

MainActivity.java

原文件:

package com.vogella.testapp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

使用該文件點擊"START"按鈕,會由於沒有實現onClick 而發生崩潰。

下面增長onClick:

package com.vogella.testapp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onClick (View view) {
        Toast.makeText(this, "Button 1 pressed",
                Toast.LENGTH_LONG).show();
    }

}

如今就有彈出信息顯示。下面修改爲顯示編輯框的內容。

package com.vogella.testapp;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // you may have here an onCreateOptionsMenu method
    // this method is not required for this exercise
    // therefore you can delete it

    public void onClick(View view) {
        EditText input = (EditText) findViewById(R.id.main_input);
        String string = input.getText().toString();
        Toast.makeText(this, string, Toast.LENGTH_LONG).show();
    }
}

上面代碼由於原代碼的log部分有錯而刪除,不影響主體功能。

運行時調整視圖佈局

繼續修改activity_main.xml,添加radio組和radio按鈕:

ID View
orientation Radio Group
horizontal First radio button
vertical Second radio button


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >


    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/main_input"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentEnd="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start"
        android:id="@+id/button"
        android:layout_below="@id/main_input"
        android:layout_alignParentStart="true"
        android:onClick="onClick"/>


    <RadioGroup
        android:id="@+id/orientation"
        android:layout_below="@id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp">

        <RadioButton
            android:id="@+id/horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Horizontal" >
        </RadioButton>

        <RadioButton
            android:id="@+id/vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="Vertical" >
        </RadioButton>
    </RadioGroup>


</RelativeLayout>

如今佈局以下:

Show the layout

更改onCreate()。使用findViewById()方法來查找您的佈局中的RadioGroup。

基於當前選擇單選按鈕實現監聽器,選擇以後改變方向爲橫向或縱向。
MainActivity.java代碼以下:


package com.vogella.testapp;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RadioGroup group1 = (RadioGroup) findViewById(R.id.orientation);
        group1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.horizontal:
                        group.setOrientation(LinearLayout.HORIZONTAL);
                        break;
                    case R.id.vertical:
                        group.setOrientation(LinearLayout.VERTICAL);
                        break;
                }
            }
        });
    }

    // you may have here an onCreateOptionsMenu method
    // this method is not required for this exercise
    // therefore you can delete it

    public void onClick(View view) {
        EditText input = (EditText) findViewById(R.id.main_input);
        String string = input.getText().toString();
        Toast.makeText(this, string, Toast.LENGTH_LONG).show();
    }
}


溫度轉換實例

下載地址:https://play.google.com/store/apps/details?id=de.vogella.android.temperature

也能夠在Google Play掃描二維碼:

QR Code to install the Android Temperature converter

建立工程:

Property Value
Application Name Temperature Converter
Package name com.vogella.android.temperatureconverter
API (Minimum, Target, Compile with) Latest
Template Empty Activity
Activity MainActivity
Layout activity_main

res/values/strings.xml建立屬性

Type Name Value
Color myColor #F5F5F5
String celsius to Celsius
String fahrenheit to Fahrenheit
String calc Calculate

修改後內容以下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Temperature Converter</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <color name="myColor">#F5F5F5</color>
    <string name="celsius">to Celsius</string>
    <string name="fahrenheit">to Fahrenheit</string>
    <string name="calc">Calculate</string>
</resources>


修改佈局res/layout/activity_main.xml

Component view

Current layout of activity_main.xml

內容以下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:background="@color/myColor">


    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/inputValue"
        android:inputType="numberSigned|numberDecimal"/>

    <RadioGroup
        android:id="@+id/radioGroup1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/editText1"
        android:layout_below="@+id/editText1">

        <RadioButton
            android:id="@+id/radio0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="@string/celsius" />

        <RadioButton
            android:id="@+id/radio1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/fahrenheit" />
    </RadioGroup>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/radioGroup1"
        android:layout_below="@+id/radioGroup1"
        android:layout_marginTop="22dp"
        android:text="@string/calc"
        android:onClick="onClick"/>

</LinearLayout>

建立ConverterUtil類用於轉換溫度:

com.vogella.android.temperatureconverter;

 {
    convertFahrenheitToCelsius(fahrenheit) {
        ((fahrenheit - ) * / );
    }

    convertCelsiusToFahrenheit(celsius) {
        ((celsius * ) / ) + ;
    }
}

修改MainActivity.java

原文件:

package com.vogella.android.temperatureconverter;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}


修改後:

package com.vogella.android.temperatureconverter;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;

public class MainActivity extends Activity {

    private EditText text;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (EditText) findViewById(R.id.inputValue);
    }
    
    // this method is called at button click because we assigned the name to the
    // "OnClick" property of the button
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
                RadioButton celsiusButton = (RadioButton) findViewById(R.id.radio0);
                RadioButton fahrenheitButton = (RadioButton) findViewById(R.id.radio1);
                if (text.getText().length() == 0) {
                    Toast.makeText(this, "Please enter a valid number",
                            Toast.LENGTH_LONG).show();
                    return;
                }
                float inputValue = Float.parseFloat(text.getText().toString());
                if (celsiusButton.isChecked()) {
                    text.setText(String
                            .valueOf(ConverterUtil.convertFahrenheitToCelsius(inputValue)));
                    celsiusButton.setChecked(false);
                    fahrenheitButton.setChecked(true);
                } else {
                    text.setText(String
                            .valueOf(ConverterUtil.convertCelsiusToFahrenheit(inputValue)));
                    fahrenheitButton.setChecked(false);
                    celsiusButton.setChecked(true);
                }
                break;
        }
    }
}


運行:

Change the text property of the radio button

未完待續,參考資料: http://www.vogella.com/tutorials/Android/article.html 

微博 http://weibo.com/cizhenshi 做者博客:http://www.cnblogs.com/pythontesting/ python測試開發精華羣 291184506 PythonJava單元白盒測試 144081101

相關文章
相關標籤/搜索