仿京東商城系列18------xml文件讀任龊(地址選擇器)

本項目來自菜鳥窩佑菩,有興趣者點擊http://www.cniao5.com/course/

項目已經(jīng)做完绞幌,
https://github.com/15829238397/CN5E-shop


仿京東商城系列0------項目簡介
仿京東商城系列1------fragmentTabHost實現(xiàn)底部導航欄
仿京東商城系列2------自定義toolbar
仿京東商城系列3------封裝Okhttp
仿京東商城系列4------輪播廣告條
仿京東商城系列5------商品推薦欄
仿京東商城系列6------下拉刷新上拉加載的商品列表
仿京東商城系列7------商品分類頁面
仿京東商城系列8------自定義的數(shù)量控制器
仿京東商城系列9------購物車數(shù)據(jù)存儲器實現(xiàn)
仿京東商城系列10------添加購物車,管理購物車功能實現(xiàn)
仿京東商城系列11------商品排序功能以及布局切換實現(xiàn)(Tablayout)
仿京東商城系列12------商品詳細信息展示(nativie與html交互)
仿京東商城系列13------商品分享(shareSDK)
仿京東商城系列14------用戶登錄以及app登錄攔截
仿京東長城系列15------用戶注冊,SMSSDK集成
仿京東商城系列16------支付SDK集成
仿京東商城系列17------支付功能實現(xiàn)
仿京東商城系列18------xml文件讀刃呱帧(地址選擇器)
仿京東商城系列19------九宮格訂單展示
仿京東商城系列20------終章


前言

我們接著上一更的內(nèi)容畏浆,上一更我們集成并使用了支付SDK完成了模擬支付。但我們的訂單編輯頁面地址與收貨人信息一欄還是空白,今天我們要做的就是填充這個空白。效果圖如下:

地址選擇器.gif

內(nèi)容

補充新知識

xml文件讀取

解析方式

1、DOM解析器
DOM(Document Object Model) 是一種用于XML文檔的對象模型,可用于直接訪問XML文檔的各個部分胶背。它是一次性全部將內(nèi)容加載在內(nèi)存中,生成一個樹狀結(jié)構(gòu),它沒有涉及回調(diào)和復雜的狀態(tài)管理。 缺點是加載大文檔時效率低下,所以一般在解析大文檔時不建議使用DOM解析岳服。
分析該結(jié)構(gòu)通常需要加載整個文檔和構(gòu)造樹形結(jié)構(gòu)贫母,然后才可以檢索和更新節(jié)點信息。Android完全支持DOM 解析趾断。利用DOM中的對象脐帝,可以對XML文檔進行讀取疚顷、搜索届垫、修改妄迁、添加和刪除等操作。
DOM的工作原理:使用DOM對XML文件進行操作時,首先要解析文件流妻,將文件分為獨立的元素、屬性和注釋等,然后以節(jié)點樹的形式在內(nèi)存中對XML文件進行表示浑度,就可以通過節(jié)點樹訪問文檔的內(nèi)容,并根據(jù)需要修改文檔横漏。
常用的DOM的接口和類:
Document:該接口定義分析并創(chuàng)建DOM文檔的一系列方法,它是文檔樹的根二蓝,是操作DOM的基礎。
Node:該接口提供處理并獲取節(jié)點和子節(jié)點值的方法。
Element:該接口繼承Node接口,提供了獲取炬藤、修改XML元素名字和屬性的方法并闲。
NodeList:提供獲得節(jié)點個數(shù)和當前節(jié)點的方法溜徙。這樣就可以迭代地訪問各個節(jié)點九巡。
DOMParser:該類是Apache的Xerces中的DOM解析器類疏日,可直接解析XML文件。

2宾肺、SAX解析
SAX(Simple API for XML) 使用流式處理的方式,它并不記錄所讀內(nèi)容的相關(guān)信息。它是一種以事件為驅(qū)動的XML API,解析速度快熄求,占用內(nèi)存少渣玲。使用回調(diào)函數(shù)來實現(xiàn)。 缺點是因為以事件為驅(qū)動的它不能回退弟晚。
它的核心是事件處理模式忘衍,主要是圍繞著事件源以及事件處理器來工作的卿城。當事件源產(chǎn)生事件后拣凹,調(diào)用事件處理器相應的處理方法节腐,一個事件就可以得到處理。在事件源調(diào)用事件處理器中特定方法的時候,還要傳遞給事件處理器相應事件的狀態(tài)信息徽职,這樣事件處理器才能夠根據(jù)提供的事件信息來決定自己的行為怠蹂。
SAX的工作原理:SAX會順序掃描文檔剧蹂,在掃描到文檔(document)開始與結(jié)束爆安、元素(element)開始與結(jié)束、元素內(nèi)容(characters)等時通知事件處理方法怀偷,事件處理方法進行相應處理家厌,然后繼續(xù)掃描,指導文檔掃描結(jié)束椎工。
常用的SAX接口和類:
Attrbutes:用于得到屬性的個數(shù)饭于、名字和值。
ContentHandler:定義與文檔本身關(guān)聯(lián)的事件(例如维蒙,開始和結(jié)束標記)掰吕。大多數(shù)應用程序都注冊這些事件木西。
DTDHandler:定義與DTD關(guān)聯(lián)的事件畴栖。它沒有定義足夠的事件來完整地報告DTD。如果需要對DTD進行語法分析八千,請使用可選的DeclHandler吗讶。
DeclHandler是SAX的擴展。不是所有的語法分析器都支持它恋捆。
EntityResolver:定義與裝入實體關(guān)聯(lián)的事件照皆。只有少數(shù)幾個應用程序注冊這些事件。
ErrorHandler:定義錯誤事件沸停。許多應用程序注冊這些事件以便用它們自己的方式報錯膜毁。
DefaultHandler:它提供了這些接LI的缺省實現(xiàn)。在大多數(shù)情況下愤钾,為應用程序擴展DefaultHandler并覆蓋相關(guān)的方法要比直接實現(xiàn)一個接口更容易瘟滨。
下面是部分說明:

SAX處理器說明

部分常用方法說明

    所以,我們通常要使用XmlReader和DefaultHandler配合起來解析xml文檔能颁。
    SAX的解析流程:

startDocument --> startElement --> characters --> endElement --> endDocument

3杂瘸、pull解析
Pull內(nèi)置于Android系統(tǒng)中。也是官方解析布局文件所使用的方式伙菊。Pull與SAX有點類似败玉,都提供了類似的事件,如開始元素和結(jié)束元素镜硕。不同的是运翼,SAX的事件驅(qū)動是回調(diào)相應方法,需要提供回調(diào)的方法兴枯,而后在SAX內(nèi)部自動調(diào)用相應的方法血淌。而Pull解析器并沒有強制要求提供觸發(fā)的方法。因為他觸發(fā)的事件不是一個方法财剖,而是一個數(shù)字悠夯。它使用方便,效率高峰伙。Android官方推薦開發(fā)者們使用Pull解析技術(shù)疗疟。Pull解析技術(shù)是第三方開發(fā)的開源技術(shù),它同樣可以應用于JavaSE開發(fā)瞳氓。
pull返回的常量:
讀取到xml的聲明返回 START_DOCUMENT;
讀取到xml的結(jié)束返回 END_DOCUMENT ;
讀取到xml的開始標簽返回 START_TAG;
讀取到xml的結(jié)束標簽返回 END_TAG;
讀取到xml的文本返回 TEXT;
pull的工作原理:pull提供了開始元素和結(jié)束元素策彤。當某個元素開始時,我們可以調(diào)用parser.nextText從XML文檔中提取所有字符數(shù)據(jù)匣摘。當解釋到一個文檔結(jié)束時店诗,自動生成EndDocument事件。
常用的XML pull的接口和類:
XmlPullParser:XML pull解析器是一個在XMLPULL VlAP1中提供了定義解析功能的接口音榜。
XmlSerializer:它是一個接口庞瘸,定義了XML信息集的序列。
XmlPullParserFactory:這個類用于在XMPULL V1 API中創(chuàng)建XML Pull解析器赠叼。
XmlPullParserException:拋出單一的XML pull解析器相關(guān)的錯誤擦囊。
pull的解析流程:
start_document --> end_document --> start_tag -->end_tag

**在Android中還有第四種方式:android.util.Xml類 **(本人未使用過)
在Android API中违霞,另外提供了Android.util.Xml類,同樣可以解析XML文件瞬场,使用方法類似SAX买鸽,也都需編寫Handler來處理XML的解析,但是在使用上卻比SAX來得簡單 贯被,如下所示:
以android.util.XML實現(xiàn)XML解析 :
MyHandler myHandler=new MyHandler0眼五;
android.util.Xm1.parse(url.openC0nnection().getlnputStream(),Xml.Encoding.UTF-8彤灶,myHandler)看幼;

代碼講解

了解完概念,我們就可以著手解析xml文件了幌陕。接下來我來講述以下解析xml文件的步驟诵姜。

  • 將xml文件放在main->assets目錄下。
  • 新建一個類XmlParserHandler繼承DefaultHandler苞轿,并實現(xiàn)相關(guān)方法茅诱。代碼如下:
    xml文件:
<root>
  <province name="安徽省">
    <city name="安慶市">
      <district name="樅陽縣" zipcode="246000" />
      <district name="大觀區(qū)" zipcode="246000" />
      <district name="懷寧縣" zipcode="246000" />
      <district name="潛山縣" zipcode="246000" />
      <district name="宿松縣" zipcode="246000" />
      <district name="太湖縣" zipcode="246000" />
      <district name="桐城市" zipcode="246000" />
      <district name="望江縣" zipcode="246000" />
      <district name="宜秀區(qū)" zipcode="246000" />
      <district name="迎江區(qū)" zipcode="246000" />
      <district name="岳西縣" zipcode="246000" />
      <district name="其他" zipcode="246000" />
    </city>
    ......

XmlParserHandler類代碼:

package com.example.cne_shop.bean.city;

import android.util.Log;

import com.example.cne_shop.bean.city.model.CityModel;
import com.example.cne_shop.bean.city.model.DistrictModel;
import com.example.cne_shop.bean.city.model.PrivinceModel;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.util.ArrayList;
import java.util.List;

import static android.content.ContentValues.TAG;

/**
 * Created by 博 on 2017/7/27.
 */

public class XmlParserHandler extends DefaultHandler {

    private List<PrivinceModel> privinceModels ;
    private List<CityModel> cityModels ;
    private List<DistrictModel> districtModels ;
    private PrivinceModel privinceModel ;
    private DistrictModel districtModel ;
    private CityModel cityModel ;
    private String preTag ;

    public List<PrivinceModel> getPrivinceModels() {
        return privinceModels;
    }

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        privinceModels = new ArrayList<>() ;

        Log.d(TAG, "startDocument: ------------------------------");

        //當讀到第一個標簽的時候會觸發(fā)這個方法
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        //開始解析節(jié)點

        if ("province".equals(localName)){

            Log.d(TAG, "新建省: --------------------------------------------");
            cityModels = new ArrayList<>() ;
            privinceModel = new PrivinceModel() ;
            privinceModel.setName(attributes.getValue("name") );

        }else if ("city".equals(localName)){

            districtModels = new ArrayList<>() ;
            cityModel = new CityModel() ;
            cityModel.setName(attributes.getValue("name") );
        }else if ("district".equals(localName)){

            districtModel = new DistrictModel() ;
            districtModel.setName(attributes.getValue("name") );
            districtModel.setZipcode(attributes.getValue("zipcode") );
        }

        preTag = localName ;

    }

    public void endDocument () {
        //文檔解析結(jié)束
        Log.d(TAG, "endDocument: --------------------------------------------");

    }

    public void characters (char[] ch, int start, int length) {
        //保存節(jié)點內(nèi)容

   if ("province".equals(preTag)){
            privinceModels.add(privinceModel) ;
            Log.d(TAG, "添加省: --------------------------------------------");

        }else if ("city".equals(preTag)){
            cityModels.add(cityModel) ;
            privinceModel.setCityModels(cityModels);
       Log.d(TAG, "添加市: --------------------------------------------");
        }else if ("district".equals(preTag)){
            districtModels.add(districtModel) ;
            cityModel.setDistrictModels(districtModels);
       Log.d(TAG, "添加縣: --------------------------------------------");
        }

        preTag = null ;

    }

    public void endElement (String uri, String localName, String qName) {
        //結(jié)束解析節(jié)點

        Log.d(TAG, "endElement: ------------------------"+ uri + "   " + localName + " " + qName);
    }
}
  • 調(diào)用新建類XmlParserHandler代碼如下:
 SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XmlParserHandler sfh = new XmlParserHandler();

        AssetManager am = this.getAssets();
        InputStream is = am.open("province_data.xml");

        sp.parse(is , sfh);
        getAdrMsg(sfh.getPrivinceModels()) ;

地址選擇器實現(xiàn)

pickerView簡介

這是一款仿iOS的PickerView控件,有時間選擇和選項選擇搬卒,并支持一二三級聯(lián)動,支持自定義樣式摆寄,3.x新版本的詳細特性如下:

有時間和選項這兩種選擇器
選項選擇器支持三級聯(lián)動
時間選擇器支持起始和終止日期設定
支持“年微饥,月古戴,日肃续,時始锚,分瞧捌,秒”殿怜,“省赠法,市砖织,區(qū)”等選項的單位(label)顯示新锈、隱藏和自定義妹笆。
支持自定義文字、顏色窟坐、文字大小等屬性
支持背景顏色更換,有夜間模式需求的問題可以解決了
Item的文字長度過長時徙菠,文字會自適應縮放到Item的長度,避免顯示不完全的問題
——TimePickerView 時間選擇器脸秽,支持年月日時分,年月日片酝,年月练湿,時分等格式
——OptionsPickerView 選項選擇器,支持一篡诽,二,三級選項選擇,并且可以設置是否聯(lián)動

TimePickerNight.gif
TimePickerNight.gif

Province.gif
Province.gif
CustomLayout.gif
CustomLayout.gif

pickerView代碼調(diào)用

下面是地址選擇器的代碼調(diào)用

   OptionsPickerView  pvOptions = new  OptionsPickerView.Builder(this, new OptionsPickerView.OnOptionsSelectListener() {
            @Override
            public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
                //返回的分別是三個級別的選中位置
                consigneeAdr.setText(province.get(options1) + city.get(options1).get(option2) + county.get(options1).get(option2).get(options3));
                zip_code = zip_codes.get(options1).get(option2).get(options3) ;
            }
        })
                .setSubmitText("確定")//確定按鈕文字
                .setCancelText("取消")//取消按鈕文字
                .setTitleText("城市選擇")//標題
                .setSubCalSize(18)//確定和取消文字大小
                .setTitleSize(20)//標題文字大小
                .setTitleColor(Color.BLACK)//標題文字顏色
                .setSubmitColor(Color.BLACK)//確定按鈕文字顏色
                .setCancelColor(Color.BLACK)//取消按鈕文字顏色
                .setTitleBgColor(Color.WHITE)//標題背景顏色 Night mode
                .setBgColor(Color.WHITE)//滾輪背景顏色 Night mode
                .setContentTextSize(18)//滾輪文字大小
//                .setLinkage(false)//設置是否聯(lián)動,默認true
                .setLabels("", "", "")//設置選擇的三級單位
                .isCenterLabel(false) //是否只顯示中間選中項的label文字,false則每項item全部都帶有l(wèi)abel啃憎。
                .setCyclic(false, false, false)//循環(huán)與否
                .setSelectOptions(1, 1, 1)  //設置默認選中項
                .setOutSideCancelable(false)//點擊外部dismiss default true
                .isDialog(true)//是否顯示為對話框樣式
                .build();

//        Log.d("----" , "--------------"+county.get(1).get(1).get(1)) ;

        pvOptions.setPicker(province, city  , county);//添加數(shù)據(jù)源
        pvOptions.show();

沒有什么要講了的羡藐,都在注釋里,這樣我們就可以調(diào)用好玩的地址選擇器啦仆嗦。


其他部分沒有什么要說的辉阶,就是簡單布局谆甜,網(wǎng)絡申請,處理信息,布拉布拉。完整代碼請戳頁首github地址掠河。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市奉瘤,隨后出現(xiàn)的幾起案子勾拉,更是在濱河造成了極大的恐慌,老刑警劉巖卖局,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斧蜕,死亡現(xiàn)場離奇詭異砚偶,居然都是意外死亡批销,警方通過查閱死者的電腦和手機染坯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來单鹿,“玉大人掀宋,你說我怎么就攤上這事〔茧” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵是趴,是天一觀的道長涛舍。 經(jīng)常有香客問我,道長唆途,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任没佑,我火速辦了婚禮温赔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘陶贼。我一直安慰自己,他們只是感情好拜秧,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布枉氮。 她就那樣靜靜地躺著,像睡著了一般聊替。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上佃牛,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天俘侠,我揣著相機與錄音,去河邊找鬼爷速。 笑死,一個胖子當著我的面吹牛惫东,可吹牛的內(nèi)容都是我干的毙石。 我是一名探鬼主播颓遏,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼叁幢,長吁一口氣:“原來是場噩夢啊……” “哼滤灯!你這毒婦竟也來了曼玩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤豫尽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后顷帖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體美旧,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡窟她,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趴腋。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡优炬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蠢护,到底是詐尸還是另有隱情,我是刑警寧澤眉抬,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布懈凹,位于F島的核電站,受9級特大地震影響介评,放射性物質(zhì)發(fā)生泄漏爬舰。R本人自食惡果不足惜寒瓦,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一杂腰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧颈墅,春花似錦、人聲如沸恤筛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽煎殷。三九已至,卻和暖如春豪直,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背末融。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工暇韧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人巧婶。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓涂乌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親骂倘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,071評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫漾唉、插件堰塌、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,093評論 4 62
  • 旭日的東升, 喚醒我沉睡的意識般此; 一盆水的清洗, 褪去我朦朧的瞳目铐懊。 清晨的校園瞎疼, 是希望醞釀的溫床; 一本書的滋...
    筆觸流年閱讀 4,985評論 6 5
  • 1.管理者就是做好示范作用贼急,事事先行,你就是你部隊的靈魂空闲,你決定你的團隊的好壞走敌!一切取決于你碴倾。 2.競爭掉丽,人天生懶...
    風清楊閱讀 167評論 0 1
  • 記得很早以前机打,也就是上個世紀末,看國足沖擊法國世界杯的“十強賽”片迅,有兩個印象深刻的廣告,一個是“愛立信”GS768...
    今又十年閱讀 247評論 0 0