Android开发入门经典实例
開發(fā)實例概述
今天帶大家做一個簡單的Android App,這個App會顯示創(chuàng)新工程實踐老師們的照片和信息,不妨先看一看效果:
雖然這個App非常簡單,但是涉及到了Android開發(fā)中的一些關(guān)鍵知識,比如:
- 配置開發(fā)環(huán)境
- App中一個屏幕的抽象:Activity
- 屏幕之間的跳轉(zhuǎn):Intent
- 構(gòu)成屏幕展示的視圖組件:顯示圖片的ImageView,顯示文字的TextView,把組件組成一個列表的視圖ListView
- 通過Adapter來控制模型和視圖組件之間通信,即如何在視圖上展示特定的數(shù)據(jù)
- 通過事件來處理用戶的交互:OnClickListener
讓我們開始吧!
建立開發(fā)環(huán)境
工欲善其事,必先利其器
在編寫代碼之前,我們需要在我們的計算機中配置集成開發(fā)環(huán)境(IDE,Integrated Development Environment),它是用來開發(fā)和部署軟件的工具集合。
如果你之前有過編程的經(jīng)歷,那么一定會知道最重要的工具是編譯器——它將我們用高級語言編寫的源代碼轉(zhuǎn)換成計算機可以執(zhí)行的指令來完成指定的任務(wù)。
開發(fā)環(huán)境的安裝和配置往往需要花費不少時間。對于不同的計算機以及操作系統(tǒng)平臺,安裝配置過程都不盡相同,會出現(xiàn)很多不可預(yù)測的錯誤—。新手見到這些錯誤往往會一頭霧水、不知如何解決。
好的開始等于成功的一般,開始學習前最重要的一個步驟就是完成開發(fā)環(huán)境的配置,讓我們開始吧。
配置Java開發(fā)環(huán)境
Android的開發(fā)使用Java語言,因此首先需要在開發(fā)設(shè)備上配置好Java的開發(fā)環(huán)境。
參考Java開發(fā)環(huán)境安裝與配置。
Android Studio的安裝
Android Studio是Google官方強烈推薦的集成開發(fā)環(huán)境。在Android官方網(wǎng)站下載Android Studio,它包含了:
- 基于IntelliJ平臺的Android IDE
- Android SDK工具(API、驅(qū)動、源碼、樣例等等)
- Android模擬器
由于眾所周知的原因,可能需要“翻墻”才能夠完整安裝Android Studio,這里給出一個百度網(wǎng)盤的下載鏈接:http://pan.baidu.com/s/1i3rIfPz
下載安裝文件之后,普通軟件的安裝過程沒有任何區(qū)別,不再贅述。
如果下載的不是最新版本,啟動Android Studio后,可以通過Check for Update更新到最新的版本。
這里先告訴大家一個小招數(shù),如果在編程過程中,遇到錯誤提示,alt+Enter(即按照alt鍵的同時按下回車鍵)可以自動進行錯誤修復。比如,在開發(fā)過程中我們經(jīng)常需要引入一些包,就能自動幫我們引入。
創(chuàng)建項目
啟動Android Studio
如果Android Studio中尚未打開任何項目,在Welcome頁面選擇Start a new Android Studio project
如果Android Studio中已經(jīng)打開了其他項目,從文件菜單中選擇New Project
Configure your new project中填寫相應(yīng)信息:
-
Application Name是我們項目的名稱,我們填寫為InnovationCourse
-
Company Domain是開發(fā)者所在的組織,一般是公司的域名,這里我們不妨填寫為zhihuishu.com
-
Project Location是項目存在在本地的位置
-
填寫好后,點擊Next
Select the form factors your app will run on中選擇Phone and Tablet并設(shè)置Mininum SDK為API 15: Android 4.0.3 (IceCreamSandwich)。Mininum SDK表示所支持的Android的最低版本,版本越低支持的設(shè)備數(shù)量就會越多。我們可以選擇不同的版本來看所支持設(shè)備的百分比。百分比越大,表示越多人可以使用你的APP。選擇好后點擊Next
Add an activity to Mobile中選擇Blank Activity,點擊Next
Customize the Activity中設(shè)置Activity信息,這里我直接使用Android Studio提供的默認信息即可
項目結(jié)構(gòu)
如果你急于開始項目的開發(fā),你可以略過這一小節(jié)。
現(xiàn)在我們已經(jīng)創(chuàng)建了一個基本的Android應(yīng)用,它包含了Android Studio幫助我們生成的文件,在默認的Android視圖中,文件結(jié)構(gòu)如下圖所示:
這里我們看到的是Android Studio給我們生成MainActivity的代碼骨架,這個Activity就代表App啟動的時候,我們看到的那個屏幕。這個Java文件定義了一個Activity,當應(yīng)用運行時,MainActivity類啟動一個Acitivty并加載activity_main.xml布局文件,將其顯示在屏幕上。Acitvity和layout的關(guān)聯(lián)是在MainActivity中onCreate()方法里完成的:setContentView(R.layout.activity_main);
我們再雙擊layout目錄下的activity_main.xml,可以看到這個屏幕的預(yù)覽:
點擊下方的Text,我們可以以文本的形式看到這個文件的內(nèi)容。這個文件就定義了屏幕中應(yīng)該顯示哪些組件。你如果學過HTML的話,可以類比一下,HTML描述了一個網(wǎng)頁長什么樣子,而這個XML文件則描述了App長什么樣子。可以看到,這個布局簡單的在屏幕上顯示了一條消息——Hello world!
我們再來來具體看一下其它幾個重要的文件:
-
app/src/main/AndroidManifest.xml
Android Manifest文件是描述Android應(yīng)用的基本信息,并定義了應(yīng)用中的各個組件(Activity是一種組件)。
-
)app/src/main/res目錄下包含了應(yīng)用所需要的資源文件:
- drawable<density>/?- 圖片資源文件
- layout/?- 用戶界面布局描述文件
- menu/?- 應(yīng)用的菜單布局
- values/?常量值例如字符串、顏色數(shù)值等
- strings/?國際化數(shù)據(jù)
運行應(yīng)用
在模擬器上運行應(yīng)用
- 在Android Studio的菜單中打開:?Tools > Android > AVD Manager
- 選擇Create Virtual Device創(chuàng)建模擬器
創(chuàng)建完成后,AVD Manager如下圖:
模擬器創(chuàng)建完成后,回到Android Studio的項目中,在工具欄里點擊Run按鈕,接下來會彈出一個Choose Device窗口,選擇Launch emulator并設(shè)置好需要使用的模擬器。
接下來等待模擬器啟動,然后就可以看見剛剛創(chuàng)建的應(yīng)用運行在模擬器窗口中了(剛啟動的機器可能需要在模擬器中解鎖屏幕)
在真機上運行應(yīng)用
在真機上運行應(yīng)用需要先進行一些設(shè)置:
- 將真機通過USB線纜連接至開發(fā)機器。如果在Windows上開發(fā),可能需要選擇合適的USB驅(qū)動,可以參考OEM USB Drivers文檔
- 在真機系統(tǒng)中打開USB調(diào)試選項
接下來就可以在Android Studio運行應(yīng)用了,方法和在模擬器相同,只是在Choose Device窗口中需要選擇USB連接的真機。
這里我們以模擬器為例進行講解。
展示列表
打開activity_main.xml布局文件,在Design視圖下,我們將上面的HelloWorld標簽刪掉。
我們準備在這個屏幕中顯示老師的列表,而一個列表是一個ViewGroup,內(nèi)部包含了其他的視圖。我們在顯示手機屏幕的預(yù)覽區(qū)的左側(cè)可以看到大量的視圖組件,這些就是用來構(gòu)建我們App模樣的基本元素。我們我們選中ListView,將其拖入預(yù)覽區(qū)內(nèi)
我們前后左右拖動一下,使其布滿屏幕。也可以切換到Text視圖來編輯XML,XML進行了修改之后,切回Design視圖可以馬上看到效果。
最終acitivity_main.xml中的內(nèi)容為:
<?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="com.zhihuishu.innovationcourse.MainActivity"><ListViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/teacher_listView"android:layout_alignParentLeft="true"android:layout_alignParentStart="true" /> </RelativeLayout>注意,這里面android:id="@+id/teacher_listView"定義了這個ListView的ID為teacher_listView,這是需要大家手動去修改的。當然你也可以全部復制后替換掉整個XML文件的內(nèi)容。
這個ID非常重要,我們在Java程序中,將需要通過這個ID來找到這個視圖組件,進行相應(yīng)的設(shè)置和操作。
視圖組件還有其他一些屬性,比如這里其它四個屬性都是跟布局相關(guān)的屬性,比如android:layout_alignParentLeft="true"就表示與包含它的父視圖是左側(cè)對齊的。其它屬性我們就不一一解釋了。
簡化的老師列表
準備數(shù)據(jù):實現(xiàn)模型
我們這里先實現(xiàn)一個簡化的老師列表,只顯示老師的名字,圖片暫時不管。
首先我們需要準備老師的數(shù)據(jù),我們來創(chuàng)建一個Teacher類。
選中java目錄下的com.zhihuishu.innovationcourse包,【右鍵】->【New】->【Java Class】,在彈出的窗口中輸入類的名稱Teacher。
給Teacher類增加一個獲取所有老師姓名的方法。這個Teacher類,正是我們所說的MVC中M,即Model。
package com.zhihuishu.innovationcourse;import java.util.ArrayList; import java.util.List;public class Teacher {public static List<String> getAllTeachers() {List<String> teachers = new ArrayList<String>();teachers.add("張海霞");teachers.add("陳江");teachers.add("葉蔚");return teachers;} }這里我們采用了硬編碼的形式,通常情況下數(shù)據(jù)是從數(shù)據(jù)庫中取出來的,而且是不斷變化的。不過這里我們不涉及數(shù)據(jù)庫訪問,簡化處理了。大家知道有數(shù)據(jù)庫的存在就可以了。
設(shè)置Adapter
用來將數(shù)據(jù)傳遞給ListView的適配器是ArrayAdapter。這里我們傳入的是一個字符串的數(shù)組,因此我們創(chuàng)建一個ArrayAdapter<String>類。
這部分代碼添加到MainActivity.java的onCreate方法中:
public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化一個AdapterArrayAdapter<String> teacherAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Teacher.getAllTeachers());//通過ID獲取listViewListView listView = (ListView) findViewById(R.id.teacher_listView);//設(shè)置listView的AdapterlistView.setAdapter(teacherAdapter);}... }注意初始化Adapter的代碼ArrayAdapter<String> teacherAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Teacher.getAllTeachers());三個參數(shù)的含義:
- 第一個參數(shù)是this,表示傳入的是當前的Activity
- 第二個參數(shù)是android.R.layout.simple_list_item_1,這是Android系統(tǒng)自帶的一個列表元素(即列表中的每一行)布局,只顯一串簡單的文字
- 第三個參數(shù)是需要顯示的所有數(shù)據(jù)構(gòu)成的List,即數(shù)據(jù)源
后面我們會傳入自己定義的元素布局(因為我們還希望在每一行中顯示老師的圖片),數(shù)據(jù)源也需要修改,因為此時不僅僅包含字符串了,還需要包含圖片。
運行效果
我們已經(jīng)可以看到一個簡單的老師列表的效果了:
優(yōu)化模型
老師的信息不僅僅包括姓名,還包括圖片和介紹。因此我們需要給Teacher類增加一些屬性,分別為name、imageId和desc。
老師的圖片我們實現(xiàn)準備好了,大家只需要拷貝進入drawable文件夾就能在Java代碼中引用了。我們之前說過drawable文件夾就是用來存放圖片文件的。
增加屬性之后我們還需要做三件事情:
改進列表
創(chuàng)建新的布局
為了在列表的一行中,同時顯示老師的圖片和名稱,我們需要創(chuàng)建自定義的布局。
選中res/layout目錄,【右鍵】->【New】->【Layout Resource File】,在彈出對話框中,輸入如下信息:
File Name為布局文件的名稱,我們輸入teacher_item。其他的輸入框使用默認信息即可。其中Root Element表示布局的方式,這里我們無需修改,使用默認的LinearLayout,即視圖組件通過線性的方式來進行布局。
新的布局中,我們需要在左側(cè)顯示一張圖片,右側(cè)顯示老師姓名,因此我們往預(yù)覽區(qū)拖入一個ImageView和TextView,然后切換到Text視圖進行編輯,最終的布局文件如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal" android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:layout_width="50dp"android:layout_height="50dp"android:layout_marginBottom="5dp"android:layout_marginTop="5dp"android:id="@+id/teacher_small_imageView" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="New Text"android:id="@+id/teacher_name_textView"android:layout_gravity="center_vertical" /> </LinearLayout>注意我們將根元素<LinearLayout>的android:orientation改為了horizontal,因為我們希望老師的圖片和老師的姓名水平線性布局。
ImageView命名為teacher_small_imageView,長寬都為50dp,與上下的間距為5dp。dp是一種長度的單位,也有其他類型的單位,dp能夠比較好的兼容各種分辨率的設(shè)備。
TextView命名為teacher_name_textView,長寬為根據(jù)內(nèi)容自適應(yīng),與左側(cè)圖片間距為10dp,垂直居中。
創(chuàng)建自定義的ArrayAdapter
我們創(chuàng)建一個自定義的ArrayAdapter。我們創(chuàng)建一個命名為TeacherAdapter的類,讓其繼承ArrayAdapter<Teacher>,同時提供一個構(gòu)造函數(shù)。
package com.zhihuishu.innovationcourse;import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView;import java.util.List; import java.util.zip.Inflater;public class TeacherAdapter extends ArrayAdapter<Teacher> {public TeacherAdapter(Context context, int resource, List<Teacher> objects) {super(context, resource, objects);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// 獲取老師的數(shù)據(jù)Teacher teacher = getItem(position);// 創(chuàng)建布局View oneTeacherView = LayoutInflater.from(getContext()).inflate(R.layout.teacher_item, parent, false);// 獲取ImageView和TextViewImageView imageView = (ImageView) oneTeacherView.findViewById(R.id.teacher_small_imageView);TextView textView = (TextView) oneTeacherView.findViewById(R.id.teacher_name_textView);// 根據(jù)老師數(shù)據(jù)設(shè)置ImageView和TextView的展現(xiàn)imageView.setImageResource(teacher.getImageId());textView.setText(teacher.getName());return oneTeacherView;} }這段代碼的主要功能就是,提供了一個getView()方法的重載實現(xiàn),我們通過重載這個方法就能夠讓listView根據(jù)我們的要求來生成每一個列表元素了。而這個方法做了四件事情:
在MainActivity.java中的代碼也需要做相應(yīng)的修改,此時我們要創(chuàng)建一個TeacherAdapter的對象,并將其設(shè)置為listView的Adapter。
public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TeacherAdapter teacherAdapter = new TeacherAdapter(this, R.layout.teacher_item, Teacher.getAllTeachers());ListView listView = (ListView) findViewById(R.id.teacher_listView);listView.setAdapter(teacherAdapter);}... }運行效果
此時已經(jīng)可以看到更好看的老師列表界面了:
創(chuàng)建第二個Activity
一切進展順利,我們已經(jīng)了解如何創(chuàng)建Activity中的視圖,如何通過Adapter給視圖傳遞數(shù)據(jù)。接下來我們要做一個功能,當點擊列表中的每一項時,會進入第二個Activity,顯示老師的大圖片以及詳細介紹。
所以我們先來創(chuàng)建第二個Activity吧。
選中java目錄下的com.zhihuishu.innovationcourse包,【右鍵】->【New】->【Activity】->【Blank Activity】,在彈出的窗口中輸入Activity名稱TeacherDetailActivity,點擊【Finish】。
類似于teacher_item.xml布局的編輯,我們往預(yù)覽區(qū)中拖入一個ImageView和TextView,然后在Text視圖中進行布局的編輯。最終的布局配置如下:
<?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="com.zhihuishu.innovationcourse.TeacherDetailActivity"><ImageViewandroid:layout_width="300dp"android:layout_height="300dp"android:id="@+id/teacher_large_imageView"android:layout_alignParentTop="true"android:layout_centerHorizontal="true" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="New Text"android:id="@+id/teacher_desc_textView"android:layout_below="@+id/teacher_large_imageView"android:layout_centerHorizontal="true"android:layout_marginTop="20dp" /> </RelativeLayout>很多屬性我們之前已經(jīng)遇到過了。這里我們使用了另外一種布局RelativeLayout,顧名思義,就是通過視圖元素的相對位置來進行布局。其中關(guān)鍵的一行代碼是android:layout_below="@+id/teacher_large_imageView",這表示teacher_large_imageView在teacher_large_imageView的下方。
實現(xiàn)行為:事件處理
這個Activity的布局已經(jīng)創(chuàng)建好了,如何跳轉(zhuǎn)到這個Activity呢?這時我們需要識別出用戶的點擊行為,當用戶點擊發(fā)生時才能進行跳轉(zhuǎn)。
我們回到TeacherAdapter的getView()方法,在最后一條return語句前加入:
oneTeacherView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 這里進行跳轉(zhuǎn)}});這段代碼就是在返回oneTeacherView之前,設(shè)置一個OnClick點擊事件的監(jiān)聽器,當事件發(fā)生的時候,就會執(zhí)行public void onClick(View v)內(nèi)部的代碼。
Activity的跳轉(zhuǎn):Intent
接下來我們就要進行真正的跳轉(zhuǎn)了,?Intent終于排上用場了,代碼如下:
oneTeacherView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 初始化一個準備跳轉(zhuǎn)到TeacherDetailActivity的IntentIntent intent = new Intent(getContext(), TeacherDetailActivity.class);// 準備跳轉(zhuǎn)getContext().startActivity(intent);}});增加兩行代碼就能跳轉(zhuǎn)到第二個Activity了。但是運行起來之后,在第二個Activity中我們并沒有看到數(shù)據(jù)。所以讓我們來做最后一步吧,你馬上就要成功了。
在進行跳轉(zhuǎn)的時候,我們需要把老師的數(shù)據(jù)傳遞給TeacherDetailActivity,并在TeacherDetailActivity中進行適當?shù)脑O(shè)置。
通過Intent傳遞參數(shù)
設(shè)置Intent的Extra數(shù)據(jù)
Intent的putExtra方法就是用來傳遞參數(shù)的,我們只需在初始化Intent對象之后把老師的數(shù)據(jù)傳遞進去即可。
需要注意的一點是,為了訪問teacher變量,需要在申明的時候加上final修飾符。注意代碼中哪些地方發(fā)生了變化,完整的代碼如下:
package com.zhihuishu.innovationcourse;import android.content.Context; import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView;import java.util.List;public class TeacherAdapter extends ArrayAdapter<Teacher> {public TeacherAdapter(Context context, int resource, List<Teacher> objects) {super(context, resource, objects);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// 獲取老師的數(shù)據(jù)final Teacher teacher = getItem(position);// 創(chuàng)建布局View oneTeacherView = LayoutInflater.from(getContext()).inflate(R.layout.teacher_item, parent, false);// 獲取布局中的ImageView和TextViewImageView imageView = (ImageView) oneTeacherView.findViewById(R.id.teacher_small_imageView);TextView textView = (TextView) oneTeacherView.findViewById(R.id.teacher_name_textView);// 根據(jù)老師數(shù)據(jù)設(shè)置ImageView和TextView的展現(xiàn)imageView.setImageResource(teacher.getImageId());textView.setText(teacher.getName());oneTeacherView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 初始化一個準備跳轉(zhuǎn)到TeacherDetailActivity的Intent Intent intent = new Intent(getContext(), TeacherDetailActivity.class);// 往Intent中傳入Teacher相關(guān)的數(shù)據(jù),供TeacherDetailActivity使用intent.putExtra("teacher_image", teacher.getImageId());intent.putExtra("teacher_desc", teacher.getDesc());// 初始化一個準備跳轉(zhuǎn)到TeacherDetailActivity的IntentgetContext().startActivity(intent);}});return oneTeacherView;} }根據(jù)Intent數(shù)據(jù)展示內(nèi)容
最后我們修改TeacherDetailActivity的onCreate()方法,加入從Intent獲取數(shù)據(jù)并設(shè)置視圖展現(xiàn)的代碼。
package com.zhihuishu.innovationcourse;import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.widget.ImageView; import android.widget.TextView;public class TeacherDetailActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_teacher_detail);// 從Intent獲取數(shù)據(jù)int imageId = getIntent().getIntExtra("teacher_name", 0);String desc = getIntent().getStringExtra("teacher_desc");// 獲取特定的視圖ImageView imageView = (ImageView) findViewById(R.id.teacher_large_imageView);TextView textView = (TextView) findViewById(R.id.teacher_desc_textView);// 根據(jù)數(shù)據(jù)設(shè)置視圖展現(xiàn)imageView.setImageResource(imageId);textView.setText(desc);}}注意int imageId = getIntent().getIntExtra("teacher_image", 0);語句中傳入的屬性名teacher_image一定要寫對,和putExtra()方法中的保持一致。通常我們是通過定義常量的方式來定義這樣的字符串名字,這里為了簡單處理我們用了硬編碼的方式。
好了,運行起來看看吧,跳轉(zhuǎn)沒有問題了,恭喜你,整個APP已經(jīng)搞定了!
版權(quán)聲明
本文由David創(chuàng)作,轉(zhuǎn)載需署名作者且注明文章出處
參考代碼
要獲取本文的參考代碼,請訪問:?https://www.tianmaying.com/tutorial/a-simple-sample-for-android-development/repo
from:?https://www.tianmaying.com/tutorial/a-simple-sample-for-android-development?
總結(jié)
以上是生活随笔為你收集整理的Android开发入门经典实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017 Vue.js 2快速入门指南
- 下一篇: Android开发如何进阶?