Android移動(dòng)終端開發(fā)大作業(yè)_第1頁(yè)
Android移動(dòng)終端開發(fā)大作業(yè)_第2頁(yè)
Android移動(dòng)終端開發(fā)大作業(yè)_第3頁(yè)
Android移動(dòng)終端開發(fā)大作業(yè)_第4頁(yè)
Android移動(dòng)終端開發(fā)大作業(yè)_第5頁(yè)
已閱讀5頁(yè),還剩30頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

...wd......wd......wd...Android移動(dòng)終端開發(fā)大作業(yè)作業(yè)要求1人一組,獨(dú)立完成。按照個(gè)人興趣方向,自選題目,完成系統(tǒng)。在規(guī)定的時(shí)間里完成系統(tǒng)主體功能,程序?qū)Ρ确€(wěn)定的運(yùn)行。手機(jī)界面要求簡(jiǎn)潔、美觀,功能不能過于簡(jiǎn)單,應(yīng)具備一定的實(shí)用性。至少要3個(gè)Activity以上。必須使用自定義Listview,要使用Sqlite數(shù)據(jù)庫(kù)或API調(diào)用與數(shù)據(jù)解析〔API可使用聚合數(shù)據(jù)〔s:///〕、APIStore〔://apistore.baidu/〕或apix〔:///〕提供的API,如有能力也可自行開發(fā)服務(wù)器端〕。歡送好的創(chuàng)意作品、實(shí)用作品,評(píng)分時(shí)會(huì)適當(dāng)加分。需提交設(shè)計(jì)報(bào)告,設(shè)計(jì)報(bào)告格式見附件,按附件順序裝訂〔包括評(píng)分表〕大作業(yè)成績(jī)從工作量、功能點(diǎn)、創(chuàng)新性、實(shí)用性、報(bào)告的字?jǐn)?shù)、質(zhì)量及標(biāo)準(zhǔn)度等方面的成績(jī)構(gòu)成本卷須知壓縮包內(nèi)作業(yè)內(nèi)容包括兩局部:作業(yè)工程文件夾,工程必須能夠調(diào)試通過,android平臺(tái)選擇選擇2.2或是2.3.3。作業(yè)設(shè)計(jì)說(shuō)明,word文件。可以借鑒網(wǎng)絡(luò)上的代碼,但不可全部照搬。不許相互抄襲,一旦發(fā)現(xiàn)成績(jī)?yōu)榱恪8郊?:學(xué)號(hào)0121309341617成績(jī)Android平臺(tái)移動(dòng)應(yīng)用開發(fā)大作業(yè)題目基于Android的新聞瀏覽軟件的設(shè)計(jì)與實(shí)現(xiàn)學(xué)院信息工程學(xué)院專業(yè)信息工程班級(jí)信息1303姓名杏允升指導(dǎo)教師秦珀石2015年12月10日TOC\o"1-3"\h\u26428一、331306二、概述414812三、關(guān)鍵技術(shù)521607四、概要設(shè)計(jì)628337五、系統(tǒng)實(shí)現(xiàn)716643六、心得體會(huì)8概述Android應(yīng)用平臺(tái)新聞客戶端軟件是基于Android手機(jī)平臺(tái),采用Java語(yǔ)言,從網(wǎng)絡(luò)上的開放的新聞接口獲取數(shù)據(jù),設(shè)計(jì)出針對(duì)使用Android平臺(tái)的手機(jī)新聞客戶端資訊實(shí)時(shí)掌控的手機(jī)應(yīng)用程序。Android平臺(tái)新聞客戶端軟件的開發(fā)可以進(jìn)一步擴(kuò)大時(shí)事新聞的覆蓋面,讓廣闊公眾能夠隨時(shí)隨地方便且快捷地獲取最新的新聞資訊信息,了解新聞時(shí)事,本軟件的廣泛使用,尤其是在傳授知識(shí)、普及教育方面起著非常重要的作用。目前市場(chǎng)研究機(jī)構(gòu)Worldpanel發(fā)布了全球主要的國(guó)家智能手機(jī)操作系統(tǒng)在去年Q4內(nèi)的分布報(bào)告,報(bào)告指出了谷歌的Android繼續(xù)保持著增長(zhǎng)的勢(shì)態(tài),但是增幅已經(jīng)明顯放緩了。而在另一個(gè)方面,蘋果iOS操作系統(tǒng)在全球只能手機(jī)市場(chǎng)上均有下滑,個(gè)別國(guó)家的降幅甚至高達(dá)10.3%。最新統(tǒng)計(jì)數(shù)據(jù)中顯示,Android操作系統(tǒng)將繼續(xù)領(lǐng)跑全球市場(chǎng),包括美國(guó)、澳大利亞、中國(guó)、意大利、英國(guó)、德國(guó)、西班牙等所占的市場(chǎng)比例都已經(jīng)超出50%,并且還將繼續(xù)呈現(xiàn)上漲的趨勢(shì)。而在蘋果iOS操作系統(tǒng)方面,最大的市場(chǎng)份額所占比的國(guó)家依舊是美國(guó),數(shù)值為43.9%;緊隨美國(guó)的那么是澳大利亞,數(shù)值為35.2%;而在中國(guó)方面,市場(chǎng)份額也從21.2%下降到了19%;在意大利,iOS所占的市場(chǎng)份額更是從23.1%猛降至12.8%。從上面的數(shù)據(jù)可以看出,Android手機(jī)軟件的開發(fā)具有巨大的開展前景,在Android系統(tǒng)上開發(fā)出一款手機(jī)新聞客戶端軟件所支持的用戶量也是相對(duì)比于其他系統(tǒng)多出很多的。谷歌的移動(dòng)平臺(tái)主管安迪·魯賓(AndyRubin)表示,跟軟件開發(fā)合作對(duì)象的密切接觸正在進(jìn)展中。Google與開放手機(jī)聯(lián)盟聯(lián)合開發(fā)了Android操作系統(tǒng),這個(gè)聯(lián)盟由摩托羅拉、高通、宏達(dá)電、中國(guó)移動(dòng)和T-Mobile等在內(nèi)的多家無(wú)線應(yīng)用和技術(shù)的領(lǐng)軍企業(yè)組成。Google通過與設(shè)備制造商、開發(fā)商、運(yùn)營(yíng)商和其他有關(guān)各方結(jié)成深層次的合作關(guān)系,希望借助建設(shè)開放式、標(biāo)準(zhǔn)化的移動(dòng)移動(dòng)軟件平臺(tái),在移動(dòng)產(chǎn)業(yè)內(nèi)形成一個(gè)開放性的生態(tài)系統(tǒng),這將是開發(fā)Android軟件的一個(gè)契機(jī),Android平臺(tái)的開發(fā)在將來(lái)必定大放異彩。關(guān)鍵技術(shù)使用ViewPager里面添加多張圖片配合線程延時(shí)實(shí)現(xiàn)輪播圖的自沒有通過ScheduledExecutorService或Timer定期執(zhí)行某個(gè)任務(wù)實(shí)現(xiàn),而是簡(jiǎn)單的通過handler發(fā)送消息去完成一次滾動(dòng),在完成一次滾動(dòng)后發(fā)送另外一個(gè)delay的滾動(dòng)消息,如此循環(huán)實(shí)現(xiàn)。自動(dòng)滾動(dòng)局部核心代碼如下:至于ViewPager嵌套引起子ViewPager無(wú)法觸摸問題是通過在子ViewPager的onTouchEvent中添加制止父控件對(duì)touchevent做intercept解決的。ViewPager滑動(dòng)速度的設(shè)置是通過反射的方式重新設(shè)置ViewPager的Scroller,改變Scroller的startScroll的間隔時(shí)間完成的。調(diào)用setScrollDurationFactor(double)即可。2、使用(1)引入公共庫(kù)引入AndroidAutoScrollViewPager@Github作為你工程的library(若何拉取代碼及添加公共庫(kù))。(2)調(diào)用僅需簡(jiǎn)單兩步:布局定義代替一般的ViewPager定義b.啟動(dòng)ViewPager自動(dòng)滾動(dòng)startAutoScroll()啟動(dòng)自動(dòng)滾動(dòng)stopAutoScroll()停頓自動(dòng)滾動(dòng)3、設(shè)置setInterval(long)設(shè)置自動(dòng)滾動(dòng)的間隔時(shí)間,單位為毫秒setDirection(int)設(shè)置自動(dòng)滾動(dòng)的方向,默認(rèn)向右setCycle(boolean)是否自動(dòng)循環(huán)輪播,默認(rèn)為truesetScrollDurationFactor(double)設(shè)置ViewPager滑動(dòng)動(dòng)畫間隔時(shí)間的倍率,到達(dá)減慢動(dòng)畫或改變動(dòng)畫速度的效果setStopScrollWhenTouch(boolean)當(dāng)手指碰到ViewPager時(shí)是否停頓自動(dòng)滾動(dòng),默認(rèn)為truesetSlideBorderMode(int)滑動(dòng)到第一個(gè)或最后一個(gè)Item的處理方式,支持沒有任何操作、輪播以及傳遞到父View三種模式setBorderAnimation(boolean)設(shè)置循環(huán)滾動(dòng)時(shí)滑動(dòng)到從邊緣滾動(dòng)到下一個(gè)是否需要?jiǎng)赢嫞J(rèn)為true4、其他〔1〕指示器,圓形或是方形指示器請(qǐng)配合ViewPagerIndicator使用〔2〕無(wú)限循環(huán),如果希望在最后一張繼續(xù)播放第一張而不是退回到第一張,請(qǐng)參考AutoScrollViewPagerSingleDemo.java,注意這個(gè)特性不能和ViewPagerIndicator使用2)使用viewpager結(jié)合ViewPageIndicator進(jìn)展新聞?lì)悇e的分類切換,可點(diǎn)擊切換也可以滑動(dòng)切換。1.ViewPagerIndicator的Library查看ViewpagerIndicator的Library代碼,可以看到此工程的設(shè)計(jì)思想:

首先定義了一個(gè)PageIndicator接口,它里面定義了最重要和基本的indicator表現(xiàn)出的一些方法:

1.1首先一個(gè)indicator必須要與一個(gè)ViewPager關(guān)聯(lián)在一起,所以它提供了一個(gè)setViewPager方法。

1.2它擴(kuò)展了ViewPager.OnPageChangeListener接口,表示接收了ViewPager的Pager改變時(shí)的監(jiān)聽處理,

這也是為什么為ViewPager設(shè)置OnPageChangeListener監(jiān)聽器時(shí)不能設(shè)置在ViewPager上而必須設(shè)置在

indicator上的原因。

1.3還有一個(gè)notifyDataSetChanged通知方法,表示為這個(gè)ViewPager提供View(一般是Fragment)的

Adapter里面的數(shù)據(jù)集發(fā)生變化時(shí),執(zhí)行的動(dòng)作,這里可增加相關(guān)的邏輯。2.ViewpagerIndicator的實(shí)現(xiàn)類

然后再看下ViewpagerIndicator的實(shí)現(xiàn)類,共有6個(gè),由6個(gè)類分別實(shí)現(xiàn),它們分別為:

2.1小圓圈類型的

2.2帶圖標(biāo)類型的

2.3小橫線類型的,距離屏幕最下邊端有一定的距離。

2.4標(biāo)簽類型的〔Tab〕

2.5標(biāo)題類型的,與標(biāo)簽類型的有點(diǎn)像,但它當(dāng)前的標(biāo)題頁(yè)的左/右邊的標(biāo)題會(huì)卷起,即往兩端縮進(jìn)去。

2.6屏幕底部小橫線類型的,并且會(huì)占滿整行。

3.ViewpagerIndicator隨附帶的Demo

Demo工程的設(shè)計(jì)

工程由一個(gè)ListSamples的ListActivity入口,它主要用作組裝所有的子indicator的列表。

TestFragment.java,所有ViewPager上真正顯示的視圖。

TestFragmentAdapter.java,所有ViewPager里的Adapter,為ViewPager生成TestFragment。

Samplexxx.java,所有的indicator的顯示,一個(gè)類顯示一種使用方法或特性2)使用viewpager結(jié)合ViewPageIndicator進(jìn)展新聞?lì)悇e的分類切換,可點(diǎn)擊切換也可以滑動(dòng)切換。3)使用Gson對(duì)新聞數(shù)據(jù)的json字符串進(jìn)展解析顯示到listview上需要使用jar包fastjson或gson這兩個(gè)jar包。//Gson的使用方式Gsongson=newGson();Stringstr=ReadAssetsFile.readtext(this,"json_ss");//this當(dāng)前類,"json_ss"需要解析的文件名UserMessageuserMessage=gson.fromJson(str,UserMessage.class);//需要解析的json文件最外層類名//fastjson的使用方法Stringjson=ReadAssetsFile.readtxt(this,"json_h");UserMessageuser=JSON.parseObject(json,UserMessage.class);自己擴(kuò)展4)使用Universal-Image-Loader對(duì)圖片進(jìn)展緩存加載Android上最讓人頭疼的莫過于從網(wǎng)絡(luò)獲取圖片、顯示、回收,任何一個(gè)環(huán)節(jié)有問題都可能直接OOM,這個(gè)工程或許能幫到你。UniversalImageLoaderforAndroid的目的是為了實(shí)現(xiàn)異步的網(wǎng)絡(luò)圖片加載、緩存及顯示,支持多線程異步加載。它最初來(lái)源于FedorVlasov的工程,且自此之后,經(jīng)過大規(guī)模的重構(gòu)和改良。特性列舉:多線程下載圖片,圖片可以來(lái)源于網(wǎng)絡(luò),文件系統(tǒng),工程文件夾assets中以及drawable中等支持隨意的配置ImageLoader,例如線程池,圖片下載器,內(nèi)存緩存策略,硬盤緩存策略,圖片顯示選項(xiàng)以及其他的一些配置支持圖片的內(nèi)存緩存,文件系統(tǒng)緩存或者SD卡緩存支持圖片下載過程的監(jiān)聽根據(jù)控件(ImageView)的大小對(duì)Bitmap進(jìn)展裁剪,減少Bitmap占用過多的內(nèi)存較好的控制圖片的加載過程,例如暫停圖片加載,重新開場(chǎng)加載圖片,一般使用在ListView,GridView中,滑動(dòng)過程中暫停加載圖片,停頓滑動(dòng)的時(shí)候去加載圖片提供在較慢的網(wǎng)絡(luò)下對(duì)圖片進(jìn)展加載使用過程:創(chuàng)立默認(rèn)的ImageLoader,所有的操作都由ImageLoader控制。該類使用單例設(shè)計(jì)模式,所以如果要獲取該類的實(shí)力,需要調(diào)用getInstance()方法。在使用ImageLoader顯示圖片之前,你首先要初始化它的配置,調(diào)用ImageLoaderConfiguration的init()方法,然后你就可以實(shí)現(xiàn)各種的顯示了。自定義配置imageloader,就像你已經(jīng)知道的,首先,你需要使用ImageLoaderConfiguration對(duì)象來(lái)初始化ImageLoader。由于ImageLoader是單例,所以在程序開場(chǎng)的時(shí)候只需要初始化一次就好了。建議你在Activity的onCreate〔〕方法中初始化。如果一個(gè)ImageLoader已經(jīng)初始化過,再次初始化不會(huì)有任何效果。下面我們通過ImageLoaderConfiguration.Builder創(chuàng)立一個(gè)設(shè)置得到imageLoader使用過程:圖像操作是否參與緩存以及圖像效果的配置操作DisplayImageOptions以下是所有默認(rèn)配置參數(shù)根據(jù)需求可以自定義配置〔2〕圖片加載監(jiān)聽器在這里吧可以設(shè)置加載時(shí)的動(dòng)畫或者進(jìn)度條之類的東西這里〔3〕簡(jiǎn)單設(shè)置就可以給ImageView添加圖片了對(duì)于本地的圖片,在其絕對(duì)地址前面要參加"file://"。網(wǎng)絡(luò)圖片就直接寫路徑了。緩存的清理:緩存的清理可以按需求來(lái)定,可以再每個(gè)Activity的生命周期函數(shù)onDestroy中清理也可以單獨(dú)設(shè)置讓用戶自行清理。GirdView,ListView加載圖片:相信大局部人都是使用GridView,ListView來(lái)顯示大量的圖片,而當(dāng)我們快速滑動(dòng)GridView,ListView,我們希望能停頓圖片的加載,而在GridView,ListView停頓滑動(dòng)的時(shí)候加載當(dāng)前界面的圖片,這個(gè)框架當(dāng)然也提供這個(gè)功能,使用起來(lái)也很簡(jiǎn)單,它提供了PauseOnScrollListener這個(gè)類來(lái)控制ListView,GridView滑動(dòng)過程中停頓去加載圖片,該類使用的是代理模式第一個(gè)參數(shù)就是我們的圖片加載對(duì)象ImageLoader,第二個(gè)是控制是否在滑動(dòng)過程中暫停加載圖片,如果需要暫停傳true就行了,第三個(gè)參數(shù)控制猛的滑動(dòng)界面的時(shí)候圖片是否加載概要設(shè)計(jì)Json數(shù)據(jù)的一些返回參數(shù)名稱 類型 說(shuō)明 error_code int 返回碼 reason string 返回說(shuō)明 result string 返回結(jié)果集 title string 新聞標(biāo)題 content string 新聞?wù)獌?nèi)容 img_width string 圖片寬度 full_title string 完整標(biāo)題 pdate string 發(fā)布時(shí)間 src string 新聞來(lái)源 img_length string 圖片高度 img string 圖片鏈接 url string 新聞鏈接 pdate_src string 發(fā)布完整時(shí)間三、系統(tǒng)實(shí)現(xiàn)代碼1:package.xinwen;importcom.thinkland.sdk.android.JuheSDKInitializer;importandroid.app.Application;importandroid.content.Context;importandroid.os.Handler;importandroid.os.Looper;/***@應(yīng)用程序的入口*/publicclassBaseApplicationextendsApplication{ privatestaticContextmContext; privatestaticThreadmMainThread; privatestaticintmMainThreadId; privatestaticHandlermMainThreadHandler; privatestaticLoopermMainThreadLooper; @Override publicvoidonCreate(){ super.onCreate(); JuheSDKInitializer.initialize(getApplicationContext()); //在應(yīng)用程序入口提供全局的工具 //上下文 mContext=this; //主線程和子線程 mMainThread=Thread.currentThread();// mMainThreadId=mMainThread.getId(); //當(dāng)前應(yīng)用程序進(jìn)程ID// mMainThreadId=android.os.Process.myPid(); //線程idmyTid(); mMainThreadId=android.os.Process.myTid(); //用戶idmyUid(); //主線程handler mMainThreadHandler=newHandler(); mMainThreadLooper=getMainLooper(); } publicstaticContextgetContext(){ returnmContext; } publicstaticThreadgetMainThread(){ returnmMainThread; } publicstaticintgetMainThreadId(){ returnmMainThreadId; } publicstaticHandlergetMainThreadHandler(){ returnmMainThreadHandler; } publicstaticLoopergetMainThreadLooper(){ returnmMainThreadLooper; }}package.xinwen;importcom.thinkland.sdk.android.JuheSDKInitializer;importandroid.app.Application;importandroid.content.Context;importandroid.os.Handler;importandroid.os.Looper;/***@應(yīng)用程序的入口*/publicclassBaseApplicationextendsApplication{ privatestaticContextmContext; privatestaticThreadmMainThread; privatestaticintmMainThreadId; privatestaticHandlermMainThreadHandler; privatestaticLoopermMainThreadLooper; @Override publicvoidonCreate(){ super.onCreate(); JuheSDKInitializer.initialize(getApplicationContext()); //在應(yīng)用程序入口提供全局的工具 //上下文 mContext=this; //主線程和子線程 mMainThread=Thread.currentThread();// mMainThreadId=mMainThread.getId(); //當(dāng)前應(yīng)用程序進(jìn)程ID// mMainThreadId=android.os.Process.myPid(); //線程idmyTid(); mMainThreadId=android.os.Process.myTid(); //用戶idmyUid(); //主線程handler mMainThreadHandler=newHandler(); mMainThreadLooper=getMainLooper(); } publicstaticContextgetContext(){ returnmContext; } publicstaticThreadgetMainThread(){ returnmMainThread; } publicstaticintgetMainThreadId(){ returnmMainThreadId; } publicstaticHandlergetMainThreadHandler(){ returnmMainThreadHandler; } publicstaticLoopergetMainThreadLooper(){ returnmMainThreadLooper; }}代碼2:/**Copyright(C)2013AndreasStuetz<andreas.stuetz@gmail>**LicensedundertheApacheLicense,Version2.0(the"License");*youmaynotusethisfileexceptincompliancewiththeLicense.*YoumayobtainacopyoftheLicenseat**:///licenses/LICENSE-2.0**Unlessrequiredbyapplicablelaworagreedtoinwriting,software*distributedundertheLicenseisdistributedonan"ASIS"BASIS,*WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.*SeetheLicenseforthespecificlanguagegoverningpermissionsand*limitationsundertheLicense.*/packageorg.xinwen.indicator.lib;importandroid.annotation.SuppressLint;importandroid.content.Context;importandroid.content.res.TypedArray;importandroid.graphics.Canvas;importandroid.graphics.Paint;importandroid.graphics.Paint.Style;importandroid.graphics.Typeface;importandroid.os.Build;importandroid.os.Parcel;importandroid.os.Parcelable;importandroid.support.v4.view.ViewPager;importandroid.support.v4.view.ViewPager.OnPageChangeListener;importandroid.util.AttributeSet;importandroid.util.DisplayMetrics;importandroid.util.TypedValue;importandroid.view.Gravity;importandroid.view.View;importandroid.view.ViewTreeObserver.OnGlobalLayoutListener;importandroid.widget.HorizontalScrollView;importandroid.widget.ImageButton;importandroid.widget.LinearLayout;importandroid.widget.TextView;importjava.util.Locale;importorg.itheima51.indicator.lib.R;publicclassTabSlidingIndicatorextendsHorizontalScrollView{ publicinterfaceIconTabProvider { publicintgetPageIconResId(intposition); } //@formatter:off privatestaticfinalint[]ATTRS=newint[]{ android.R.attr.textSize, android.R.attr.textColor}; //@formatter:on privateLinearLayout.LayoutParams defaultTabLayoutParams; privateLinearLayout.LayoutParams expandedTabLayoutParams; privatefinalPageListener pageListener =newPageListener(); publicOnPageChangeListener delegatePageListener; privateLinearLayout tabsContainer; privateViewPager pager; privateint tabCount; privateint currentPosition =0; privatefloat currentPositionOffset =0f; privatePaint rectPaint; privatePaint dividerPaint; privateint indicatorColor =0xFF666666; privateint underlineColor =0x1A000000; privateint dividerColor =0x1A000000; privateboolean shouldExpand =false; privateboolean textAllCaps =true; privateint scrollOffset =52; privateint indicatorHeight =8; privateint underlineHeight =2; privateint dividerPadding =12; privateint tabPadding =24; privateint dividerWidth =1; privateint tabTextSize =12; privateint tabTextColor =0xFF666666; privateint tabNormalTextColor =0xFF666666; privateint tabSelectedTextColor =0xFFFF0000; privateTypeface tabTypeface =null; privateint tabTypefaceStyle =Typeface.BOLD; privateint lastScrollX =0; privateint tabBackgroundResId =R.drawable.background_tab; privateLocale locale; publicTabSlidingIndicator(Contextcontext){ this(context,null); } publicTabSlidingIndicator(Contextcontext,AttributeSetattrs){ this(context,attrs,0); } publicTabSlidingIndicator(Contextcontext,AttributeSetattrs,intdefStyle){ super(context,attrs,defStyle); setFillViewport(true); setWillNotDraw(false); tabsContainer=newLinearLayout(context); tabsContainer.setOrientation(LinearLayout.HORIZONTAL); tabsContainer.setLayoutParams(newLayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); addView(tabsContainer); DisplayMetricsdm=getResources().getDisplayMetrics(); scrollOffset=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,scrollOffset,dm); indicatorHeight=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,indicatorHeight,dm); underlineHeight=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,underlineHeight,dm); dividerPadding=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,dividerPadding,dm); tabPadding=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,tabPadding,dm); dividerWidth=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_DIP,dividerWidth,dm); tabTextSize=(int)TypedValue.applyDimension(TypedValuePLEX_UNIT_SP,tabTextSize,dm); //getsystemattrs(android:textSizeandandroid:textColor) TypedArraya=context.obtainStyledAttributes(attrs,ATTRS); tabTextSize=a.getDimensionPixelSize(0,tabTextSize); tabTextColor=a.getColor(1,tabTextColor); a.recycle(); //getcustomattrs a=context.obtainStyledAttributes(attrs,R.styleable.TabSlidingIndicator); indicatorColor=a.getColor(R.styleable.TabSlidingIndicator_pstsIndicatorColor,indicatorColor); underlineColor=a.getColor(R.styleable.TabSlidingIndicator_pstsUnderlineColor,underlineColor); dividerColor=a.getColor(R.styleable.TabSlidingIndicator_pstsDividerColor,dividerColor); indicatorHeight=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsIndicatorHeight,indicatorHeight); underlineHeight=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsUnderlineHeight,underlineHeight); dividerPadding=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsDividerPadding,dividerPadding); tabPadding=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsTabPaddingLeftRight,tabPadding); tabBackgroundResId=a.getResourceId(R.styleable.TabSlidingIndicator_pstsTabBackground,tabBackgroundResId); shouldExpand=a.getBoolean(R.styleable.TabSlidingIndicator_pstsShouldExpand,shouldExpand); scrollOffset=a.getDimensionPixelSize(R.styleable.TabSlidingIndicator_pstsScrollOffset,scrollOffset); textAllCaps=a.getBoolean(R.styleable.TabSlidingIndicator_pstsTextAllCaps,textAllCaps); a.recycle(); rectPaint=newPaint(); rectPaint.setAntiAlias(true); rectPaint.setStyle(Style.FILL); dividerPaint=newPaint(); dividerPaint.setAntiAlias(true); dividerPaint.setStrokeWidth(dividerWidth); defaultTabLayoutParams=newLinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT); expandedTabLayoutParams=newLinearLayout.LayoutParams(0,LayoutParams.MATCH_PARENT,1.0f); if(locale==null) { locale=getResources().getConfiguration().locale; } } publicvoidsetViewPager(ViewPagerpager) { this.pager=pager; if(pager.getAdapter()==null){thrownewIllegalStateException("ViewPagerdoesnothaveadapterinstance.");} pager.setOnPageChangeListener(pageListener); notifyDataSetChanged(); } publicvoidsetOnPageChangeListener(OnPageChangeListenerlistener) { this.delegatePageListener=listener; } publicvoidnotifyDataSetChanged() { tabsContainer.removeAllViews(); tabCount=pager.getAdapter().getCount(); for(inti=0;i<tabCount;i++) { if(pager.getAdapter()instanceofIconTabProvider) { addIconTab(i,((IconTabProvider)pager.getAdapter()).getPageIconResId(i)); } else { addTextTab(i,pager.getAdapter().getPageTitle(i).toString()); } } updateTabStyles(); getViewTreeObserver().addOnGlobalLayoutListener(newOnGlobalLayoutListener(){ @SuppressWarnings("deprecation") @SuppressLint("NewApi") @Override publicvoidonGlobalLayout() { if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN) { getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { getViewTreeObserver().removeOnGlobalLayoutListener(this); } currentPosition=pager.getCurrentItem(); scrollToChild(currentPosition,0); if(pageListener!=null) { pageListener.onPageSelected(currentPosition); } } }); } privatevoidaddTextTab(finalintposition,Stringtitle) { TextViewtab=newTextView(getContext()); tab.setText(title); tab.setGravity(Gravity.CENTER); tab.setSingleLine(); addTab(position,tab); } privatevoidaddIconTab(finalintposition,intresId) { ImageButtontab=newImageButton(getContext()); tab.setImageResource(resId); addTab(position,tab); } privatevoidaddTab(finalintposition,Viewtab) { tab.setFocusable(true); tab.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv) { pager.setCurrentItem(position); } }); tab.setPadding(tabPadding,0,tabPadding,0); tabsContainer.addView(tab,position,shouldExpand?expandedTabLayoutParams:defaultTabLayoutParams); } privatevoidupdateTabStyles() { for(inti=0;i<tabCount;i++) { Viewv=tabsContainer.getChildAt(i); v.setBackgroundResource(tabBackgroundResId); if(vinstanceofTextView) { TextViewtab=(TextView)v; tab.setTextSize(TypedValuePLEX_UNIT_PX,tabTextSize); tab.setTypeface(tabTypeface,tabTypefaceStyle); //tab.setTextColor(tabTextColor); if(this.pager.getCurrentItem()==i) { //選錕斤拷時(shí)錕斤拷錕斤拷選錕叫碉拷錕斤拷色 tab.setTextColor(tabSelectedTextColor); } else { //沒選錕斤拷時(shí)錕斤拷錕斤拷?jīng)]選錕叫碉拷錕斤拷色 tab.setTextColor(tabNormalTextColor); } //setAllCaps()isonlyavailablefromAPI14,sotheuppercase //ismademanuallyifweareona //pre-ICS-build if(textAllCaps) { if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.ICE_CREAM_SANDWICH) { tab.setAllCaps(true); } else { tab.setText(tab.getText().toString().toUpperCase(locale)); } } } } } privatevoidscrollToChild(intposition,intoffset) { if(tabCount==0){return;} intnewScrollX=tabsContainer.getChildAt(position).getLeft()+offset; if(position>0||offset>0) { newScrollX-=scrollOffset; } if(newScrollX!=lastScrollX) { lastScrollX=newScrollX; scrollTo(newScrollX,0); } } @Override protectedvoidonDraw(Canvascanvas) { super.onDraw(canvas); if(isInEditMode()||tabCount==0){return;} finalintheight=getHeight(); //drawindicatorline rectPaint.setColor(indicatorColor); //default:linebelowcurrenttab ViewcurrentTab=tabsContainer.getChildAt(currentPosition); floatlineLeft=currentTab.getLeft(); floatlineRight=currentTab.getRight(); //ifthereisanoffset,startinterpolatingleftandrightcoordinates //betweencurrentandnexttab if(currentPositionOffset>0f&¤tPosition<tabCount-1) { ViewnextTab=tabsContainer.getChildAt(currentPosition+1); finalfloatnextTabLeft=nextTab.getLeft(); finalfloatnextTabRight=nextTab.getRight(); lineLeft=(currentPositionOffset*nextTabLeft+(1f-currentPositionOffset)*lineLeft); lineRight=(currentPositionOffset*nextTabRight+(1f-currentPositionOffset)*lineRight); } canvas.drawRect(lineLeft,height-indicatorHeight,lineRight,height,rectPaint); //drawunderline rectPaint.setColor(underlineColor); canvas.drawRect(0,height-underlineHeight,tabsContainer.getWidth(),height,rectPaint); //drawdivider dividerPaint.setColor(dividerColor); for(inti=0;i<tabCount-1;i++) { Viewtab=tabsContainer.getChildAt(i); canvas.drawLine(tab.getRight(),dividerPadding,tab.getRight(),height-dividerPadding,dividerPaint); } } privateclassPageListenerimplementsOnPageChangeListener { @Override publicvoidonPageScrolled(intposition,floatpositionOffset,intpositionOffsetPixels) { currentPosition=position; currentPositionOffset=positionOffset; scrollToChild(position,(int)(positionOffset*tabsContainer.getChildAt(position).getWidth())); invalidate(); if(delegatePageListener!=null) { delegatePageListener.onPageScrolled(position,positionOffset,positionOffsetPixels); } } @Override publicvoidonPageScrollStateChanged(intstate) { if(state==ViewPager.SCROLL_STATE_IDLE) { scrollToChild(pager.getCurrentItem(),0); } if(delegatePageListener!=null) { delegatePageListener.onPageScrollStateChanged(state); } } @Override publicvoidonPageSelected(intposition) { if(delegatePageListener!=null) { delegatePageListener.onPageSelected(position); } updateTabStyles(); } } publicvoidsetIndicatorColor(intindicatorColor) { this.indicatorColor=indicatorColor; invalidate(); } publicvoidsetIndicatorColorResource(intresId) { this.indicatorColor=getResources().getColor(resId); invalidate(); } publicintgetIndicatorColor() { returnthis.indicatorColor; } publicvoidsetIndicatorHeight(intindicatorLineHeightPx) { this.indicatorHeight=indicatorLineHeightPx; invalidate(); } publicintgetIndicatorHeight() { returnindicatorHeight; } publicvoidsetUnderlineColor(intunderlineColor) { this.underlineColor=underlineColor; invalidate(); } publicvoidsetUnderlineColorResource(intresId) { this.underlineColor=getResources().getColor(resId); invalidate(); } publicintgetUnderlineColor() { returnunderlineColor; } publicvoidsetDividerColor(intdividerColor) { this.dividerColor=dividerColor; invalidate(); } publicvoidsetDividerColorResource(intresId) { this.dividerColor=getResources().getColor(resId); invalidate(); } publicintgetDividerColor() { returndividerColor; } publicvoidsetUnderlineHeight(intunderlineHeightPx) { this.underlineHeight=underlineHeightPx; invalidate(); } publicintgetUnderlineHeight() { returnunderlineHeight; } publicvoidsetDividerPadding(intdividerPaddingPx) { this.dividerPadding=dividerPaddingPx; invalidate(); } publicintgetDividerPadding() { returndividerPadding; } publicvoidsetScrollOffset(intscrollOffsetPx) { this.scrollOffset=scrollOffsetPx; invalidate(); } publicintgetScrollOffset() { returnscrollOffset; } publicvoidsetShouldExpand(booleanshouldExpand) { this.shouldExpand=shouldExpand; requestLayout(); } publicbooleangetShouldExpand() { returnshouldExpand; } publicbooleanisTextAllCaps() { returntextAllCaps; } publicvoidsetAllCaps(booleantextAllCaps) { this.textAllCaps=textAllCaps; } publicvoidsetTextSize(inttextSizePx) { this.tabTextSize=textSizePx; updateTabStyles(); } publicintgetTextSize() { returntabTextSize; } publicvoidsetTextColor(inttextColor) { this.tabTextColor=textColor; updateTabStyles(); } publicvoidsetTextColor(inttextNormalColor,inttextSelectedColor) { this.tabNormalTextColor=textNormalColor; this.tabSelectedTextColor=textSelectedColor; updateTabStyles(); } publicvoidsetTextColorResource(intresId) { this.tabTextColor=getResources().getColor(resId); updateTabStyles(); } publicintgetTextColor() { returntabTextColor; } publicvoidsetTypeface(Typefacetypeface,intstyle) { this.tabTypeface=typeface; this.tabTypefaceStyle=style; updateTabStyles(); } publicvoidsetTabBackground(intresId) { this.tabBackgroundResId=resId; } publicintgetTabBackground() { returntabBackgroundResId; } publicvoidsetTabPaddingLeftRight(intpaddingPx) { this.tabPadding=paddingPx; updateTabStyles(); } publicintgetTabPaddingLeftRight() { returntabPadding; } @Override publicvoidonRestoreInstanceState(Parcelablestate) { SavedStatesavedState=(SavedState)state; super.onRestoreInstanceState(savedState.getSuperState()); currentPosition=savedState.currentPosition; requestLayout(); } @Override publicParcelableonSaveInstanceState() { ParcelablesuperState=super.onSaveInstanceState(); SavedStatesavedState=newSavedState(superState); savedState.currentPosition=currentPosition; returnsavedState; } staticclassSavedStateextendsBaseSavedState { int currentPosition; publicSavedState(ParcelablesuperState){ super(superState); } privateSavedState(Parcelin){ super(in); currentPosition=in.readInt(); } @Override publicvoidwriteToParcel(Parceldest,intflags) { super.writeToParcel(dest,flags); dest.writeInt(currentPosition); } publicstaticfinalParcelable.Creator<SavedState> CREATOR =newParcelable.Creator<SavedState>(){ @Override publicSavedStatecreateFromParcel(Parcelin) { returnnewSavedState(in); } @Override publicSavedState[]newArray(intsize) { returnnewSavedState[size]; } }; }}代碼3:*Copyright(c)2013.wyouflf(wyouflf@gmail)**LicensedundertheApacheLicense,Version2.0(the"License");*youmaynotusethisfileexceptincompliancewiththeLicense.*YoumayobtainacopyoftheLicenseat**:///licenses/LICENSE-2.0*Unlessrequiredbyapplicablelaworagreedtoinwriting,software*distributedundertheLicenseisdistributedonan"ASIS"BASIS,*WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.*SeetheLicenseforthespecificlanguagegoverningpermissionsand*limitationsundertheLicense.*/packagecom.lidroid.xutils;importandroid.content.Context;importandroid.graphics.Bitmap;importandroid.graphics.drawable.BitmapDrawable;importandroid.graphics.drawable.Drawable;importandroid.text.TextUtils;importandroid.view.View;importandroid.view.animation.Animation;importcom.lidroid.xutils.bitmap.BitmapCacheListener;importcom.lidroid.xutils.bitmap.BitmapCommonUtils;importcom.lidroid.xutils.bitmap.BitmapDisplayConfig;importcom.lidroid.xutils.bitmap.BitmapGlobalConfig;importcom.lidroid.xutils.bitmap.callback.BitmapLoadCallBack;importcom.lidroid.xutils.bitmap.callback.BitmapLoadFrom;importcom.lidroid.xutils.bitmap.callback.DefaultBitmapLoadCallBack;importcom.lidroid.xutils.bitmap.core.AsyncDrawable;importcom.lidroid.xutils.bitmap.core.BitmapSize;importcom.lidroid.xutils.bitmap.download.Downloader;importcom.lidroid.xutils.cache.FileNameGenerator;importcom.lidroid.xutils.task.PriorityAsyncTask;importcom.lidroid.xutils.task.PriorityExecutor;importcom.lidroid.xutils.task.TaskHandler;importjava.io.File;importjava.lang.ref.WeakReference;publicclassBitmapUtilsimplementsTaskHandler{privatebooleanpauseTask=false;privatebooleancancelAllTask=false;privatefinalObjectpauseTaskLock=newObject();privateContextcontext;privateBitmapGlobalConfigglobalConfig;privateBitmapDisplayConfigdefaultDisplayConfig;///////////////////////////////////////////////create///////////////////////////////////////////////////publicBitmapUtils(Contextcontext){

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論