基於Android平臺智慧手機報系統的設計與開發
前言:
本文寫於2012年11月,轉眼間7年的時間過去了,最近翻箱倒櫃找出來了,看看7年之前寫的程式碼和文章,簡直不敢直視,哈哈哈,也沒有修改直接分享出來,以示紀念。本文出自門心叼龍的部落格,轉載請註明出處。屬於原創類容,侵權必究。 https://blog.csdn.net/geduo_83/article/details/85858394
中國網際網路發展迅速,據中國網際網路絡資訊中心(CNNIC)釋出的統計報告顯示,截至2011年底,中國網民規模突破5億,達到5.13億,全年新增網民5580萬,中國手機網民規模達到3.56億,同比增長17.5%。隨著智慧手機的普及,龐大的智慧手機網民規模為移動網際網路應用的爆發提供了基礎,各大網際網路服務商也開始紛紛佈局移動網際網路,而激烈的競爭必將催生能夠滿足細分人群需求的創新應用,並進一步推動手機網民進入下一輪高速增長週期。
移動網際網路現在已經成為人們生活不可或缺的一部分,手機閱讀報紙是依託手機媒介,由報紙和網路運營商聯手搭建的資訊傳播平臺,使用者可通過手機瀏覽到當天發生的新聞,手機閱讀方便,快捷,隨時隨地,為傳統的網際網路應用提供了新的發展空間和可持續發展的新商業模式,促進了行動網路寬頻化的深入發展。通過本系統可以在智慧手機上“原汁原味”直接閱讀報紙版面和新聞,便捷和“原汁原味”,這正是智慧手機報系統最有價值的地方。
在智慧手機上所執行的應用程式,根據開發方式的不同分為兩種,一種是Native App,另外一種是Web App
Web App無需安裝,對裝置碎片化的適應能力優於App,它只需要通過XHTML、CSS和JavaScript就可以在任意移動瀏覽器中執行。開發成本低、適配多種移動裝置成本低、跨平臺和終端、迭代更新容易、無需安裝成本,但是不支援離線模式、訊息推送不夠及時、呼叫本地檔案系統的能力弱。
Native App因為位於平臺層上方,向下訪問和相容的能力會比較好一些,提供最佳的使用者體驗,最優質的使用者介面,最華麗的互動、針對不同平臺提供不同體驗、可節省頻寬成本、可訪問本地資源,但是移植到不同平臺上比較麻煩、維持多個版本的成本比較高,App的開發成本要高很多,維持多個版本的更新升級比較麻煩
智慧手機報的核心功能是報紙閱讀,需要上下翻頁,為了提供最佳的使用者體驗,和優質的使用者介面,本系統採用Native App方式開發
Android是一個移動裝置的軟體平臺,是由Linux+Java構成的開源軟體,它提供包括SDK、Apps、Middleware、Linux Kernel四個部分在內的全套手機軟體方案。它開放了基於Linux核心以上的開發工具,從而保證了內容的可移植性和多樣性。Android平臺為我們開發應用程式提供了一套很好的框架,我們可以在這個平臺的基礎上開發不同的應用程式,也可以開發新的元件供應用程式呼叫。
3.1 Android架構
Android的架構是Linux核心、C/C++函式庫、Dalvik虛擬機器、應用框架以及關鍵應用程式構成的,如圖2-1。通過編譯基於框架的應用程式可以降低開發負荷。應用軟體原則上是在Dalvik VM上執行的。
第一層:Linux 核心,Display Rriver、Camera Driver、Flash Memory Driver、Wifi Driver它是整個Android系統最基礎,最核心的部分
第二層:系統執行庫(程式庫和執行庫),主要包括SQLite(一個小型的關係型資料庫),WebKit(一個開源的瀏覽器),OpenGL(3G開發API),同時在這一層還有個Android Runtime(android執行環境),主要包括Core Libraries(Java開發中常用的一些資源包)和Android執行虛擬機器
第三層:應用程式框架層(Application FrameWork),如:ActivtiyManager,ContentProvider,Window Manager(就是我們在開發Android應用程式,所需要的的一些框架)
第四層:應用程式層(Application),如:Home,Contacts、phone等等
對於一個Android應用程式來說,是由Activity、 BroadcastReceiver 、Service、ContentProvider四部分組成,但並不是每一個Android應用程式都必須由這四部分組成。在應用程式中使用時,需要在配置檔案AndroidMainfest.xml中進行配置。這個配置檔案是每個Android應用程式所必需的,用於定義應用程式的元件、元件的功能以及必要條件等。
3.2.1 Activity
Activity是構成應用程式中最重要的構造塊, 在Android應用程式中,幾乎都是通過Activity來與使用者進行互動,所以Activity主要負責的就是建立與使用者進行互動的顯示視窗,你可以在這些窗口裡通過呼叫setContentView(View)方法來顯示你自己的使用者介面。
活動生命週期
活動(Activity)在系統中以活動棧的形式進行管理。當一個新的活動啟動後,被放到了棧項,成為了執行活動,而新活動之前的活動在活動棧裡總位於新活動之下,直到新的活動退出才重新回到前臺。
(1)活動的整個生命期:從首次呼叫onCreate(Bundle)開始,到最終呼叫onDestroyO結束。在onCreate()中進行所有初始化,在onDestroyO時進行清理工作,釋放資源。
(2)活動的可見生命期:從呼叫onStart()開始,到onStop()被呼叫為止。在這段時間內,即使活動不與使用者進行互動,使用者也可以在螢幕上看到它。在這兩個方法呼叫之間,可以維護活動顯示給使用者的資源。onStart()和onStop()方法可以多次呼叫,因為活動隨時可以在可見和隱藏之間進行轉換。
(3)活動的後臺生命期:從呼叫onResume()開始,到onPause()被呼叫為止。在這段時間內活動處於其它所有活動之前,並與使用者進行互動。一個活動可以不斷在resumed狀態和paused狀態之間變換[4]。
活動之間的切換
Android使用了Intent類來實現活動之間的切換工作。Intent負責對應用中一次操作的動作、動作涉及的資料和附加資料進行描述。根據Intent的描述,負責找到對應的元件,將Intent傳遞給呼叫的元件並完成元件的呼叫。因此,Intent起著一種媒體中介的作用,專門提供元件互相呼叫的相關資訊,實現呼叫者與被呼叫者之間的解耦。在應用中,我們可以以兩種形式來使用Intent:直接Intent,指定了component屬性的Intent,通過指定具體的元件類,通知應用啟動對應的元件。間接Intent,沒有指定comonent屬性的Intent,則需要包含足夠的資訊,這樣系統才能根據這些資訊,在所有的可用元件中,確定滿足此Intent的元件。
3.2.2 BroadcastReceiver
BroadcastReceiver是用於對外部事件的響應,當外部事件發生時,會使用NotificationManager通知使用者。當一個BroadcastReceiver被觸發時,系統會在需要的時候啟動對應的應用程式。如在本系統中,當用戶正在其它介面進行操作時,有好友傳送訊息過來,就會以通知的形式傳送到當前介面的正上方來通知使用者。各種應用還可以通過使用Context.broadcastIntent()將它們的BroadcastReceiver廣播給其它的應用程式,實現應用之間的通訊。
3.2.3 Service
Service是提供連續資訊的應用程式。它是運行於應用程式後臺的服務,在使用者進行其它活動的時候,這個服務將一直執行在基於Android平臺的即時通訊統的研究與實現後臺直到使用者停止該服務或服務執行結束。本系統客戶端擴充套件功能的音樂播放就是採用Service來進行設計和開發的,使使用者可以邊聊天邊聽音樂。
3.2.4 ContentProvider
Content Provider應用程式能夠將它們的資料儲存到檔案、SQL資料庫和其它的儲存裝置中。當應用程式需要使用儲存裝置中的資料時,可以使用Content Provider來完成。使用Content Provider能夠靈活的替換底層使用的儲存裝置,使開發者可以專著於應用邏輯的開發,不用考慮底層儲存裝置的細節,從而使應用系統具有良好的資料
4 需求分析
4.1 業務流程圖
4.2 主要功能
5 系統設計與實現
5.1 相關技術
5.1.1 Http通訊
HttpURLConnection介面
首先需要明確的是,Http通訊中的POST和GET請求方式的不同。GET可以獲得靜態頁面,也可以把引數放在URL字串後面,傳遞給伺服器。而POST方法的引數是放在Http請求中。因此,在程式設計之前,應當首先明確使用的請求方法,然後再根據所使用的方式選擇相應的程式設計方式。
HttpURLConnection是繼承於URLConnection類,二者都是抽象類。其物件主要通過URL的openConnection方法獲得。建立方法如下程式碼所示:
URL url = new URL("http://....");
HttpURLConnection urlConn=(HttpURLConnection)url.openConnection();
5.1.2 xml解析
在Android平臺上可以使用Simple API for XML(SAX)、Document Object Model(DOM)和Android附帶的pull解析器解析XML檔案。
(1)使用SAX讀取XML檔案
SAX是一個解析速度快並且佔用記憶體少的XML解析器,非常適合用於Android等移動裝置。SAX解析XML檔案採用的是事件驅動,也就是說,它並不需要解析完整個文件,在按內容順序解析文件的過程中,SAX會判斷當前讀到的字元是否合法XML語法中的某部分,如果符合就會觸發事件。所謂事件,其實就是一些回撥(callback)方法,這些方法(事件)定義在ContentHandler介面。
下面是一些ContentHandler介面常用的方法:
startDocument()當遇到文件的開頭的時候,呼叫這個方法,可以在其中做一些預處理的工作。
endDocument()和上面的方法相對應,當文件結束的時候,呼叫這個方法,可以在其中做一些善後的工作。
startElement(String namespaceURI, String localName, String qName, Attributes atts)當讀到一個開始標籤的時候,會觸發這個方法。namespaceURI就是名稱空間,localName是不帶名稱空間字首的標籤名,qName是帶名稱空間字首的標籤名。通過atts可以得到所有的屬性名和相應的值。要注意的是SAX中一個重要的特點就是它的流式處理,當遇到一個標籤的時候,它並不會紀錄下以前所碰到的標籤,也就是說,在startElement()方法中,所有你所知道的資訊,就是標籤的名字和屬性,至於標籤的巢狀結構,上層標籤的名字,是否有子元屬等等其它與結構相關的資訊,都是不得而知的,都需要你的程式來完成。這使得SAX在程式設計處理上沒有DOM來得那麼方便。
endElement(String uri, String localName, String name)這個方法和上面的方法相對應,在遇到結束標籤的時候,呼叫這個方法。
characters(char[] ch, int start, int length)這個方法用來處理在XML檔案中讀到的內容,第一個引數用於存放檔案的內容,後面兩個引數是讀到的字串在這個陣列中的起始位置和長度,使用new String(ch,start,length)就可以獲取內容。
(2)使用DOM讀取XML檔案
除了可以使用 SAX解析XML檔案,大家也可以使用熟悉的DOM來解析XML檔案。 DOM解析XML檔案時,會將XML檔案的所有內容讀取到記憶體中,然後允許您使用DOM API遍歷XML樹、檢索所需的資料。使用DOM操作XML的程式碼看起來比較直觀,並且,在某些方面比基於SAX的實現更加簡單。但是,因為DOM需要將XML檔案的所有內容讀取到記憶體中,所以記憶體的消耗比較大,特別對於執行Android的移動裝置來說,因為裝置的資源比較寶貴,所以建議還是採用SAX來解析XML檔案,當然,如果XML檔案的內容比較小採用DOM是可行的。
(3)使用Pull解析器讀取XML檔案
除了可以使用 SAX和DOM解析XML檔案,大家也可以使用Android內建的Pull解析器解析XML檔案。 Pull解析器的執行方式與 SAX 解析器相似。它提供了類似的事件,如:開始元素和結束元素事件,使用parser.next()可以進入下一個元素並觸發相應事件。事件將作為數值程式碼被髮送,因此可以使用一個switch對感興趣的事件進行處理。當元素開始解析時,呼叫parser.nextText()方法可以獲取下一個Text型別元素的值
5.1.3 廣播機制
BroadcastReceiver:他主要是實現了不同的應用程式之間資料的非同步接收,其本質是一個事件監聽器,用於監聽系統全域性的廣播訊息
1.概念:
1.1 Broadcast:是一種廣泛運用的在應用程式之間傳輸資訊的機制
1.2 BroadcastReceiver:是對傳送出來的 Broadcast進行過濾接受並響應的一類元件,其本質是一個監聽器,用來監聽系統全域性的廣播資訊
2.廣播機制工作原理:
如何傳送Broadcast和使用BroadcastReceiver過濾接收:
2.1 首先在需要傳送資訊的地方,把要傳送的資訊和用於過濾的資訊(如Action、Category)裝入一個Intent物件
2.2 然後通過呼叫 Context.sendBroadcast()、sendOrderBroadcast()或sendStickyBroadcast()方法,把Intent物件以廣播方式傳送出去。
2.3 當Intent傳送以後,所有已經註冊的BroadcastReceiver會檢查註冊時的IntentFilter是否與傳送的Intent相匹配,若匹配則就會呼叫BroadcastReceiver的onReceive()方法
3.註冊BroadcastReceiver有兩種方式:
3.1 靜態的在AndroidManifest.xml中用<receiver>標籤宣告註冊,並在標籤內用<intent-filter>標籤設定過濾器
3.2 動態的在程式碼中先定義並設定好一個 IntentFilter物件,然後在需要註冊的地方調 Context.registerReceiver()方法,如果取消時就呼叫Context.unregisterReceiver()方法。如果用動 態方式註冊的BroadcastReceiver的Context物件被銷燬時, BroadcastReceiver,也就自動取消註冊了,動態註冊退出程式前要記得呼叫Context.unregisterReceiver()方法
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(String);//BroadcastReceiver指定action,
registerReceiver(BroadcastReceiver,intentFilter); (一般:在onStart中註冊,onStop中取消unregisterReceiver;官方提醒,如果在Activity.onResume()裡面註冊了,就必須在Activity.onPause()登出)
4.兩種註冊方式的區別:
4.1 靜態註冊可以在xml裡面一目瞭然,而動態註冊方式,隱藏在程式碼中,比較難發現
4.2 同一優先順序的廣播接收器,動態的要比靜態註冊接受的早
sendBroadcast 傳送的是無序廣播
sendOrderedBroadcast 傳送的是有序廣播
5.指定接收的許可權:
若在使用sendBroadcast()的方法是指定了接收許可權,則只有在AndroidManifest.xml中用<uses-permission>標籤聲明瞭擁有此許可權的BroascastReceiver才會有可能接收到傳送來的Broadcast
6.實現一個廣播接收器的步驟:
6.1第一步:繼承BroadcastReceiver,並重寫onReceive()方法。
public class IncomingSMSReceiver extends BroadcastReceiver{
@Override public void onReceive(Context context, Intent intent){ }
}
6.2 第二步:訂閱感興趣的廣播Intent,訂閱方法有兩種:
第一種:使用程式碼進行訂閱
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomingSMSReceiver();
registerReceiver(receiver, filter);
第二種:在AndroidManifest.xml檔案中的<application>節點裡進行訂閱:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
7.常見廣播Intent:
一個receiver可以接收多個action的,即可以有多個intent-filter,需要在onReceive裡面對intent.getAction(action name)進行判斷
接受簡訊
action:android.provider.Telephony.SMS_RECEIVED
permission:android.permission.RECEIVE_SMS
接收電池電量變化
action:android.intent.action.BATTERY_CHANGED
接收開機啟動
aciton:android.intent.action.BOOT_COMPLETED
permission:andro.permission.RECEIVE_BOOT_COMPLETED
8.廣播接收器的生命週期:
在Android中,程式的響應(Responsive)被活動管理器(Activity Manager)和視窗管理器(Window Manager)這兩個系統服務所監視。當BroadcastReceiver的Receiver方法在10秒內沒有執行完畢,Android會認為該程式無響應。所以在BroadcastReceiver裡不能做一些比較 耗時的操作,否則會彈出ANR(Application No Response)的對話方塊。
如果需要完成一項比較耗時的工作,應該通過Intent啟動一個Service來完成,而不是啟動一個新的執行緒來完成,因為BoradcastReveiver的生命週期非常短暫,有可能在子執行緒還沒有執行完畢,BroadcastReceiver就提前退出了,這樣在程序中沒有任何的活動元件,系統在記憶體緊張的情況下優先結束該程序,導致BroadcastReceiver啟動的子執行緒不能執行完成
一個BroadcastReceiver,每接受一次就是產生一個新的接收器物件 物件只有在被呼叫onReceive(Context, Intent)的才有效的,當從該函式返回後,該物件就無效的了,結束生命週期
public class IncomingSMSReceiver extends BroadcastReceiver {
//傳送Intent啟動服務,由服務來完成比較耗時的操作
Intent service = new Intent(context, XxxService.class);
context.startService(service);
}
9.廣播接收器分類:
Normal Broadcast(普通廣播):
1.1 完全是非同步的的,理論上可以在同一時刻被所有接收器所接受,傳播效率高
1.2 廣播接收器無法將處理結果傳遞給下一個接收者
1.3 廣播接收器無法阻止廣播資訊的傳播
Ordered Broadcast(有序廣播):
1.1 可以按照廣播接收器預先設定的優先順序依次接受Broadcast(優先順序宣告在<IntentFilter...>的android:priority屬性中,數越大優先順序越高,取值範圍在-1000~1000之間)
1.2 廣播接收器可以終止廣播的傳播(abortBroadcast()),一旦終止,後面的廣播接收器將無法接收到廣播訊息,也無法接收廣播接收器所傳遞的資訊
1.3 廣播接收器可以將處理結果傳遞給下一個接收者(前提條件,廣播沒有終止)
小結:沒有終止廣播資訊和結果資料能接收,若終止廣播資訊和結果資料都不能接收
setResultExtras(bundle);//將廣播訊息的處理結果存入結果物件
abortBroadcast();//終止傳送廣播
Bundle bundle = getResultExtras(true);//接收所傳遞的廣播結果物件
String first = bundle.getString("first");
10.UI事件監聽器機制和廣播事件處理機制的聯絡與區別:
聯絡:都是基於事件監聽處理機制
9.1 UI事件處理機制是程式元件級別的(比如:按鈕的單擊事件),而廣播事件處理機制是系統級別的
9.2 UI事件監聽器的註冊只能在程式碼中實現,而廣播放事件的監聽器可以在程式碼中註冊也可以在xml配置檔案裡面註冊
9.3 UI事件監聽器的處理和主程式是同步的,而是廣播放事件的事件處理是非同步的
9.4 UI事件監聽器監聽的是程式中的物件,而廣播放事件的監聽器監聽的事件源是Android應用中其他的元件
5.1.4 ListView佈局
ListView 如果僅僅出於功能上的需求ListView可能沒有存在的必要,ListView能作的事情基本上ScrollView也能勝任。ListView存在的最根本的原因在於它的高效(如何實現的?).ListView通過物件的複用從而減少記憶體的消耗,也減少了物件的建立從而也減少的cpu的消耗(在Androidk中建立View物件經常伴隨著解析xml)。ListView的本質是一張bitmap(當然所有的控制元件文字等在螢幕上看到的最終都會變成bitmap),ListView會按照需求,根據Adapter提供的資訊把需要的Item畫出來顯示在螢幕上,當螢幕滾動的時候會重新計算Item的位置並繪製出新的bitmap顯示在螢幕上。這樣聽起來感覺可能不是很高效,但這樣帶的好處就是,每用為一第個Item 建立一個View物件,樣式一樣的物件可以共用一個View物件,減少了記憶體的消耗。而且ListView是事件驅動的,只有當需要的時候才會重新繪製,並且只會 繪製當前螢幕上所顯示的Items.
ListView 離不開Adapter,通常的作法建立一個類繼承BaseAdapter,Override getCount()和getView()等方法。生成這個類的物件,呼叫ListView的setAdapter()與ListViw進行繫結。
ListView會呼叫跟其繫結的Adapter的getCount()方法知道有多少個Item需要展示,然後迴圈呼叫getView(int position, View convertView, ViewGroup parent)知道第position個Item該怎麼畫,並畫出來直到把當前的ListView的空間填滿。當Adapter當中的資料改變時,需呼叫notifyDataSetChanged ()告訴Adapter資料發生了變化或者給Adapter註冊一個觀察者registerDataSetObserver (DataSetObserver observer)。當Adapter得知與其繫結的資料己發生改變時間,會再次呼叫getCount()方法,並迴圈呼叫getView(int position, View convertView, ViewGroup parent)重新整理當前頁面
5.1.5 GridView佈局
a.需要建立GridView xml佈局檔案
必須定義的屬性(列數,列寬,對其方式),android:numColumns="auto_fit" android:columnWidth="90" android:gravity="center"
b.建立資料介面卡ImageAdapter(注意一定要給imageViewz賦值)
if(convertView==null){
//設定ImageView的資源
ImageView imageView = new ImageView(mContent);
//設定圖片的尺寸
imageView.setLayoutParams(new GridView.LayoutParams(85,85));
//設定顯示比例型別
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
}else{
imageView = (ImageView)convertView;
}
imageView.setImageResource(imgArr[position]);
c.設定Activity的佈局檔案,並獲得GriwView,並且設定它的介面卡
setContentView(R.layout.gridview);
d.獲取GridView控制元件
GridView gv = (GridView)findViewById(R.id.gridView);
e.設定GridView的匹配器
gv.setAdapter(new ImageAdapter(this));
f.設定網格元素的監聽器
gv.setOnItemClickListener(new AdapterView.onItemClickListener(){});
5.1.6 翻頁技術
實現原理:
使用貝賽爾曲線。曲線有四個點:起始點、終止點(也稱錨點)以及兩個相互分離的中間點。滑動兩個中間點,貝塞爾曲線的形狀會發生變化。
根據第一種翻頁效果原理可以確定a、e、h、f、g ,由eh平行於cj且af垂直於eh,則 af垂直於cj則三角形egf相似於三角形cnf 則有ef:cf = gf:nf 。
設n為ag中點 則有cf=(3/2)*ef ,則c點座標可求 由c點、k點座標已知可知過兩點間的直線
由該直線可計算與y軸相交點j 由a、e、c、j可計算兩條直線的相交點b 同理可求點k。
在Android中的具體實現步驟:
起始頁展示
1.建立螢幕尺寸的bmp 2.將圖片轉化為canvas 3.獲取起始頁面資料 3.在canvas中繪製起始頁資料 4.在當前檢視中複寫onDraw進行重繪出bmp物件
翻頁處理
1.初始化時建立兩個bmp(bmp1、bmp2)並將其轉換為canvas(canvas1、canvas2)
2.獲取手勢首次觸控的區域 (例:當首次點選螢幕的位置x<50&&y<50則為左上角)
3.根據首次點選區域判斷需要展示的資料(例:首次點選處於左側區域【左上、左下】的則判斷操作為下一頁操作)
4.獲取下一頁中資料並繪製出來在canvas2中
5.根據1中獲取的區域位置呼叫起始動畫使檢視移動到手勢首次點選位置
6.獲取手勢每次移動的座標並根據移動座標計算繪製的各個點的座標
7.每次移動重新整理檢視
5.2 相關介面
5.2.1 首頁
5.2.2 報紙閱讀頁
5.2.3 報紙列表頁
5.3 相關實現
5.3.1 首頁
Android的每一個視覺化介面,都有其唯一的佈局配置檔案,該檔案中有各種佈局的方式,和各種資原始檔如影象,文字,顏色引用等,程式在執行時可以通過程式碼對各個配置檔案進行讀取,這樣可以形成不同的視覺化介面和絢麗的效果。
該軟體的主介面是一個Activity,Android工程在啟動每一個Activity時都會首先執行onCreate()方法,如下:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
該方法主要執行介面的初始化操作,Activity有個設定佈局的方法:
setContentView(int id)
最新報紙程式碼實現:
paper = (Paper) bundle.getSerializable("paper");
Bitmap bitmapZxbz = bundle.getParcelable("bitmapZxbz"); publishDateTv.setText(paper.getPublishDate().toString());
paperSizeTv.setText(paper.getSize()+"");
paperImgIv.setImageBitmap(bitmapZxbz);
本期導讀程式碼實現:
listArticle = (List<Article>) bundle.getSerializable("listArticle");
List<HashMap<String,String>> listArticleMap = new ArrayList<HashMap<String,String>>();
LayoutParams params = bqddLv.getLayoutParams();
params.height = listArticle.size()*42;
bqddLv.setLayoutParams(params);
BqddArrayAdapter adapterBqdd = new BqddArrayAdapter(IndexActivity.this,R.layout.bqdd,listArticle);
bqddLv.setAdapter(adapterBqdd);
bqddLv.setOnItemClickListener(new BqddLvOnItemClickListener());
bqddLv.setItemsCanFocus(true);
過往瀏覽程式碼實現:
String[] picGwllArr = bundle.getStringArray("picGwllArr");
gwllGridView.setAdapter(new GwllImageAdapter(IndexActivity.this,picGwllArr));
翻頁程式碼實現:
BookLayout bk = new BookLayout(PaperReadActivity.this,listPage);
BookAdapter ba = new BookAdapter(PaperReadActivity.this,pageArr,false);
bk.setPageAdapter(ba);
setContentView(bk);
5.3.2 報紙閱讀頁
BookLayout bk = new BookLayout(PaperReadActivity.this,listPage);
BookAdapter ba = new BookAdapter(PaperReadActivity.this,pageArr,false);
bk.setPageAdapter(ba);
setContentView(bk);
5.3.3 報紙列表頁
private void InitLayout() {
//得到ScrollView控制元件
waterfall_scroll = (LazyScrollView) findViewById(R.id.waterfall_scroll);
//的到ScrollView控制元件下的子控制元件
waterfall_scroll.getView();
//給ScrollView繫結滑屏監聽器
waterfall_scroll.setOnScrollListener(new OnScrollListener() {
@Override
public void onTop() {
// 滾動到最頂端
Log.d("LazyScroll", "Scroll to top");
}
@Override
public void onScroll() {
// 滾動中
Log.d("LazyScroll", "Scroll");
}
@Override
public void onBottom() {
// 滾動到最低端 呼叫該方法
AddItemToContainer(++current_page, page_count);
}
});
//得到線性佈局控制元件
waterfall_container = (LinearLayout) this.findViewById(R.id.waterfall_container);
//例項化線性佈局控制元件集合
waterfall_items = new ArrayList<LinearLayout>();
//迴圈給線性控制元件集合賦值,並將子控制元件新增到父控制元件
for (int i = 0; i < column_count; i++) {
System.out.println("--------->"+i);
LinearLayout itemLayout = new LinearLayout(this);
LinearLayout.LayoutParams itemParam = new LinearLayout.LayoutParams(itemWidth, LayoutParams.WRAP_CONTENT);
// itemParam.width = itemWidth;
// itemParam.height = LayoutParams.WRAP_CONTENT;
itemLayout.setPadding(2, 2, 2, 2);
itemLayout.setOrientation(LinearLayout.VERTICAL);
itemLayout.setLayoutParams(itemParam);
waterfall_items.add(itemLayout);
waterfall_container.addView(itemLayout);
}
6 結論
通過對Android智慧手機報系統的開發,對Android下Http網路通訊機制有了深入的瞭解,熟悉了Android開發架構和API呼叫, 掌握了多執行緒開發技術,熟練Android平臺UI佈局,熟練常用控制元件使用,通過專案實踐認識到整個開發過程中就是圍繞著一個數據,Activity顯示資料,Service處理資料,Intent傳遞資料,BroadcastReceiver接收資料,ContentProvider共享資料,對Adroid平臺提供的幾大基本元件有深刻的理解和認識
Activity:是整個應用程式的門面,主要負責應用程式當中資料的展示,是各種各樣控制元件的容器,是使用者和應用程式之間互動的介面 (美女)
Service:在前臺不可見,但是承擔大部分資料處理工作,Service和Activity的地位是並列的,他也代表一個單獨的Android元件,區別在於:Activity執行與前臺,Service通常位於後臺執行,他一般需要與使用者互動,因此Service沒有圖形使用者介面,通常他為其他的元件提供後臺服務或監控其他元件的執行狀態(勞模)
Intent:是應用程式種各個元件聯絡的橋樑,主要負責應用程式中所有資料的傳遞(運輸大隊長)
BroadcastReceiver:他主要是實現了不同的應用程式之間資料的非同步接收,其本質是一個事件監聽器,用於監聽系統全域性的廣播訊息(廣播接收器)
ContentProvider:負責不同應用程式之間資料的共享,為不同的應用程式之間資料訪問提供統一的介面 ,這個介面就是ContentHandler,具體就是要實現如下的四個抽象方法insert(),delete(),update(),query(),通常它與ContentResolver結合使用,一個是應用程式使用ContentProvider來暴露自己的資料,而另外一個是應用程式通過ContentResolver來訪問資料(國家檔案館)