課程 1: JSON 解析

結(jié)束 Android 開發(fā)(入門)課程 的第二部分《多屏幕應(yīng)用》后店乐,來到第三部分《訪問網(wǎng)絡(luò)》橄教,這部分課程要完成一個(gè)名為 Quake Report 的應(yīng)用橄维,這個(gè)應(yīng)用從網(wǎng)絡(luò)獲取數(shù)據(jù)枣接,列出全球范圍內(nèi)最近發(fā)生的地震信息,包括時(shí)間硕旗、地點(diǎn)窗骑、震級(jí)。

Quake Report App 分三節(jié)課完成漆枚,每個(gè)課程的進(jìn)度分配如下:

  1. JSON Parsing
    從 USGS API 請(qǐng)求數(shù)據(jù)创译,了解返回的數(shù)據(jù)結(jié)構(gòu),并提取數(shù)據(jù)墙基。
  2. HTTP Networking
    將數(shù)據(jù)輸入 App软族,涉及 Android 權(quán)限辛藻、后臺(tái)線程等內(nèi)容。
  3. Threads & Parallelism
    了解 HTTP 請(qǐng)求的端對(duì)端路徑互订,實(shí)時(shí)更新數(shù)據(jù),并顯示出來痘拆。

這是第三部分《訪問網(wǎng)絡(luò)》的第一節(jié)課仰禽,導(dǎo)師是 Chris Lei 和 Joe Lewis。這節(jié)課的重點(diǎn)是解析 API 返回的 HTTP 響應(yīng)中包含的 JSON纺蛆。因?yàn)榇饲罢n程都沒有涉及網(wǎng)絡(luò)訪問的內(nèi)容吐葵,所以這節(jié)課會(huì)循序漸進(jìn)地介紹相關(guān)知識(shí)。首先了解 USGS API桥氏,再在導(dǎo)入已有代碼后通過 Java 提取和格式化元數(shù)據(jù)温峭,然后暫時(shí)通過 JSON 響應(yīng)示例作為占位符數(shù)據(jù),最后優(yōu)化布局字支。

關(guān)鍵詞:API凤藏、JSON、Key/Value Pair堕伪、Traversal Path揖庄、JSONObject、Utility class欠雌、SimpleDateFormat蹄梢、String.split、DecimalFormat富俄、drawable.shape禁炒、GradientDrawable、ContextCompat.getColor霍比、switch Statement幕袱、Math.floor

USGS API

Quake Report App 要從網(wǎng)絡(luò)獲取地震數(shù)據(jù),那么就要用到 API桂塞。API(應(yīng)用程序編程接口凹蜂,Application Programming Interface)是一個(gè)軟件產(chǎn)品或服務(wù)將其一部分功能或數(shù)據(jù)提供給其它軟件使用的一種方法,API 的提供者和使用者互相形成一種編程合作關(guān)系 (Programming Partnership)阁危,相互創(chuàng)造出更大的價(jià)值玛痊。針對(duì)地震數(shù)據(jù)的 API,Google 搜索 "earthquake api" 可以找到 USGS(美國(guó)地質(zhì)勘探局狂打,U. S. Geological Survey)網(wǎng)站提供相應(yīng)的技術(shù)支持擂煞。點(diǎn)擊 "For Developers" 目錄下的 "API Documentation" 可以看到,USGS API 支持通過 URL 請(qǐng)求數(shù)據(jù)趴乡,格式如下:

https://earthquake.usgs.gov/fdsnws/event/1/[METHOD][?[PARAMETERS]]

在這里 URL 可分為三部分:

  1. 頭部 https://earthquake.usgs.gov/fdsnws/event/1/对省,固定不變蝗拿。
  2. 按照不同數(shù)據(jù)需求接上 METHOD,支持 catalogs蒿涎、count哀托、query 等。Quake Report App 要獲取地震信息劳秋,所以這里用到 query仓手。
  3. 最后添加參數(shù) ?[PARAMETERS],支持?jǐn)?shù)據(jù)格式玻淑、時(shí)間嗽冒、震級(jí)等。參數(shù)無需用 [] 包括补履,第一個(gè)參數(shù)前用 ? 連接添坊,參數(shù)之間用 & 連接。

例如要獲取 2014 年 1 月 1 日至 2014 年 1 月 2日之間震級(jí)大于五級(jí)的地震數(shù)據(jù)箫锤,并以 GeoJSON 格式返回?cái)?shù)據(jù)贬蛙,那么向 USGS API 請(qǐng)求數(shù)據(jù)的 URL 如下:

https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2014-01-01&endtime=2014-01-02&minmagnitude=5
  1. methodquery,后面用 ? 連接參數(shù)谚攒。
  2. parameters 有四個(gè)速客,相互之間用 & 連接,參數(shù)分別為
    (1)format=geojson 指定數(shù)據(jù)以 GeoJSON 格式返回五鲫;
    (2)starttime=2014-01-01 指定數(shù)據(jù)開始時(shí)間為 2014 年 1 月 1 日溺职;
    (3)endtime=2014-01-02 指定數(shù)據(jù)截止時(shí)間為 2014 年 1 月 2日;
    (4)minmagnitude=5 指定數(shù)據(jù)的震級(jí)為五級(jí)以上位喂。

API 返回的 GeoJSON 數(shù)據(jù) 沒有可讀性浪耘,可以復(fù)制到 JSON Pretty Print 網(wǎng)站 格式化后查看。例如 "time" 是用 Unix 時(shí)間戳(從 1970 年 1 月 1 日零時(shí)開始所經(jīng)過的毫秒數(shù)塑崖,整數(shù)七冲,便于時(shí)間計(jì)算,詳細(xì)信息可以觀看這個(gè) YouTube 視頻)的形式記錄规婆,表示地震發(fā)生的時(shí)間澜躺;"felt" 表示 USGS 網(wǎng)站用戶反饋的震感;"tsunami" 是一個(gè)布爾類型數(shù)據(jù)抒蚜,表示地震是否觸發(fā)海嘯預(yù)警掘鄙;"title" 是包含震級(jí)和震源地的英文字符;"coordinates" 是一個(gè)三維數(shù)據(jù)嗡髓,包含震源的經(jīng)度操漠、緯度、深度饿这。

JSON

事實(shí)上浊伙,USGS API 支持多種格式的響應(yīng)數(shù)據(jù)撞秋,包括 CSV、XML嚣鄙、GeoJSON 等吻贿,這里選擇 GeoJSON 并不意味著它是最好的,而是因?yàn)?JSON 是現(xiàn)今許多簽名 Web 服務(wù)中最常用的響應(yīng)格式哑子,GeoJSON 則是 JSON 的一種特殊風(fēng)格廓八,定制用于表示地理信息。對(duì)于開發(fā)者而言赵抢,擁有使用 JSON 的經(jīng)驗(yàn)后,其它格式也能快速上手声功。

JSON 的全稱是 JavaScript Object Notation烦却,但其實(shí)它與 Javascript 語言并不相關(guān),名稱用 JS 開頭是因?yàn)樽畛踉O(shè)計(jì)時(shí)為了促進(jìn) Web 的有效溝通先巴。實(shí)際上 JSON 是組織數(shù)據(jù)的一種策略型規(guī)則其爵,它是獨(dú)立的數(shù)據(jù)交換格式,可以使用任何語言解析伸蚯,例如 Android 用到的 Java 語言摩渺。

JSON 結(jié)構(gòu)

1   {
2       "size" : 9.5,
3       "wide" : true,
4       "country-of-origin" : "usa",
5       "style" : {
6           "categories" : [ "boot", "winklepicker" ],
7           "color" : "black"
8       }
9   }

上面是一段簡(jiǎn)單的 JSON 示例剂邮,雖然 JSON 采用完全獨(dú)立于語言的文本格式摇幻,但是也使用了類似于 C 語言家族 (C++, Java, Python) 的習(xí)慣,包括字符串挥萌、對(duì)象绰姻、數(shù)組等。

  1. 第 2引瀑、3狂芋、4、7 行的格式相同憨栽,稱為鍵/值對(duì) (Key/Value Pair)帜矾。
    (1)冒號(hào) : 左側(cè)的是鍵 (Key),由 "" 包括屑柔,表示一類數(shù)據(jù)的名稱屡萤。
    (2)冒號(hào) : 右側(cè)的是值 (Value),表示一類數(shù)據(jù)的值掸宛,可以是數(shù)值灭衷、布爾類型、字符串旁涤、數(shù)組翔曲、對(duì)象等迫像。其中字符串由 "" 包括,使用 \ 轉(zhuǎn)義瞳遍。
    (3)鍵/值對(duì)之間用 , 分隔闻妓。
  2. 第 6 行的鍵/值對(duì),鍵是 categories掠械,值是一個(gè)數(shù)組由缆,由 [] 包括,元素之間用 , 分隔猾蒂。
  3. 第 5 行的鍵/值對(duì)均唉,鍵是 style,值是一個(gè)對(duì)象肚菠,由 {} 包括舔箭。對(duì)象是鍵/值對(duì)的集合,這里是 categoriescolor 兩個(gè)鍵/值對(duì)的集合蚊逢,這就形成了嵌套結(jié)構(gòu)层扶。
  4. 整個(gè) JSON 文件由 {} 包括,所以一個(gè) JSON 就是一個(gè)對(duì)象烙荷,名稱常用 root 表示镜会。

詳細(xì)的 JSON 結(jié)構(gòu)介紹可以到官網(wǎng)查看。

JSON 對(duì)象樹

JSON 存在嵌套結(jié)構(gòu)终抽,也就產(chǎn)生了 JSON 對(duì)象樹戳表,要訪問其中的節(jié)點(diǎn),就有了遍歷路徑 (Traversal Path) 的概念昼伴。例如要訪問上面的 JSON 示例中的第一個(gè) categories 元素扒袖,遍歷路徑如下:

Root > JSONObject with key "style" > JSONArray with key "categories" >  Look for the first element in the array

JSON 對(duì)象樹節(jié)點(diǎn)的遍歷路徑對(duì)解析 JSON 至關(guān)重要,它的作用與之前提到的偽代碼 (Pseudo code) 的作用類似亩码,幫助開發(fā)者理清編程思路季率。復(fù)雜的 JSON 文件可以復(fù)制到 JSON Formatter 網(wǎng)站 格式化后,選擇折疊或展開節(jié)點(diǎn)查看描沟。

在 Android 中解析 JSON

// Create a JSONObject from the SAMPLE_JSON_RESPONSE string
JSONObject baseJsonResponse = new JSONObject(SAMPLE_JSON_RESPONSE);

// Extract the JSONArray associated with the key called "features",
// which represents a list of features (or earthquakes).
JSONArray earthquakeArray = baseJsonResponse.getJSONArray("features");

// For each earthquake in the earthquakeArray, create an {@link Earthquake} object
for (int i = 0; i < earthquakeArray.length(); i++) {
    // Get a single earthquake at position i within the list of earthquakes
    JSONObject currentEarthquake = earthquakeArray.getJSONObject(i);
    // For a given earthquake, extract the JSONObject associated with the
    // key called "properties", which represents a list of all properties
    // for that earthquake.
    JSONObject properties = currentEarthquake.getJSONObject("properties");
    // Extract the value for the key called "mag"
    double magnitude = properties.getDouble("mag");
    // Extract the value for the key called "place"
    String location = properties.getString("place");
    // Extract the value for the key called "time"
    long time = properties.getLong("time");
    // Extract the value for the key called "url"
    String url = properties.getString("url");

    // Add the new {@link Earthquake} to the list of earthquakes.
    earthquakes.add(new Earthquake(magnitude, location, time, url));
}

Android 提供了強(qiáng)大的 JSONObject class 用于解析 JSON飒泻,在了解遍歷路徑后通過豐富的 getter method 即可靈活處理 JSON。

  1. 解析 JSON 的代碼放在一個(gè) Utility class 內(nèi)吏廉,該類的構(gòu)造函數(shù)為 private泞遗,表示不應(yīng)該創(chuàng)建 Utility 對(duì)象,因?yàn)?Utility class 只用于存放靜態(tài)變量 (static variable) 和 static method席覆,它們可以直接用類名訪問史辙,無需實(shí)例化。
  2. 這節(jié)課先驗(yàn)證 JSON 解析,利用 JSONObject(String json) 構(gòu)造函數(shù)傳入一個(gè)占位符數(shù)據(jù)聊倔,新建 JSONObject 對(duì)象晦毙,名為 baseJsonResponse,對(duì)應(yīng)的 JSON 對(duì)象樹節(jié)點(diǎn)為 Root耙蔑。
  3. 針對(duì) Quake Report App 需要的震級(jí)见妒、地點(diǎn)、時(shí)間甸陌、URL 信息须揣,按照遍歷路徑通過相應(yīng)的 getter method 獲取數(shù)據(jù)。
    (1)通過 getJSONArray 獲取 Root 內(nèi)鍵為 features 的數(shù)組钱豁;
    (2)通過 length() 獲取 features 數(shù)組的長(zhǎng)度耻卡;
    (3)通過 getJSONObject 獲取 features 數(shù)組的元素 currentEarthquake 對(duì)象;
    (4)通過 getJSONObject 獲取 currentEarthquake 對(duì)象內(nèi)的元素 properties 對(duì)象牲尺;
    (5)通過 getDouble 獲取 properties 對(duì)象內(nèi)的元素 mag double 數(shù)值卵酪;
    (6)通過 getString 獲取 properties 對(duì)象內(nèi)的元素 place 字符串;
    (7)通過 getLong 獲取 properties 對(duì)象內(nèi)的元素 time long 數(shù)值秸谢;
    (8)通過 getString 獲取 properties 對(duì)象內(nèi)的元素 url 字符串;
  4. 上述 getter method 在傳入不存在的鍵時(shí)會(huì)產(chǎn)生 JSONException 錯(cuò)誤霹肝,這里可以使用對(duì)應(yīng)的 opt method 代替估蹄,例如 optString(String name) 在傳入不存在的字符串時(shí)會(huì)返回一個(gè)空的字符串,optInt(String name) 在傳入無法轉(zhuǎn)換為 int 的數(shù)據(jù)時(shí)會(huì)返回 0沫换。

更多 JSONObject 的信息可以參考這個(gè)入門教程臭蚁。

功能實(shí)現(xiàn)和布局優(yōu)化

設(shè)計(jì)師提供的應(yīng)用 UI 原型,開發(fā)者要編程實(shí)現(xiàn)讯赏,雙方合作設(shè)計(jì)出殺手級(jí)的用戶體驗(yàn) (Designing a killer user experience)垮兑。如果沒有設(shè)計(jì)師也沒有關(guān)系,多花點(diǎn)時(shí)間按照 Material Design 設(shè)計(jì)也可以寫出優(yōu)秀的應(yīng)用漱挎。

  1. 顯示可讀的時(shí)間和日期

由于 USGS API 返回的地震發(fā)生時(shí)間數(shù)據(jù)是以 Unix 時(shí)間的形式記錄的系枪,在應(yīng)用中要顯示成可讀的時(shí)間和日期。Android 提供了神奇的 SimpleDateFormat class 來處理這個(gè)問題:將 Unix 時(shí)間傳入 Date 對(duì)象磕谅,新建 SimpleDateFormat 對(duì)象并指定所需的時(shí)間格式私爷,最后調(diào)用 SimpleDateFormat.format method 就實(shí)現(xiàn)了時(shí)間的格式化。

// The time in milliseconds of the earthquake.
long timeInMilliseconds = 1454124312220L;
// Create a new Date object from the time in milliseconds of the earthquake.
Date dateObject = new Date(timeInMilliseconds);
// Create a new SimpleDateFormat object by assigning the format of the date.
SimpleDateFormat dateFormatter = new SimpleDateFormat("MMM DD, yyyy");
// Get the formatted date string (i.e. "Mar 3, 1984") from a Date object.
String dateToDisplay = dateFormatter.format(dateObject);

在 SimpleDateFormat 中膊夹,時(shí)間格式通過字符表示:

Letter Date or Time Component Example
y Year 1996; 96
M Month in year (context sensitive) July; Jul; 07
D Day in year 189
d Day in month 7
H Hour in day (0-23) 0
m Minute in hour 30
s Second in minute 55
S Millisecond 978

完整表格可以到 Android Developers 網(wǎng)站查看衬浑。

(1)區(qū)分大小寫,例如 D 表示一年中的天數(shù)放刨,d 表示一月中的天數(shù)工秩。
(2)一個(gè)字符僅表示一位數(shù)字,例如 1996 年在 yyyy 時(shí)顯示 1996,在 yy 時(shí)顯示 96助币。
(2)所有未在特殊字符表中列出的字符都將在輸出字符串中直接顯示浪听。例如,如果時(shí)間格式字符串包含 :-,奠支,則輸出字符串也將在相應(yīng)位置直接包含相同的標(biāo)點(diǎn)符號(hào)馋辈。

  1. 操控字符串

在 Quake Report App 中,需要將 USGS API 返回的地點(diǎn)數(shù)據(jù)分成兩部分顯示倍谜,第一行顯示地震與城市之間的距離迈螟,第二行指定具體的城市。

// Get the original location string from the Earthquake object,
// which can be in the format of "5km N of Cairo, Egypt" or "Pacific-Antarctic Ridge".
String originalLocation = currentEarthquake.getLocation();

// If the original location string (i.e. "5km N of Cairo, Egypt") contains
// a primary location (Cairo, Egypt) and a location offset (5km N of that city)
// then store the primary location separately from the location offset in 2 Strings,
// so they can be displayed in 2 TextViews.
String primaryLocation;
String locationOffset;

// Check whether the originalLocation string contains the " of " text
if (originalLocation.contains(LOCATION_SEPARATOR)) {
    // Split the string into different parts (as an array of Strings)
    // based on the " of " text. We expect an array of 2 Strings, where
    // the first String will be "5km N" and the second String will be "Cairo, Egypt".
    String[] parts = originalLocation.split(LOCATION_SEPARATOR);
    // Location offset should be "5km N " + " of " --> "5km N of"
    locationOffset = parts[0] + LOCATION_SEPARATOR;
    // Primary location should be "Cairo, Egypt"
    primaryLocation = parts[1];
} else {
    // Otherwise, there is no " of " text in the originalLocation string.
    // Hence, set the default location offset to say "Near the".
    locationOffset = getContext().getString(R.string.near_the);
    // The primary location will be the full location string "Pacific-Antarctic Ridge".
    primaryLocation = originalLocation;
}

(1)通過 contains(CharSequence cs) 判斷字符串是否包含指定的字符尔崔,其中由于 String 是 CharSequence 的擴(kuò)展類答毫,所以這里 CharSequence 作為輸入?yún)?shù)時(shí),可以傳入 String季春。
(2)通過 split(String string) 根據(jù)輸入?yún)?shù)指定的位置對(duì)字符串進(jìn)行拆分洗搂,返回值為拆分后的字符串?dāng)?shù)組。拆分后的字符串與輸入?yún)?shù)的匹配次數(shù)和位置有關(guān)载弄,不包含輸入?yún)?shù)字符耘拇,詳細(xì)信息可以到 Android Developers 網(wǎng)站查看。
(3)除了上述操縱字符串的 method宇攻,另外幾個(gè)常用的有 length() 獲取字符串的字符數(shù)量惫叛,indexOf(String string) 返回輸入?yún)?shù)首次在字符串匹配的位置索引,substring(int start, int end) 根據(jù)輸入?yún)?shù)指定的起止位置對(duì)字符串進(jìn)行裁剪逞刷,包括開始索引但不包括結(jié)束索引嘉涌。

  1. 數(shù)字對(duì)齊

在 Quake Report App 中,需要將震級(jí)數(shù)字保留一位小數(shù)顯示夸浅,所以要格式化數(shù)字仑最。與格式化時(shí)間類似,Android 提供了 DecimalFormat class 來處理這個(gè)問題帆喇。NumberFormat class 也可用于處理所有類型數(shù)字的格式警医,但它是一個(gè)抽象類, 而 DecimalFormat 是一個(gè)具象類坯钦,因此 DecimalFormat 相對(duì)而言比較簡(jiǎn)單法严,特別是對(duì)于這種簡(jiǎn)單的數(shù)字格式化需求。

// Get the magnitude from Earthquake object.
double magnitude = currentEarthquake.getMagnitude();
// Create a new DecimalFormat object by assigning the format of the digit.
DecimalFormat formatter = new DecimalFormat("0.0");
// Get the formatted magnitude digit.
String formattedMagnitude = formatter.format(magnitude);

與 SimpleDateFormat 類似葫笼,在 DecimalFormat 中深啤,數(shù)字格式通過字符表示:

Symbol Location Meaning
0 Number Digit(數(shù)字的占位符)
# Number Digit, zero shows as absent(數(shù)字,但不顯示前導(dǎo)零)
. Number Decimal separator or monetary decimal separator
% Prefix or suffix Multiply by 100 and show as percentage

完整表格可以到 Android Developers 網(wǎng)站查看路星。

  1. 圓形背景

為 Quake Report App 的 magnitude TextView 添加圓形背景溯街,由于背景顏色需要根據(jù)震級(jí)大小變化诱桂,所以在這里沒有添加多個(gè)不同顏色的圖像資源,而是通過在 XML 中定義圓圈形狀呈昔,然后在 Java 中對(duì)顏色進(jìn)行操作的方法實(shí)現(xiàn)挥等,減少所需的資源數(shù)量。

(1)在 res/drawable 目錄下添加 New > Drawable resource file

In magnitude_circle.xml

<!-- Background circle for the magnitude value -->
<shape 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/magnitude1" />
    <size
        android:width="36dp"
        android:height="36dp" />
    <corners android:radius="18dp" />
</shape>

android:shape 屬性設(shè)置為 oval(橢圓形)堤尾,寬度肝劲、高度、轉(zhuǎn)角半徑三者配合好郭宝,畫出一個(gè)半徑為 18dp 的圓形辞槐。

(2)在 magnitude TextView 中應(yīng)用 magnitude_circle.xml

android:background="@drawable/magnitude_circle"

(3)在 Java 中操作背景顏色

// Fetch the background from the TextView, which is a GradientDrawable.
GradientDrawable magnitudeCircle = (GradientDrawable) magnitudeView.getBackground();
// Get the appropriate background color based on the current earthquake magnitude
int magnitudeColor = getMagnitudeColor(currentEarthquake.getMagnitude());
//  Set the color on the magnitude circle
magnitudeCircle.setColor(magnitudeColor);

這里新建了一個(gè) GradientDrawable 對(duì)象,指向 magnitude TextView 的背景粘室,最終通過 setColor method 來改變背景顏色榄檬。中間是一個(gè)輔助 method,根據(jù)當(dāng)前的地震震級(jí)返回正確的顏色值衔统,代碼如下:

/**
 * Return the color for the magnitude circle based on the intensity of the earthquake.
 *
 * @param magnitude of the earthquake
 */
private int getMagnitudeColor(double magnitude) {
    int magnitudeColorResourceId;
    int magnitudeFloor = (int) Math.floor(magnitude);
    switch (magnitudeFloor) {
        case 0:
        case 1:
            magnitudeColorResourceId = R.color.magnitude1;
            break;
        case 2:
            magnitudeColorResourceId = R.color.magnitude2;
            break;
        case 3:
            magnitudeColorResourceId = R.color.magnitude3;
            break;
        case 4:
            magnitudeColorResourceId = R.color.magnitude4;
            break;
        case 5:
            magnitudeColorResourceId = R.color.magnitude5;
            break;
        case 6:
            magnitudeColorResourceId = R.color.magnitude6;
            break;
        case 7:
            magnitudeColorResourceId = R.color.magnitude7;
            break;
        case 8:
            magnitudeColorResourceId = R.color.magnitude8;
            break;
        case 9:
            magnitudeColorResourceId = R.color.magnitude9;
            break;
        default:
            magnitudeColorResourceId = R.color.magnitude10plus;
            break;
    }

    return ContextCompat.getColor(getContext(), magnitudeColorResourceId);
}

(1)由于 GradientDrawable 的 setColor method 需要傳入 int argb鹿榜,而不是顏色資源的 ID,所以這里需要轉(zhuǎn)換一下锦爵,用到 ContextCompat.getColor method舱殿。

(2)由于震級(jí)數(shù)值是非布爾類型的離散值,所以這里引入一種新的 switch 流控語句险掀,它可以替代 if-else 的多級(jí)嵌套沪袭,免除每一層都需要判斷變量值的重復(fù)工作。

  • switch 語句涉及了許多 Java 關(guān)鍵字迷郑,如 switch枝恋、case创倔、break嗡害、default
  • switch 后的 () 內(nèi)傳入需要執(zhí)行的參數(shù)畦攘,隨后在 {} 內(nèi)從上至下尋找 case 后匹配的數(shù)據(jù)霸妹,若輸入?yún)?shù)匹配其中一個(gè) case 后的數(shù)據(jù),則運(yùn)行 : 下的代碼知押,直到運(yùn)行至 break;叹螟。
  • 如果 switch 的輸入?yún)?shù)沒有匹配任何 case 后的數(shù)據(jù),那么代碼會(huì)運(yùn)行 default: 下的代碼台盯。雖然 default 代碼不是強(qiáng)制的罢绽,但是為了增加代碼的魯棒性,通常都會(huì)寫在 switch 語句的最后静盅。
  • 如果 case 下的代碼沒有 break;良价,那么代碼會(huì)運(yùn)行到下一個(gè) case,直到運(yùn)行至 break;。因此明垢,這種形式的代碼實(shí)際上形成了一種或邏輯蚣常,例如上述一段代碼的邏輯是,如果 magnitudeFloor 為 0 或 1痊银,那么 magnitudeColorResourceId 賦為 R.color.magnitude1抵蚊,然后跳出 switch 語句。

(3)由于 switch 語句無法輸入 double 數(shù)值溯革,所以這里需要震級(jí)值轉(zhuǎn)換為 int贞绳,用到 Math.floor 將震級(jí)值的小數(shù)部分抹平。

  1. 布局優(yōu)化

如果要隱藏 ListView 項(xiàng)目間的分隔線鬓照,可以在 XML 中設(shè)置以下兩個(gè)屬性:

android:divider="@null"
android:dividerHeight="0dp"

設(shè)置 TextView 的 ellipsizemaxLines 兩個(gè)屬性表示:如果 TextView 中的文本長(zhǎng)度超過兩行熔酷,就可以在文本結(jié)尾處中添加省略號(hào) ("..."),而不是隨內(nèi)容增加行數(shù)豺裆。

android:ellipsize="end"
android:maxLines="2"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拒秘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子臭猜,更是在濱河造成了極大的恐慌躺酒,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔑歌,死亡現(xiàn)場(chǎng)離奇詭異羹应,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)次屠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門园匹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人劫灶,你說我怎么就攤上這事裸违。” “怎么了本昏?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵供汛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我涌穆,道長(zhǎng)怔昨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任宿稀,我火速辦了婚禮趁舀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祝沸。我一直安慰自己矮烹,他們只是感情好巡蘸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著擂送,像睡著了一般悦荒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘹吨,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天搬味,我揣著相機(jī)與錄音,去河邊找鬼蟀拷。 笑死碰纬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的问芬。 我是一名探鬼主播悦析,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼此衅!你這毒婦竟也來了强戴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤挡鞍,失蹤者是張志新(化名)和其女友劉穎骑歹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墨微,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡道媚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翘县。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片最域。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖锈麸,靈堂內(nèi)的尸體忽然破棺而出镀脂,到底是詐尸還是另有隱情,我是刑警寧澤掐隐,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布狗热,位于F島的核電站钞馁,受9級(jí)特大地震影響虑省,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜僧凰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一探颈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧训措,春花似錦伪节、人聲如沸光羞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纱兑。三九已至,卻和暖如春化借,著一層夾襖步出監(jiān)牢的瞬間潜慎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工蓖康, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铐炫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓蒜焊,卻偏偏與公主長(zhǎng)得像倒信,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泳梆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345