文章目錄
- 概述
- Miwok應用構建
- 應用概述
- 添加Activity
- OnClickListener
- 修改Activity顯示的名稱
- 視圖回收
- LinearLayout 和 TextView
- ListView 和 ArrayAdapeter
- 記憶體性能分析器使用
- 總結
- 參考
概述
今日學習內容如下:
- 了解 Miwok 語言應用的結構,在該應用中創建多屏,并使用 Intents 將多個 Activity 連接起來,
- 視圖回收
- 使用 LinearLayout 和 TextView 展示資料
- 改用 ListView 和 ArrayAdapeter 展示資料
- Memory Profiler 使用
- ……
Miwok應用構建
應用概述
Miwok 是一個用來學習 Miwok語言的應用,應用打開后應該有四個可選的類別,分別為Numbers、Family Members、Colors、Phrases,當點擊任意一個類別所在的區域時,將跳轉到該類別所在的頁面,
結構大概像下面這樣:

添加Activity
分別為四個類別新建 Activity,滑鼠右擊 --> New --> Activity --> EmptyActivity

在首頁中為每個類別創建選項,這里使用 LinearLayout 和 TextView:

OnClickListener
現在需要,當在首頁點擊某個類別時跳轉到該類別所在的頁面,這就需要監聽 視圖的 Onclick事件,而監聽事件需要用到監聽器,官方已經定義好了事件的監聽器,
下面直接使用,在首頁原始碼(MainActivity)的 OnCreate 方法方法中添加:
// Find the View that show the number category
TextView numbers = (TextView) findViewById(R.id.numbers);
// Set a clickListener on that View
numbers.setOnClickListener(new View.OnClickListener() {
// …………
});
首先使用 findViewById(R.id.numbers) 獲取到了 Numbers 類別的視圖,然后呼叫 numbers.setOnClickListener() 方法為視圖設定 OnClick 事件的監聽器,它接收 一個 OnClickListener 的實體,
監聽器是一個 interface(介面),因此我們需要按照介面中預定義的來實作這個介面,單擊事件監聽器 OnClickListener 介面中只包含一個方法 void onClick(View v);,因此單擊跳轉 Activity 的代碼如下:
numbers.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when the family category is clicked on.
@Override
public void onClick(View view) {
// Create a new intent to open the {@link NumbersActivity}
Intent numbersIntent = new Intent(MainActivity.this, NumbersActivity.class);
// Start the new activity
startActivity(numbersIntent);
}
});
首先在 OnClickListener 的實作類中 重寫 onClick 方法,并在里面定義視圖單擊時需要執行的操作,
onClick 方法中一共兩行代碼,第一行創建了一個 Intent 實體,傳入兩個引數 背景關系環境 Context 和 目標Activity(這是一個顯式的 Intent),表示將要跳轉到 NumbersActivity 頁面;第二行代碼 則啟動這個 Intent 實體,執行真實的 跳轉操作,
四個類別的頁面跳轉也是一樣的,分別創建并設定 單擊事件的監聽器并 使用 Intent 讓其跳轉套不同的 頁面即可,代碼省略…………,
修改Activity顯示的名稱
有一個問題,在創建 Miwok 專案時指定 App Name 為 Miwok,而沒有為每個Activity定義 顯示的名稱,所以默認采用了應用的名稱,在 AndroidManifest.xml 中:

想要自定義 Activity 的名稱,可以更改 activity 標簽中的屬性來實作,如 指定 label 屬性的值即可更改相應的 Activity 顯示的名稱

視圖回收
LinearLayout 和 TextView
在 Numbers 頁面中需要顯示 1 到 10 的語言串列,因此考慮使用 線性布局 加 TextView 來實作:
在 Numbers 頁面的布局檔案中定義一個 id 為 rootView 的 LinearLayout,它將用于垂直排列 1 到 10 的 TextView
<?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:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".NumbersActivity" />
在 Numbers 頁面的 OnCreate 方法中 填加代碼 實作,先通過 findViewById 方法獲取到根視圖LinearLayout的實體,然后 創建一個 TextView 實體傳入 this (當前Activity)作為背景關系并設定 Text,最后呼叫根視圖的 addView 方法將 TextView 添加進去,回圈10次就添加了10個數字,
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_numbers);
LinearLayout root = (LinearLayout) findViewById(R.id.rootView);
for (int i = 0; i < 10; i++) {
TextView t = new TextView(this);
t.setText("" + i);
root.addView(t);
}
}
采用這種方法,如果有 幾千個數字要顯示,則要回圈 幾千次,在手機里創建幾千個TextView并渲染在手機螢屏上,這會占用較大的記憶體空間,因為手機螢屏能顯示的TextView可能只有幾個或十多個,這取決于 TextView的高寬,
設備的記憶體資源 是有限的,
ListView 和 ArrayAdapeter
LinearLayout + TextView 的會造成資源的浪費,
ListView 和 ArrayAdapeter 則不會,ArrayAdapeter是一個配接器 ,用于管理 視圖和 資料,
假如在手機螢屏中可以顯示 10 條 TextView ,而我們有 10000 個 數字需要顯示,用戶在滑動螢屏查看更多的數字時(上面的數字會移出螢屏,下面的數字會進入排列),配接器就會回收 移出數字的視圖資源,并將改視圖資源用于顯示新進入的數字,
代碼:
Numbers 的 xml 布局檔案:
<?xml version="1.0" encoding="utf-8"?>
<ListView 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:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".NumbersActivity" />
Numbers 頁面 的 onCreate 函式:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_numbers);
// Create a array list of words
ArrayList<String> words = new ArrayList<String>();
for (int i = 0; i < 10000; i++) {
words.add("" + i);
}
// Create a ArrayAdapter
ArrayAdapter<String> itemsAdapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, words);
// Get layout instance
ListView listLayout = (ListView) findViewById(R.id.list);
// Set adapter for the layout instance
listLayout.setAdapter(itemsAdapter);
}
- 首先創建了一個包含了 10000 個數字的 串列作為資料來源
- 創建一個 ArrayAdapter 用于管理字串資料(這里是泛型),
this引數指定背景關系,android.R.layout.simple_list_item_1是Android中一個串列項布局,words指定資料來源 findViewById(R.id.list)獲取根視圖 ListView 的實體listLayout.setAdapter(itemsAdapter)為 根視圖系結配接器
這樣配接器就可以管理 視圖視圖 和 資料來源了,
最后一步的 listLayout.setAdapter(itemsAdapter); 比較復雜,ListView 定義的 設定配接器方法為 public void setAdapter(ListAdapter adapter) 要求接收一個 ListAdapter 物件,而最終轉入的卻是 ArrayAdapter 物件,
原因是:
ArrayAdapter 繼承自 抽象類 BaseAdapter ,BaseAdapter 實作了 ListAdapter 介面,所以 ArrayAdapter 也是 ListAdapter的實作,
運行效果,圖片大,只截部分,:
橫線是 android.R.layout.simple_list_item_1 的布局樣式

記憶體性能分析器使用
在 Android Studio 的工具列中 View --> Tool Windows --> Profiler ,即可打開 Profiler,它顯示一個應用記憶體使用量的實時圖表,讓您可以捕獲堆轉儲、強制執行垃圾回收以及跟蹤記憶體分配,
使用 Memory Profiler 對比 視圖回收中,兩種方法 在頁面顯示 1000 個數字的記憶體消耗情況:

LinearLouyout + TextView 的方式大概占用了 18mb 的記憶體 資源,ListView + ArrayAdapter 的方式則消耗了 8mb 資源,只使用到了前者的一半不到,
如果有更多的內容需要顯示,兩者的 記憶體消耗會更加明顯;比如在微博 App 的首頁用戶可以一直往下刷,查看 幾千上萬條 動態 ,就使用到了 視圖回收的機制,
并且 LinearLouyout 要想在螢屏中滾動查看更多內容,需要配合 ScrollView 實作;而 ListView 默認支持在螢屏中滾動瀏覽更多的效果,
總結
視圖回收 機制在日常使用的 App 中十分常見,如微博,CSDN 等,
今天學的 內容差不多就這些了, 步驟不多,但涵蓋的概念和知識點不少,慢慢來,
參考
OnClickListener
<activity>
ListView | Android Developers
ArrayAdapter --> BaseAdapter --> ListAdapter
查看堆和記憶體分配
關于 ListView 和 ArrayAdapter 的 Codepath 教程,
關于 ListView 的 Google I/O 演講 Youtube 視頻,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/246583.html
標籤:其他
下一篇:安卓開發學習——day2
