在本文中,我們將演示如何使用Android Studio和Java編程語言創建一個示例Android應用程式,從“臨時”實現高級響應用戶界面的功能。本文中討論的應用程式將實現機場航班時刻表模擬的功能。在開發生命周期中,我們將實現Android應用程式的響應式用戶界面,用於呈現“到達”和“離開”航班的 ...
在本文中,我們將演示如何使用Android Studio和Java編程語言創建一個示例Android應用程式,從“臨時”實現高級響應用戶界面的功能。本文中討論的應用程式將實現機場航班時刻表模擬的功能。在開發生命周期中,我們將實現Android應用程式的響應式用戶界面,用於呈現“到達”和“離開”航班的列表,並提供動態生成和更新實時模式中的航班信息的功能。
我們將大力強調幾個Java語言編程方面,並深入研究允許我們提供高級Android應用程式的編程技術的數量,包括從一開始就創建響應app's drawer和navigation bar應用程式的方面,提供我們自己的custom views並且layouts,如custom search view bar with action button,覆蓋預設功能通用app's action bar,保持tabbed layout,渲染recycler views ,不同於listviews或gridviews允許創建的自定義外觀的項目lists由應用程式所呈現的數據,與創建各種佈局多重嵌套fragments,使用 bottom navigation view等
除了應用程式的界面特定主題,我們還將瞭解如何創建一個用Java編寫的高效代碼來實現生成和操作數據內容的功能,以及如何提供操作數據的代碼和應用程式的用戶界面。
具體來說,我們將實施機場航班時刻表模擬器的功能,該模擬器生成隨機航班數據集並通過在實時模式中過濾掉航班來模擬航班到達和延長時間線來操縱這些數據,動態更新航班列表被渲染。為此,我們將使用和討論諸如使用Android應用程式的後臺任務,使用計時器等主題。
背景
先決條件(在我們開始之前...)
在我們開始討論之前,讓我們花點時間仔細研究一下到目前為止我們特別需要的開發工具和庫來構建和運行我們的第一個Android應用程式。
因為,我們即將使用Java編程語言來部署我們運行Android的第一個應用程式,我們必須安裝Java SE。為此,我們需要從http://www.codesocang.com/下載並安裝Java Standard Edition - SE平臺。反過來,Java SE平臺包含在PC上構建和運行用Java編寫的代碼所需的所有庫和模塊。
在我們成功安裝Java SE平臺之後,我們還需要正確安裝IDE和創建Android應用程式項目所需的特定庫,並構建運行我們正在部署的應用程式的代碼。各種IDE,編程語言和庫的數量,例如由Android開發社區授權的Microsoft Visual Studio / C#.NET Xamarin或Android Studio,可以有效地用於創建和部署Android應用程式。
在本文中,為了提供Android應用程式開發生命周期的效率,平臺相容性以及開發流程,我們將特別使用Android Studio和Java編程語言來實現此目的。
這就是為什麼,在我們在之前的配置步驟中安裝Java SE平臺之後,需要並強烈建議在開發機器上下載並安裝Android Studio(https://developer.android.com/studio/)。
我們可能已經註意到,安裝的Android Studio包含許多開發工具,包括IDE,Java SDK和NDK庫,Android系統模擬器,Gradle / Maven - java編譯器的“make”實用程式,可以更輕鬆地編譯和編譯用Java編程語言編寫的鏈接代碼。
反過來,Android Studio的IDE是一個高效且響應迅速的工具,用於輕鬆創建和編輯Android源碼以及實現基本應用程式功能的Java代碼。
除了高效便捷的IDE之外,Android Studio軟體包還包括為各種目標(手機,平板電腦,可穿戴設備,Android電視......)開發Android應用程式所需的Java SDK庫。具體來說,Android Studio IDE允許通過SDK管理器下載和安裝適用於各種Android系統版本的SDK,SDK Manager是Android Studio的一部分,或者可選地定期使用Java SDK發行版中的本機SDK管理器。
為了編譯和鏈接正在創建的應用程式,Android Studio的軟體包還包括上面提到的Gradle / Maven'make'實用程式。在Android Studio中創建我們的第一個Android應用程式項目時,Gradle組件已下載並配置為與Android Studio的IDE一起使用。每次,當我們構建和運行Android應用程式的項目時,Gradle實用程式正在執行編譯和鏈接特定的任務,例如創建包含內置Android應用程式的apk包,可以在模擬器上運行或者一個Android設備。在開發生命周期中,由於已經創建和配置了項目,因此我們可以使用Gradle實用程式的多個版本,就像在本文的項目創建部分中討論的那樣。
為了能夠在調試開發階段運行應用程式,Android Studio還包括一個支持各種Android系統版本的Android設備模擬器,可通過Android Studio的模擬器管理器從Google和Android開發社區網站源碼下載。在模擬器上運行應用程式與在目標Android設備上運行應用程式非常相似。
在本文的下一部分中,我們將演示如何在安裝的Android Studio環境中創建我們的第一個Android應用程式項目。
摘要
創建您的第一個Android App項目
在我們成功滿足上面討論的所有安裝和配置要求之後,我們要做的第一件事就是運行Android Studio並創建一個項目來實現我們的機場航班時刻表模擬Android應用程式功能。為此,我們將使用Android Studio主對話框切換啟動新的Android Studio項目選項:
在此之後,Android項目創建對話框將出現在屏幕上:
在這個對話框中,我們必須指定一個應用程式名稱(在這種情況下,它是` AirportApp`),公司域(例如,` epsilon.com`)來正確配置應用程式包,項目位置,特別是包name,在我們的例子中是` com.epsilon.airportapp`。在我們提供了創建項目所需的所有信息後,單擊此對話框底部的下一個按鈕。
在此步驟之後,我們必須正確選擇並指定我們的應用程式的目標設備,包括正確的外形(“手機”或“平板電腦”),最小的SDK及其版本,以及Android系統發佈版本:
在我們成功選擇了目標設備和Android發佈版本之後,我們還必須選擇一種應用程式的活動。活動通常是java類實現功能,負責應用程式的主視窗創建,事件處理以及完成其他用戶交互特定任務。實際上,擴展泛型Activity類或其他派生類的java 類是任何現有Android應用程式的主類:
在這種特殊情況下,我們開始我們的第一個Android應用程式開發生命周期,選擇一個空活動作為我們的機場計劃模擬器應用程式的主要活動。此外,我們將定製和增強預設的空活動,以提供執行機場計劃模擬任務所需的功能。
Android應用程式創建階段的最後一步是配置基於活動的java類別名,生成特定的活動佈局,以及配置應用程式的向後相容庫。為此,我們必須繼續下一個配置對話框:
在最後一步中,我指定一個應用程式基於活動的java類名稱,該名稱將對應於正在生成的特定活動佈局xml文件名。此外,我們必須指定是否要提供應用程式與舊版Android的向後相容性。
由於我們已經配置了應用程式的活動,因此在最後階段生成特定項目並打開Android Studio的IDE主視窗:
在本文的下一部分中,我們將簡要介紹使用Android Studio創建的Android應用程式的項目結構。
Android App的項目結構
在這一點上,讓我們仔細看看應用程式項目創建後打開的Android Studio IDE主視窗左上角的應用程式解決方案樹。通常,解決方案樹顯示正在創建的項目的內容,該內容與保存到特定位置的目錄結構完全對應(例如,“ D:\ AirportApp ”)。
AndroidManifest.xml中
文件夾“清單”是顯示在應用解決方案樹頂部的第一個文件夾。它基本上只包含一個文件' AndroidManifest.xml '。以下文件主要包含運行正在創建的應用程式所需的xml格式的所有配置數據。AndroidManifest.xml文件具有以下結構,對於所有Android應用程式都完全相同:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.epsilon.arthurvratz.airportapp"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme.NoActionBar"> <activity android:name=".AirportActivity" android:theme="@style/AppTheme.NoActionBar" android:windowSoftInputMode="stateHidden" android:configChanges="orientation|screenSize|keyboard|keyboardHidden"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
AndroidManifest.xml文件的第二行包含manifest標記,其屬性提供命名空間和應用程式的包名稱信息。它還包含一個嵌套標簽application ,該標簽具有定義標簽,文本方向和創建的應用程式的一對圖標的屬性數。由應用程式標簽的屬性指定的圖標和標簽基本上顯示在應用程式的主視窗中。應用程式標記還包含一個定義預設應用程式主題的屬性(例如,android:theme="@style/AppTheme")。或者,我們可能希望修改現有的或嚮應用程式標記添加更多屬性,以便提供應用程式主視窗的自定義外觀和行為。例如,我們可能想要更改值android:theme屬性,以便我們的應用程式將覆蓋預設的泛型並使用其自己的應用程式操作欄實現。為此,我們需要將以下標記的值更改為android:theme="@style/AppTheme.NoActionBar".
通常,application標記具有嵌套標記的數量,例如activity標記,用於提供主應用程式活動的一組配置屬性。預設情況下,activity標記只有一個屬性,用於定義主應用程式活動的名稱(例如android:name=".AirportActivity")。要修改應用程式的主要活動配置參數,我們可能需要向以下標記添加更多屬性:
android:theme="@style/AppTheme.NoActionBar" android:windowSoftInputMode="stateHidden" android:configChanges="orientation|screenSize|keyboard|keyboardHidden">
在這種特殊情況下,我們將以下配置屬性添加到activity上面列出的機場計劃模擬器應用主標簽中。第一個屬性是我們之前在application 上面標記中指定的屬性的副本。以下屬性用於指定將顯示正在運行的應用程式中的預設通用應用程式操作欄。第二個屬性android:windowSoftInputMode="stateHidden"用於指定在啟動應用程式時不會自動呈現的軟輸入方法。最後一個屬性 android:configChanges="orientation|screenSize|keyboard|keyboardHidden"提供應用程式覆蓋的配置更改列表。這意味著應用程式將處理以下更改,而不是Android系統。具體來說,應用程式將處理屏幕旋轉並根據當前屏幕方向呈現正確的界面佈局變化(例如' portrait'或' landscape')。
應用程式標記還包含最內層嵌套標記的數量,例如intent-filter,action和category。在action和category裡面的意圖標簽intent-filter標簽指定的主應用程式的入口點。特別是,這些標簽指定當前'.AirportActivity' 是主應用程式的活動:
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
Gradle腳本
現在,讓我們來看看位於應用解決方案樹底部的' Gradle Scripts '兄弟。以下文件夾包含配置上一節中提到的gradle'make'實用程式所需的所有腳本文件,包括項目' '或' '模塊的兩個' build.gradle '文件實例。第一個build.gradle文件包含以下內容:AirportAppapp
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.1.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
以下文件是包含Gradle存儲庫的基本配置的非xml文件,包括其構建版本(例如 'com.android.tools.build:gradle:3.1.3')。在項目配置期間,以下文件的內容通常保持不變。 但是,第二個build.gradle文件特別感興趣。第二個build.gradle文件基本上包含應用程式的項目模塊依賴項的定義。例如:
apply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { applicationId "com.epsilon.arthurvratz.airportapp" minSdkVersion 24 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0-alpha3' implementation 'com.android.support:support-v4:28.0.0-alpha3' implementation 'com.android.support:support-v13:28.0.0-alpha3' implementation 'com.android.support:design:28.0.0-alpha3' implementation 'com.android.support:recyclerview-v7:28.0.0-alpha3' implementation 'com.android.support.constraint:constraint-layout:1.1.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'org.jetbrains:annotations-java5:15.0' }
為了能夠使用Android支持庫,我們必須v.4,v.7,v.13將以下行添加到此文件的部分:RecyclerViewConstraintLayout dependencies
<span Courier New",Courier,mono; font-size: 12px; font-size-adjust: none; font-stretch: 100%; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; line-height: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-shadow: none; text-transform: none; -webkit-text-stroke-width: 0px; white-space: pre; word-spacing: 0px;">
implementation 'com.android.support:appcompat-v7:28.0.0-alpha3' implementation 'com.android.support:support-v4:28.0.0-alpha3' implementation 'com.android.support:support-v13:28.0.0-alpha3' implementation 'com.android.support:design:28.0.0-alpha3' implementation 'com.android.support:recyclerview-v7:28.0.0-alpha3' implementation 'com.android.support.constraint:constraint-layout:1.1.2'</span>
反過來,' gradle-wrapper.properties '和' local.properties '文件都是另一個特別的興趣: gradle-wrapper.properties:
#Thu Jul 26 06:49:16 EEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
local.properties:
## This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. # # Location of the SDK. This is only used by Gradle. # For customization when using a Version Control System, please read the # header note. #Thu Jul 26 15:02:12 EEST 2018 sdk.dir=C\:\\AndroidSDK
在此文件中,我們可以指定gradle實用程式版本或Android SDK位置的絕對路徑。為此,我們必須修改這兩個文件的以下行:
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
sdk.dir=C\:\\Android\AndroidStudio\SDK註意:如果您的gradle更改的版本> gradle-4.6-all.zip,,那麼你就還需要禁用“ 配置需求 ”中的“選項文件”>“ 設置 ”>“ 建立,實施,部署 “> 編譯器 ”。
應用程式的活動和佈局文件
在我們完全符合所有應用程式的項目配置步驟之後,讓我們看看我們未來應用程式的活動java實現文件和主應用程式的佈局xml文件。主應用程式的佈局文件位於“ res / layout ”文件夾下,名稱為“ activity_airport.xml ”。以下文件最初包含' android.support.constraint.ConstraintLayout'標記,這是空應用程式的預設佈局。 要修改的主要應用程式的佈局,並添加我們的Android應用程式的界面組件,如其他直列佈局或控制(即“若幹意見”),我們必須使用Android Studio的佈局設計或手動編輯以下佈局文件:為了能夠在Android Studio的設計器中編輯佈局,您還必須修改可以位於應用程式項目的“ res / values ”文件夾中的“ styles.xml ” :
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources>
具體來說,您必須parent將' style'標簽的' '屬性值更改parent="Theme.AppCompat.Light.DarkActionBar"為 parent="Base.Theme.AppCompat.Light.DarkActionBar"。 以下佈局是預設的空應用程式佈局,將在討論應用程式的開發生命周期期間進行更改。或者,我們可以通過手動編輯' activity_airport.xml '佈局文件來添加對應用程式佈局內容的更改:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".AirportActivity"> <TextView android:layout_width="wrap_content" android:layout_height="19dp" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
此外,我們將在本文的後續部分之一中提供有關如何使用約束佈局來構建響應式應用程式界面的詳細指南。 我們此時要討論的最後一個方面是應用程式的主要活動實現文件' com.epsilon.airportapp / AirportActivity.java':
package com.epsilon.airportapp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class AirportActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_airport); } }
以下文件包含在第一個' com.epsilon.airportapp '文件夾中,並包含' AirportActivity'擴展泛型AppCompatActivity'類的java類的聲明。最初,AirportActivity類只包含一個重寫方法' OnCreate',實現將應用程式佈局呈現為正在創建的應用程式的主內容視圖的功能。以下方法實現了調用onCreate超類中的' '方法,或者接受主應用程式的佈局resource-id' R.layout.activity_airport'的setContentView方法,併為主應用程式的佈局提供了基本的呈現功能。將來,我們會修改' AirportActivity''
應用程式的主要佈局Bluep rint
此時,我們的主要目標是創建機場計劃模擬應用程式的主要佈局設計草圖。更具體地說,主應用程式的佈局將具有以下外觀:
從上圖中可以看出,整個主要機場應用程式的佈局包括'SearchView'最頂層的高級變體'TabLayout',其中將呈現兩個到達和離開航班列表。每個選項卡將呈現一個'RecyclerView'顯示航班列表,' BottomNavigationView'允許導航將在'昨天','現在'和'tommorow'發生的航班列表中。“TabLayout”和“RecyclerView”由特定片段佈局呈現,這些佈局在切換應用程式的抽屜導航菜單項或選擇其中一個特定選項卡後顯示。 主應用程式的佈局主要基於' DrawerLayout'模式,這意味著應用程式的抽屜將在用戶切換應用程式主視窗左上角的操作欄按鈕時呈現。應用程式的抽屜定期可能包含基於'NavigationView',應用程式主菜單等的抽屜標題。 在此之前,讓我們回想一下,這不是項目創建嚮導生成的標準應用程式佈局。此外,我們將討論如何以編程方式實現機場應用程式的自定義佈局。設計應用程式的主要佈局
現在,我們終於維護了機場應用程式的主要佈局藍圖,現在是時候創建和編輯一個或多個應用程式的佈局文件了。我們要修改的第一個文件是' activity_airport.xml '。由於我們的機場應用程式旨在擁有應用程式的抽屜,我們選擇' DrawerLayout'作為主應用程式的佈局類型:<?xml version="1.0" encoding="utf-8"?> <!-- Use DrawerLayout as root container for activity --> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/airport_drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <include layout="@layout/content_frame" android:layout_width="match_parent" android:layout_height="wrap_content"/> <android.support.design.widget.NavigationView android:id="@+id/airport_navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:menu="@menu/main_menu" app:headerLayout="@layout/nav_header_frame"/> </android.support.v4.widget.DrawerLayout>
在這種情況下,我們android.support.v4.widget.DrawerLayout在activity_airport.xml文件中使用' '作為根標記。在此之後,我們還需要創建兩個嵌套標簽,例如' include'標簽,它將包含單獨文件' content_frame.xml'中包含的以下佈局的另一部分,或' android.support.design.widget.NavigationView'標簽,聲明機場應用程式的標簽抽屜佈局。遺憾的是,由於使用了抽屜佈局,我們無法使用Android Studio的佈局設計器修改上面顯示的佈局,但我們可以使用Android Studio的IDE文本編輯器手動編輯此佈局。 應用程式主要佈局的包含片段存儲在內容框架文件中,如下所示:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/search_bar" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toTopOf="@+id/airport_fragment_container" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.02" android:focusable="true" android:focusableInTouchMode="true"> <requestFocus /> <android.support.v7.widget.SearchView android:id="@+id/searchable" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <FrameLayout android:id="@+id/airport_fragment_container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" app:layout_constraintBottom_toTopOf="@+id/flights_navigation" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/search_bar"> </FrameLayout> <android.support.design.widget.BottomNavigationView android:id="@+id/flights_navigation" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/airport_fragment_container" app:menu="@menu/flights_navigation" android:theme="@style/AppTheme"/> </android.support.constraint.ConstraintLayout>
在這個文件中,我們通常使用' android.support.constraint.ConstraintLayout'標簽作為此佈局的根標簽。以下標記具有內聯標記的數量,包括' LinearLayout',其中' android.support.v7.widget.SearchView'標記被聲明',FrameLayout'實際上聲明瞭一個框架,將以編程方式替換為特定的片段渲染' RecyclerView',顯示一個航班列表,'BottomNavigationView'按時間過濾掉航班的渲染選項。由於我們使用約束佈局作為整個內容框架的根,因此必須正確約束所有嵌套視圖和佈局。與之前的佈局不同,可以使用Android Studio的佈局設計器成功編輯內容框架佈局。這就是我們選擇是否編輯特定內容框架文件或使用佈局設計器為以下佈局中的所有視圖提供特定約束的原因。 在這種情況下,互連內容框架中視圖的最佳方法是app:layout_constraintTop_toBottomOf向每個視圖標記添加特定屬性,例如' ',如上面的源代碼所示。在這段代碼中,我們從最上面的'LinearLayout'視圖標簽開始垂直和水平地向每個視圖標簽添加佈局約束屬性,以垂直方向鏈接所有這些屬性。 在這一點上,讓我們回到定義應用程式抽屜佈局的代碼片段。在' DrawerLayout'標簽內部聲明的另一個視圖是' android.support.design.widget.NavigationView'。以下視圖主要用於渲染應用程式的抽屜及其菜單,如上圖所示。使用導航視圖通常需要我們創建另一個應用程式的抽屜佈局和特定菜單,為應用程式的抽屜菜單聲明項目。 要創建這些佈局,我們基本上需要在項目的' / res '文件夾中創建一個子文件夾,並創建名為' main_menu.xml ' 的特定菜單佈局資源文件:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <group android:checkableBehavior="single"> <item android:id="@+id/flights" android:icon="@drawable/ic_flight_black_24dp" android:title="@string/flights" /> <item android:id="@+id/about" android:icon="@drawable/ic_star_black_24dp" android:title="@string/about" /> </group> </menu>
在這個文件中,我們必須聲明' menu'標簽,併在其中創建group項目的' '。在這種情況下,以下佈局包含每個“航班”或“關於”菜單選項的兩個項目組,顯示在應用程式的抽屜中,標題下方。 另一個佈局文件' nav_header_frame.xml '包含用戶切換時在應用程式抽屜中呈現的佈局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="240dp" android:background="@drawable/airport_nav_header" android:gravity="bottom" android:orientation="vertical" android:padding="16dp" android:theme="@style/ThemeOverlay.AppCompat.Dark"> <ImageView android:id="@+id/imageView" android:layout_width="103dp" android:layout_height="99dp" app:srcCompat="@mipmap/ic_launcher_round" /> <Space android:layout_width="352dp" android:layout_height="10dp" /> <TextView android:id="@+id/airport_app_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:fontFamily="Verdana" android:text="@string/nav_header" android:textColor="@android:color/background_light" android:textIsSelectable="false" android:textSize="30sp" /> <TextView android:id="@+id/airport_app_author" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/airport_app_author" /> </LinearLayout>
要創建應用程式的抽屜佈局,我們將使用特定的' LinearLayout'標簽。與其他佈局(例如' CostraintLayout')不同,線性佈局允許僅在垂直方向上定位所有視圖,並且不需要在視圖之間設置任何約束。 要定義正確的抽屜佈局,我們必須將以下視圖標記放置線上性佈局內,以及為應用程式的抽屜標題提供背景圖像。為此,我們指定以下線性佈局屬性:' android:background="@drawable/airport_nav_header"'。通常,我們創建的線性佈局將包含以下內聯視圖:
- ' ImageView' - 用於顯示機場應用程式的圖標;
- ' Space' - 線上性佈局中創建特定視圖之間的間隙;
- ' TextView' - 印表機場應用程式的標題或作者的詳細信息;
最後,由' NavigationView'及其藍圖呈現的應用程式的抽屜佈局將具有以下外觀:
在本文的下一部分中,我們將瞭解如何實現主要機場應用程式活動的功能。使用操作按鈕創建自定義SearchView
SearchView是出現在主應用程式視窗頂部的機場計劃模擬器應用程式的第一個控制項。此時,讓我們回到他標記的'content_frame.xml片段,聲明搜索視圖位於以下佈局文件的所有其他視圖之前,由' :包裹起來:'.Tandroid.support.v7.widget.SearchViewLinearLayout<font color="#007000" face=""Segoe UI",Arial,Sans-Serif">'</font>
<LinearLayout android:id="@+id/search_bar" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toTopOf="@+id/airport_fragment_container" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.02" android:focusable="true" android:focusableInTouchMode="true"> <requestFocus /> <android.support.v7.widget.SearchView android:id="@+id/searchable" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
我們使用線性佈局用於確保應用程式啟動後搜索視圖不會獲得焦點。 由於我們SearchView在內容框架中聲明瞭' '標簽,因此我們的目標是通過在java中實現特定代碼來提供功能和行為(例如,使搜索視圖響應),這些代碼將即時處理和處理事件。我們的搜索視圖。 我們可能知道,在這個項目中我們不會使用通用搜索視圖和應用程式欄,但會創建我們自己的自定義搜索視圖,它結合了通用搜索視圖的基本功能和應用程式的操作欄。 要使用操作按鈕創建自定義搜索視圖,我們需要創建一個新的java類,並將其命名為“ SearchableWithButtonView擴展泛型View”類:
public class SearchableWithButtonView extends View { // SearchView basic functionality implementation java-code goes here... }
在本課程中,我們需要實現以下方法。setupSearchableWithButton()是我們需要實現的第一個方法,以便為我們的自定義搜索視圖提供特定的外觀和行為:
public void setupSearchableWithButton() { // Set background color of the search view ((ViewGroup)m_SearchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon). getParent()).setBackgroundColor(Color.parseColor("#ffffff")); // Set default custom search of the search view button icon and look of the custom search view this.setDefaultSearchIcon(); this.setupIconifiedByDefault(); // Set default search hint displayed in the search view's edit text view m_SearchView.setQueryHint("TYPE HERE..."); // Set default query text and remove focus from the search view m_SearchView.setQuery("", false); getRootView().requestFocus(); // Instantinate the search view object and set default action button click event listener m_SearchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon). setOnClickListener(new SearchableViewListener()); // Instantinate the search view object ViewGroup llSearchView = ((ViewGroup)m_SearchView.findViewById( android.support.v7.appcompat.R.id.search_mag_icon).getParent()); // Instantinate object of the text editable inside the search view EditText searchEditText = llSearchView.findViewById( android.support.v7.appcompat.R.id.search_src_text); // Remove the search view text editable default selection searchEditText.setSelected(false); // Set text editable click event listener searchEditText.setOnClickListener(new SearchableViewListener()); // Set text editable onTextChange listener searchEditText.addTextChangedListener(new SearchableViewListener()); }
在此方法中,我們通過修改背景顏色,搜索視圖按鈕圖標,在應用程式啟動時從搜索視圖中刪除預設選擇和焦點來更改通用搜索視圖的外觀和行為,並且還設置處理程式(即偵聽器)各種搜索視圖事件,例如單擊用作應用程式主操作按鈕的搜索視圖按鈕,文本編輯和文本可編輯視圖點擊等。 這些事件處理程式實現為' SearchableWithButtonView '子類,在其中聲明:
public class SearchableViewListener implements OnClickListener, TextWatcher { @Override public void onClick(View view) { // Check if the custom search view button was clicked if (android.support.v7.appcompat.R. id.search_mag_icon == view.getId()) { // If so, perform a check if the default action bar icon was set if (!