仿百度地圖街景實(shí)現(xiàn)

使用過百度地圖的同學(xué)知道痊银,它有個(gè)街景功能溯革,可以看到許多地方的實(shí)景致稀。這里就其街景內(nèi)容的實(shí)現(xiàn)俱尼,進(jìn)行下學(xué)習(xí)遇八。

百度地圖SDK的官網(wǎng)上可以看到刃永,百度對(duì)開發(fā)者提供了很多相關(guān)的內(nèi)容,方便我們進(jìn)行學(xué)習(xí)囚玫。關(guān)于SDK的使用方法抓督,包括jar包導(dǎo)入本昏,*.so 動(dòng)態(tài)庫的添加位置及AndroidManifest文件的配置不做為我們這里討論的內(nèi)容,官方文檔已經(jīng)介紹的很詳細(xì)怔昨,不做無聊的搬運(yùn)工趁舀。

效果圖##

這里我們首先預(yù)覽下矮烹,今天最終要實(shí)現(xiàn)的效果圖

靜態(tài)圖1

靜態(tài)圖2

效果圖

如圖所示奉狈,我們這里的實(shí)現(xiàn)仁期,就是兩個(gè)頁面的內(nèi)容跛蛋,一個(gè)是基礎(chǔ)的地圖MapView痊硕,一個(gè)是街景地圖PanoView岔绸。接下來亭螟,就這兩個(gè)頁面(Activity)分別展開來說骑歹。(由于GIF圖片大小限制道媚,效果不是很理想,文章結(jié)尾有源碼地址谴分,可以自己跑一下看一下效果先)

地圖MapView實(shí)現(xiàn)##

地圖MapView的簡(jiǎn)單顯示###

布局文件####

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />
    </LinearLayout>

Application####

一般情況下牺蹄,我們的應(yīng)用程序都會(huì)有一個(gè)繼承自Application的類沙兰,用于實(shí)現(xiàn)一些初始化的方法鼎天,這里可以在Application里執(zhí)行一些百度地圖初始化的工作斋射,這也是官方提倡的方式。

public void onCreate() {
        super.onCreate();
        mInstance = this;  
   SDKInitializer.initialize(getApplicationContext());
        }

Activity####

在Activity的OnCreate方法中實(shí)現(xiàn)

setContentView(R.layout.activity_mapview);
mMapView = (MapView) findViewById(R.id.bmapView);

上面這樣一段簡(jiǎn)單的代碼涧至,就可以在Activity中顯示出一個(gè)MapView桑包,也就是我們最熟悉的地圖頁面捡多,是不是很簡(jiǎn)單垒手,就像我們顯示一個(gè)TextView一樣。

這里說明寫一下泳梆,按照官方的API指導(dǎo)文檔优妙,使用MapView等百度地圖SDK所提供的各種實(shí)現(xiàn)套硼,是需要去申請(qǐng)相關(guān)的key的胞皱,申請(qǐng)的方法在官網(wǎng)有著詳細(xì)的介紹,這里就不再粘貼復(fù)制了萌朱;很多同學(xué)在使用MapView的時(shí)候發(fā)現(xiàn)晶疼,程序運(yùn)行后地圖沒有顯示又憨,顯示的都是一些方格子竟块,這往往是由于key沒有申請(qǐng)浪秘,或申請(qǐng)的方式不當(dāng)造成的

MapView顯示到當(dāng)前位置###

每次打開百度地圖耸携,都會(huì)自動(dòng)定位到我們當(dāng)前所在的位置,或者是我們搜索某個(gè)特定的地方作為新的位置狈谊,整個(gè)地圖所呈現(xiàn)的區(qū)域都是新位置周邊的環(huán)境河劝。這里赎瞎,關(guān)于地圖的定位和搜索的相關(guān)實(shí)現(xiàn)內(nèi)容颊咬,就不展開來說喳篇,不當(dāng)做此次的重點(diǎn)麸澜。

假設(shè)我們已通過定位(或者是搜索),定位了到了一個(gè)位置

**
 * 假設(shè)我們當(dāng)前的位置在此
 */
private final double latitude = 39.963175;
private final double longitude = 116.400244;

這個(gè)位置按照新聞里常聽到的說法就是,東經(jīng)116.40度洽沟,北緯39.96度,位于北京市東城區(qū)舊鼓樓大街丙1號(hào)蜗细。

接下來炉媒,我們要做的就是將MapView的視圖更新到我們“定位”的位置吊骤,這個(gè)位置周邊的地圖才是我們關(guān)心的白粉。

mBaiduMap = mMapView.getMap();
        //定義Maker坐標(biāo)點(diǎn)
        point = new LatLng(latitude, longitude);
        //定義地圖狀態(tài)
        final MapStatus mMapStatus = new MapStatus.Builder()
                .target(point)
                .zoom(18)
                .build();
        //定義MapStatusUpdate對(duì)象鸭巴,以便描述地圖狀態(tài)將要發(fā)生的變化
        MapStatusUpdate mMapStatusUpdate = 
MapStatusUpdateFactory.newMapStatus(mMapStatus);
        //改變地圖狀態(tài)
        mBaiduMap.setMapStatus(mMapStatusUpdate);

這里的mBaiduMap 是一個(gè)BaiduMap的實(shí)例鹃祖,通過MapView的getMap方法即可獲得恬口。我們對(duì)地圖的各種操作祖能,設(shè)置屬性都是基于這個(gè)實(shí)例進(jìn)行。

通過上面的代碼端考,我們就可以將MapView的視圖更新到我們所想要的位置了却特。

添加View到MapView###

添加Marker####

按照百度地圖API的說法裂明,我們添加到地圖上的小圖標(biāo)統(tǒng)一稱為Marker闽晦。

//構(gòu)建Marker圖標(biāo)
        bitmap = BitmapDescriptorFactory
                .fromResource(R.drawable.icon_markc);

        //構(gòu)建MarkerOption仙蛉,用于在地圖上添加Marker
        option = new MarkerOptions()
                .position(point)
                .icon(bitmap);
        //在地圖上添加Marker荠瘪,并顯示
        mBaiduMap.addOverlay(option);

通過上面的實(shí)現(xiàn)哀墓,我們就可以將一個(gè)小圖標(biāo)添加到地圖層,作為標(biāo)記后雷。我們?nèi)粘J褂玫貓D時(shí)喷面,所搜周邊后呈現(xiàn)的一系列小圓點(diǎn)就是如此(如下圖)

marker示意圖

ShowInfoWindow使用####

最后一步惧辈,實(shí)現(xiàn)顯示街景縮略圖的那個(gè)小彈框盒齿。

這里首先自定義一下我們要添加到地圖層的View边翁。

view = LayoutInflater.from(mContext).inflate(R.layout.pano_overlay, null);
        pic = (ImageView) view.findViewById(R.id.panoImageView);
view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(mContext, PanoDemoMain.class);
                intent.putExtra("latitude", latitude);
                intent.putExtra("longitude", longitude);
                startActivity(intent);
            }
        });

這里pic這個(gè)ImageView用于顯示我們要展示的街景縮略圖符匾。pano_overlay是整個(gè)彈框的布局啊胶,很簡(jiǎn)單焰坪,這里就不貼代碼了。

同時(shí)聘惦,我們?yōu)檫@個(gè)自定義View設(shè)置點(diǎn)擊事件某饰,方便我們跳轉(zhuǎn)到PanoView街景地圖頁面,并且將當(dāng)前位置傳遞過去。

由于祖國地大物博黔漂,所以街景的覆蓋并非百分之百搁胆,所以說晶默,不是每個(gè)地方都有街景可以顯示略板,有些鳥不拉屎的地方是看不到的。那我們?cè)趺粗朗裁吹胤接薪志澳乩徒希緼PI為我們提供了很好的檢測(cè)方法

new Thread(new Runnable() {
            @Override
            public void run() {
                PanoramaRequest request = 
PanoramaRequest.getInstance(mContext);
                BaiduPanoData locationPanoData = 
request.getPanoramaInfoByLatLon(longitude, latitude);
                //開發(fā)者可以判斷是否有外景(街景)
                if (locationPanoData.hasStreetPano()) {
                    String url = baseUrl + locationPanoData.getPid();
                    Message message = new Message();
                    message.what = 0x01;
                    message.obj = url;
                    handler.sendMessage(message);
                }

            }
        }).start();

這樣驹止,我們就可以根據(jù)當(dāng)前位置浩聋,先檢測(cè)一下是否有街景可以顯示观蜗。這里,如果當(dāng)前位置有街景衣洁,我們就通過Handler通知主線程去更新UI

private class myHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0x01) {
                String url = (String) msg.obj;
                Glide.with(mContext).load(url).into(pic);
                InfoWindow mInfoWindow = new InfoWindow(view, point, -57);
                //顯示InfoWindow
                mBaiduMap.showInfoWindow(mInfoWindow);
            }
        }
    }

這里看一下墓捻,InfoWindow的說明及其構(gòu)造函數(shù)

public class InfoWindow extends java.lang.Object
在地圖中顯示一個(gè)信息窗口,可以設(shè)置一個(gè)View作為該窗口的內(nèi)容坊夫,也可以設(shè)置一個(gè) BitmapDescriptor 作為該窗口的內(nèi)容砖第。


public InfoWindow(View view, LatLng position, int yOffset)

/**
通過傳入的 view 構(gòu)造一個(gè) InfoWindow, 此時(shí)只是利用該view
生成一個(gè)Bitmap繪制在地圖中,監(jiān)聽事件由開發(fā)者實(shí)現(xiàn)环凿。
Parameters:
view - InfoWindow 展示的 view
position - InfoWindow 顯示的地理位置
yOffset - InfoWindow Y 軸偏移量
*/

在Handler的handleMessage方法中梧兼,我們通過返回的url加載圖片,并將自定義的彈框View顯示到之前一步添加的marker偏上一點(diǎn)的地方(這就是InfoWindow的構(gòu)造函數(shù)中-57的意義)

關(guān)于這個(gè)加載圖片的URL智听,可以參考這里靜態(tài)圖API羽杰。

這樣,就實(shí)現(xiàn)了MapView頁面所有的內(nèi)容到推。通過點(diǎn)擊InfoWindow考赛,就可以跳轉(zhuǎn)到PanoView所在的界面去查看街景地圖。

接下來莉测,我們將介紹PanoView街景地圖的實(shí)現(xiàn)颜骤。

街景地圖PanoViewActivity實(shí)現(xiàn)##

街景地圖PanoView基礎(chǔ)###

街景地圖PanoView的顯示和基礎(chǔ)地圖MapView十分相似

首先是在布局文件中定義view

<com.baidu.lbsapi.panoramaview.PanoramaView
            android:id="@+id/panorama"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:visibility="visible" />

Activity的OnCreate方法中

PanoDemoApplication app = (PanoDemoApplication) this.getApplication();
        if (app.mBMapManager == null) {
            app.mBMapManager = new BMapManager(app);
            app.mBMapManager.init(new 
PanoDemoApplication.MyGeneralListener());
        }

mPanoView = (PanoramaView) findViewById(R.id.panorama);
mPanoView.setPanorama(longitude, latitude);

這里同樣需要的是在Application類中做一些初始化工作;對(duì)我們所使用key的有效性進(jìn)行檢測(cè)捣卤。

public void initEngineManager(Context context) {
        if (mBMapManager == null) {
            mBMapManager = new BMapManager(context);
        }

        if (!mBMapManager.init(new MyGeneralListener())) {
            Toast.makeText(PanoDemoApplication.getInstance()
.getApplicationContext(), "BMapManager  初始化錯(cuò)誤!",
                    Toast.LENGTH_LONG).show();
        }
    }

// 常用事件監(jiān)聽忍抽,用來處理通常的網(wǎng)絡(luò)錯(cuò)誤,授權(quán)驗(yàn)證錯(cuò)誤等
    static class MyGeneralListener implements MKGeneralListener {

        @Override
        public void onGetPermissionState(int iError) {
            // 非零值表示key驗(yàn)證未通過
            if (iError != 0) {
                // 授權(quán)Key錯(cuò)誤:
                Toast.makeText(PanoDemoApplication.getInstance()
.getApplicationContext(),
     "請(qǐng)?jiān)贏ndoridManifest.xml中輸入正確的授權(quán)Key,并檢查您的網(wǎng)絡(luò)連接是否正常董朝!error: " + iError, Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(PanoDemoApplication.getInstance()
.getApplicationContext(), "key認(rèn)證成功", Toast.LENGTH_LONG)
                        .show();
            }
        }
    }

同時(shí)在Activity里也需要做一些初始化的工作梯找,最后就是通過PanoView的setPanorama()方法實(shí)現(xiàn)街景的顯示。

關(guān)于這里用到的setPanorama(),根據(jù)API我們可以看到

public void setPanorama(java.lang.String pid)
//根據(jù)全景pid值切換全景場(chǎng)景

public void setPanorama(int x,int y)
//根據(jù)百度墨卡托投影坐標(biāo)切換全景場(chǎng)景

public void setPanorama(double longitude,double latitude)
//根據(jù)百度經(jīng)緯度坐標(biāo)切換全景場(chǎng)景

public void setPanoramaByUid(java.lang.String uid,
                    int panoType)
//根據(jù)uid值切換全景場(chǎng)景

也就是說益涧,不僅通過經(jīng)緯度锈锤,而且可以通過別的方式實(shí)現(xiàn)街景地圖的功能,甚至室內(nèi)景的實(shí)現(xiàn)。這里我們就使用了大家最熟悉的經(jīng)緯度久免,對(duì)于別的實(shí)現(xiàn)方式有興趣的同學(xué)浅辙,可以自己去探索一下。

將地圖MapView展示在街景PanoView上面###

如圖所示阎姥,將一個(gè)MapView顯示在PanoView之上记舆;很自然的我們會(huì)寫出下面的布局方式:

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.baidu.lbsapi.panoramaview.PanoramaView
            android:id="@+id/panorama"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:visibility="visible" />

        <LinearLayout
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_marginBottom="8dp"
            android:layout_marginLeft="8dp"
            android:background="#00ffffff">

            <com.baidu.mapapi.map.MapView
                android:id="@+id/bmapView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clickable="true"
                android:padding="20dp" />
        </LinearLayout>
    </RelativeLayout>

這樣,我們?cè)谡麄€(gè)PanoView的左下角定義一個(gè)60x60大小的view用于顯示一個(gè)MapView呼巴。

實(shí)現(xiàn)對(duì)街景視圖操作的監(jiān)聽###

街景SDK為我們提供了PanoramaViewListener這個(gè)接口泽腮,可以實(shí)現(xiàn)對(duì)從街景視圖開始繪制到完成繪制,對(duì)街景地圖的操作(如點(diǎn)擊衣赶,旋轉(zhuǎn))的監(jiān)聽诊赊。

API

這里我們重點(diǎn)看一下onMessage(String msgName, int msgType)這個(gè)回調(diào)方法。

public void onMessage(String msgName, int msgType) {
                Log.e(LTAG, "msgName--->" + msgName + ", 
msgType--->" + msgType);
                switch (msgType) {
                    case 8213:
                        //旋轉(zhuǎn)
                        Log.e(PanoViewActivity.class.getSimpleName(), 
"now,the heading is " + mPanoView.getPanoramaHeading());
                        Message message = new Message();
                        message.what = ACTION_DRAG;
                        message.arg1 = (int) mPanoView.getPanoramaHeading();
                        handler.sendMessage(message);
                        break;
                    case 12302:
                        //點(diǎn)擊
                        Log.e(PanoViewActivity.class.getSimpleName(), 
"clicked");
                        Message msg = new Message();
                        msg.what = ACTION_CLICK;
                        handler.sendMessage(msg);
                        break;
                    default:
                        break;
                }

            }

這里不得不吐槽一下府瞄,官方所提供的API文檔碧磅,對(duì)這個(gè)onMessage回調(diào)方法中的參數(shù)居然沒有任何有價(jià)值的解釋。這里的8213及12302完全是通過打印日志自己總結(jié)出的規(guī)律遵馆。

這樣鲸郊,我們對(duì)于不同的操作,就可以通過Handler實(shí)現(xiàn)不同的UI效果货邓。我們看一下handler的實(shí)現(xiàn):

private class MyHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case ACTION_CLICK:
                    if (titleVisible) {
                        titleVisible = false;
                        textTitle.startAnimation(animationHide);
                        textTitle.setVisibility(View.GONE);
                        sv.setVisibility(View.GONE);
                    } else {
                        titleVisible = true;
                        textTitle.startAnimation(animationShow);
                        textTitle.setVisibility(View.VISIBLE);
                        sv.setVisibility(View.VISIBLE);

                    }

                    break;
                case ACTION_DRAG:
                    float heading = (float) msg.arg1;

                    mBaiduMap.clear();

                    //構(gòu)建MarkerOption秆撮,用于在地圖上添加Marker
                    option = new MarkerOptions()
                            .position(point)
                            .rotate(360-heading)
                            .icon(bitmap);
                    //在地圖上添加Marker,并顯示
                    mBaiduMap.addOverlay(option);
                    break;
                default:
                    break;
            }
        }

    }

這里的處理就分兩種情況:

  • 點(diǎn)擊事件

我們仿照百度地圖的樣式换况,實(shí)現(xiàn)標(biāo)題欄及MapView的隱藏职辨,并添加動(dòng)畫,這樣可以方便用戶全屏更清晰的觀察街景內(nèi)容复隆。

  • 旋轉(zhuǎn)事件

上面我們說過對(duì)MapView添加Marker的方法拨匆,這里就派上用場(chǎng)了。隨著我們對(duì)PanoView的不斷拖拽旋轉(zhuǎn)挽拂,通過其getPanoramaHeading() 可以得到當(dāng)前視角的偏航角惭每。
在UI線程中,我們可以通過不斷移除和添加Marker亏栈,并設(shè)置不同的marker的偏轉(zhuǎn)角度台腥,從而實(shí)現(xiàn)一種在左下方小地圖上呈現(xiàn)我們當(dāng)前視角的效果。

好了绒北,這樣就簡(jiǎn)單模仿了一下百度地圖街景的部分實(shí)現(xiàn)功能黎侈,由于UI資源所限制,部分效果并非完全一致闷游,這里只是學(xué)習(xí)下而已峻汉。

代碼已上傳至github贴汪,點(diǎn)這里即可查看。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末休吠,一起剝皮案震驚了整個(gè)濱河市扳埂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘤礁,老刑警劉巖阳懂,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異柜思,居然都是意外死亡岩调,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門赡盘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來号枕,“玉大人,你說我怎么就攤上這事亡脑《槌危” “怎么了邀跃?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵霉咨,是天一觀的道長。 經(jīng)常有香客問我拍屑,道長途戒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任僵驰,我火速辦了婚禮喷斋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒜茴。我一直安慰自己星爪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布粉私。 她就那樣靜靜地躺著顽腾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诺核。 梳的紋絲不亂的頭發(fā)上抄肖,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音窖杀,去河邊找鬼漓摩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛入客,可吹牛的內(nèi)容都是我干的管毙。 我是一名探鬼主播腿椎,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼夭咬!你這毒婦竟也來了酥诽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤皱埠,失蹤者是張志新(化名)和其女友劉穎肮帐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體边器,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡训枢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了忘巧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恒界。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖砚嘴,靈堂內(nèi)的尸體忽然破棺而出十酣,到底是詐尸還是另有隱情,我是刑警寧澤际长,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布耸采,位于F島的核電站,受9級(jí)特大地震影響工育,放射性物質(zhì)發(fā)生泄漏虾宇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一如绸、第九天 我趴在偏房一處隱蔽的房頂上張望嘱朽。 院中可真熱鬧,春花似錦怔接、人聲如沸搪泳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岸军。三九已至,卻和暖如春谎势,著一層夾襖步出監(jiān)牢的瞬間凛膏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工脏榆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留猖毫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓须喂,卻偏偏與公主長得像吁断,于是被迫代替她去往敵國和親趁蕊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

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