多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > [置頂] 模仿百度地圖的LBS服務――離線地圖篇 Part 2 (v 3.1.1)

[置頂] 模仿百度地圖的LBS服務――離線地圖篇 Part 2 (v 3.1.1)

來源:程序員人生   發布時間:2014-12-09 08:20:19 閱讀次數:2924次



1、前言



轉載請標明出處:http://blog.csdn.net/wlwlwlwl015/article/details/41492031

這1篇blog寫的真心不容易,我只想說我這類菜鳥去高仿百度地圖去做LBS服務真心有點作死,期間本想放棄,做簡單點算了,但不能說服自己。最后通過F6去1行1行的debug(新手朋友注意這是最好的解決問題的方式沒有之1),最后成功完成了核心的功能。上1篇blog高仿了百度地圖離線地圖模塊中的“城市列表”部份(模仿百度地圖的LBS服務――離線地圖篇 Part1),城市實現里“當前城市”、“熱門城市”、“全國省市”數據信息的展現,那末本篇blog主要記錄的就是如何進行下載了,一樣的是高仿百度離線地圖的“下載管理”模塊。空話不多說,下面就分步驟進行逐一介紹了。



2、百度離線地圖“下載管理”功能分析



老規矩我們先來看看百度地圖離線地圖中“下載管理”模塊的界面和功能:


通過這上面兩幅截圖我們分析1下需要做的工作:

1.下載管理分為“正在下載”和“下載完成”兩部份,所以整體界面應當分為2個ListView。

2.可以通過進度條實時看到下載任務的進度,下載中可以進行“暫停下載”和“刪除”的操作,那末暫停的時候一定也能夠履行“開始下載”的操作。具體細節大家可以通過操作百度地圖來看。

3.已下載完成的地圖提供了“查看地圖”和“刪除”的功能。


大體上功能就上面提到的這些,具體的細節在下面的代碼中再看,下面就依照我的開發順序來告知大家先做甚么、后做甚么、具體怎樣做,對高手來講高仿這個東東可能不算甚么,但是對我來講確切難度挺大,整整兩天,吃飯睡覺都在想細節,終究之所以實現了,是由于我首先會理清思路,先斟酌我需要做甚么并將任務拆分開,然后是這些步驟應當按甚么順序去做,就這樣1點1點做,1行1行debug,終究得以完成。所以下面我就列出開發步驟,再逐1說明。


Step 1 初始化

Step 2 編寫離線地圖事件通知接口及其回調方法中的代碼

Step 3 分別編寫“正在下載”和“下載完成”的布局和Adapter

Step 4 編寫測試方法,即開始履行下載任務


Step 1 

上面這個說的可能還不夠細節,但是沒關系,我會在下面通過代碼去逐一解釋清楚。首先來看看初始化,先上代碼(注意和上1篇是同1個Activity,所以重復代碼就不貼了):

// 已下載的離線地圖數據List private ArrayList<MKOLUpdateElement> isDoingUpdateMapList = null; // 正在下載的數據列表(包括下載中、暫停的) private ArrayList<MKOLUpdateElement> downLoadingMapList = new ArrayList<MKOLUpdateElement>(); // 已下載完成的數據列表 private ArrayList<MKOLUpdateElement> downLoadedMapList = new ArrayList<MKOLUpdateElement>(); // 已下載的離線地圖數據Adapter和ListView private DownLoadingListView downLoadingListView; // 正在下載的ListView private DownLoadingAdapter mDownLoadingAdapter = new DownLoadingAdapter(); private DownLoadedListView downLoadedListView; // 下載完成的ListView private DownLoadedAdapter mDownLoadedAdapter = new DownLoadedAdapter();

上面的是聲明部份,關于“正在下載”和“下載完成”一樣是兩個自定義的ListView去解決事件沖突問題,解決方案和上1篇blog1樣,都是重寫onMeasure方法。


一樣的聲明以后應當進行初始化工作,用來初始化之前的下載任務,比如:兩個下載任務都下了1半暫停了,這里我們需要在“正在下載”的ListView中顯示出來,參照百度地圖應包括以下信息:城市名、數據包大小、下載狀態、當前的下載進度等。下面這段代碼一樣位于initData()方法中:

// 初始化已下載的城市列表,并根據已下載和下載中進行分類 isDoingUpdateMapList = mOfflineMap.getAllUpdateInfo(); if (isDoingUpdateMapList == null) { isDoingUpdateMapList = new ArrayList<MKOLUpdateElement>(); } if (isDoingUpdateMapList.size() > 0) { for (MKOLUpdateElement element : isDoingUpdateMapList) { // 如果下載進度為100則應放入“已下載”的List if (element.ratio == 100) { downLoadedMapList.add(element); mDownLoadedAdapter = new DownLoadedAdapter(); } // 如果下載進入不為100則應放入“正在下載”的List if (element.ratio != 100) { downLoadingMapList.add(element); mDownLoadingAdapter = new DownLoadingAdapter(); } } }

第2行的getAllUpdateInfo()方法很好用,是這個下載模塊的核心方法,官方的解釋是:返回各城市離線地圖更新信息。對這個解釋我是覺得很笼統,不明白,通過我的使用我認為這個方法的作用就是:返回當前已下載的(包括開始下載的、暫停的、正在下載的和完成的)的所有數據信息,并且是以城市為單位的List集合。根據官方文檔可以看出返回值類型是MKOLUpdateElement,這個類也正式封裝了1個下載任務應有的所有關鍵信息,而在上面的代碼中我正是通過element.ratio來分割List,由于ratio正是下載進度的意思:


所以當ratio為100的時候,我就將這個對象放到“下載完成”的ListView,否則說明還沒下載完,就放到“正在下載”的ListView。這樣我們就能夠在進入利用以后看到之前未完成的、已完成的下載記錄了。OK,初始化很簡單,結束了。


Step 2 

初始化完成以后,現在就來講道說道離線地圖中唯1的1個監聽:public interface MKOfflineMapListener

一樣的來看看官方文檔中對它的解釋:

離線地圖事件通知接口。該接口返回新安裝離線地圖、下載更新、數據版本更新等結果,用戶需要實現該接口以處理相應事件。


不知道是否是我書讀的少,總覺得官方的解釋不夠通俗,看了仍然不知道怎樣用。但是官方對這個接口的回調方法還是解釋的比較清楚的:

void onGetOfflineMapState(int type,int state)

type - 事件類型: MKOfflineMap.TYPE_NEW_OFFLINE, MKOfflineMap.TYPE_DOWNLOAD_UPDATE, MKOfflineMap.TYPE_VER_UPDATE.

state - 事件狀態: 當type為TYPE_NEW_OFFLINE時,表示新安裝的離線地圖數目. 當type為TYPE_DOWNLOAD_UPDATE時,表示更新的城市ID.

上面的藍色字體都是官方文檔的原話,這里我們也清楚了這個回調方法的兩個參數都表示甚么意思了。根據需求,我們需要實時監控下載進度并反饋到UI,所以這里我們只需要關注TYPE_DOWNLOAD_UPDATE這個類型的事件便可,而正好此時的state就表示更新城市的ID,那末這個監聽的作用就很明顯了,就是通過它來實時獲得下載進度并更新我們界面上的ProgressBar便可??赡苡行┤瞬磺宄趺磿r候會觸發這個監聽,那末通過打印語句來視察控制臺不難發現,當type為TYPE_DOWNLOAD_UPDATE時,只要下載狀態產生變化,即會觸發監聽。文字解釋比較費力,下面我貼上監聽代碼,大家可以開啟1個下載任務(后面說),并像第9行1樣通過打印來視察1下都有甚么變化:

mOfflineMap.init(new MKOfflineMapListener() { @Override public void onGetOfflineMapState(int type, int state) { // TODO Auto-generated method stub switch (type) { case MKOfflineMap.TYPE_DOWNLOAD_UPDATE: // 得到當前正在下載的城市的具體更新信息 MKOLUpdateElement update = mOfflineMap.getUpdateInfo(state); Log.e(TAG, update.cityName + " ," + update.ratio); if (update != null) { // 此監聽器在下載任務進行期間大概每下載1%觸發1次,注意是大概 List<MKOLUpdateElement> elements = downLoadingMapList; for (MKOLUpdateElement element : elements) { if (update.cityID == element.cityID) { element.ratio = update.ratio; if (update.ratio == 100) { // 當下載進度到100時,Item從“下載中”的List移動到“已下載的List” downLoadingMapList.remove(element); downLoadedMapList.add(element); mDownLoadedAdapter.notifyDataSetChanged(); } break; } } } mDownLoadingAdapter.notifyDataSetChanged(); break; case MKOfflineMap.TYPE_NEW_OFFLINE: // 有新離線地圖安裝 Log.e(TAG, "TYPE_NEW_OFFLINE"); break; case MKOfflineMap.TYPE_VER_UPDATE: // 版本更新提示 break; } } });

相信認真看了代碼的朋友肯定也大致明白了個123吧,有問題可以留言,雖然我是新手,可我自己寫的東西還是解釋的清的。


Step 3 

下面就是最重要的適配器了,我們來分別看看“下載中”的Adapter和“下載完成”的Adapter:

// 下載管理――正在下載――適配器 class DownLoadingAdapter extends BaseAdapter { @Override public int getCount() { // TODO Auto-generated method stub return downLoadingMapList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return downLoadingMapList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub final MKOLUpdateElement element = downLoadingMapList.get(position); ViewHolder holder = null; if (convertView == null) { convertView = mInflater.inflate(R.layout.down_loading_item, null); holder = new ViewHolder(); holder.cityName = (TextView) convertView .findViewById(R.id.id_city_name); holder.dataPakSize = (TextView) convertView .findViewById(R.id.id_data_size); holder.downLoadState = (TextView) convertView .findViewById(R.id.id_down_state); holder.downLoadRatio = (TextView) convertView .findViewById(R.id.id_down_raito); holder.downLoadProgress = (ProgressBar) convertView .findViewById(R.id.id_down_progress); holder.downPullIcon = (ImageButton) convertView .findViewById(R.id.id_expand_down_icon); holder.upPullIcon = (ImageButton) convertView .findViewById(R.id.id_expand_up_icon); holder.pauseDownBtn = (Button) convertView .findViewById(R.id.id_pause_down_btn); holder.startDownBtn = (Button) convertView .findViewById(R.id.id_start_down_btn); holder.deleteMapBtn = (Button) convertView .findViewById(R.id.id_delete_map); holder.btnGroup = (LinearLayout) convertView .findViewById(R.id.id_btn_group); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.cityName.setText(element.cityName); holder.dataPakSize.setText(NumberFormatUtil .dataSizeFormatter(element.serversize) + "M"); String stateInfo = ""; // 如果是正在下載的狀態 if (element.status == MKOLUpdateElement.DOWNLOADING) { stateInfo = "正在下載"; holder.startDownBtn.setVisibility(View.GONE); holder.pauseDownBtn.setVisibility(View.VISIBLE); holder.downLoadState.setTextColor(Color.BLUE); } //如果是暫停的狀態 if (element.status == MKOLUpdateElement.SUSPENDED) { stateInfo = "已暫停"; holder.downLoadState.setTextColor(Color.RED); holder.startDownBtn.setVisibility(View.VISIBLE); holder.pauseDownBtn.setVisibility(View.GONE); } holder.downLoadState.setText(stateInfo); //設置當前進度的百分數 holder.downLoadRatio.setText(element.ratio + "%"); //設置ProgressBar的進度 holder.downLoadProgress.setProgress(element.ratio); // 暫停下載 holder.pauseDownBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub int cityId = element.cityID; mOfflineMap.pause(cityId); Toast.makeText(OfflineActitivty.this, "暫停下載" + element.cityName + "離線地圖:", Toast.LENGTH_SHORT).show(); isDoingUpdateMapList = mOfflineMap.getAllUpdateInfo(); if (isDoingUpdateMapList == null) { isDoingUpdateMapList = new ArrayList<MKOLUpdateElement>(); } if (isDoingUpdateMapList.size() > 0) { downLoadingMapList.clear(); for (MKOLUpdateElement element : isDoingUpdateMapList) { if (element.ratio != 100) { downLoadingMapList.add(element); } } } mDownLoadingAdapter.notifyDataSetChanged(); } }); // 開始下載 holder.startDownBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub int cityId = element.cityID; mOfflineMap.start(cityId); Toast.makeText(OfflineActitivty.this, "開始下載" + element.cityName + "離線地圖:", Toast.LENGTH_SHORT).show(); isDoingUpdateMapList = mOfflineMap.getAllUpdateInfo(); if (isDoingUpdateMapList == null) { isDoingUpdateMapList = new ArrayList<MKOLUpdateElement>(); } if (isDoingUpdateMapList.size() > 0) { downLoadingMapList.clear(); for (MKOLUpdateElement element : isDoingUpdateMapList) { if (element.ratio != 100) { downLoadingMapList.add(element); } } } mDownLoadingAdapter.notifyDataSetChanged(); mDownLoadedAdapter.notifyDataSetChanged(); } }); // 刪除地圖 holder.deleteMapBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub int cityId = element.cityID; mOfflineMap.remove(cityId); Toast.makeText(OfflineActitivty.this, "已刪除" + element.cityName + "離線地圖:", Toast.LENGTH_SHORT).show(); downLoadingMapList.remove(position); mDownLoadingAdapter.notifyDataSetChanged(); } }); } } }); return convertView; } private class ViewHolder { TextView cityName; TextView dataPakSize; TextView downLoadState; TextView downLoadRatio; ProgressBar downLoadProgress; ImageButton downPullIcon; ImageButton upPullIcon; Button pauseDownBtn; Button startDownBtn; Button deleteMapBtn; LinearLayout btnGroup; } }


// 下載管理――已下載――適配器 class DownLoadedAdapter extends BaseAdapter { @Override public int getCount() { // TODO Auto-generated method stub return downLoadedMapList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return downLoadedMapList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub final MKOLUpdateElement element = downLoadedMapList.get(position); ViewHolder holder = null; if (convertView == null) { convertView = mInflater .inflate(R.layout.down_loaded_item, null); holder = new ViewHolder(); holder.cityName = (TextView) convertView .findViewById(R.id.id_city_name); holder.isHasNewData = (TextView) convertView .findViewById(R.id.id_is_has_new); holder.dataPakSize = (TextView) convertView .findViewById(R.id.id_data_pak_size); holder.deleteMapBtn = (Button) convertView .findViewById(R.id.id_btn_delete_map); holder.seeMapDetailBtn = (Button) convertView .findViewById(R.id.id_see_map_detail); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.cityName.setText(element.cityName); holder.dataPakSize.setText(NumberFormatUtil .dataSizeFormatter(element.serversize) + "M"); // 刪除地圖 holder.deleteMapBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub // 刪除已下載的離線Map int cityId = element.cityID; mOfflineMap.remove(cityId); Toast.makeText(OfflineActitivty.this, "已刪除" + element.cityName + "離線地圖:", Toast.LENGTH_SHORT).show(); downLoadedMapList.remove(position); mDownLoadedAdapter.notifyDataSetChanged(); } }); // 查看地圖 holder.seeMapDetailBtn .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(); intent.putExtra("x", element.geoPt.longitude); intent.putExtra("y", element.geoPt.latitude); intent.setClass(OfflineActitivty.this, BaseMapActivity.class); startActivity(intent); } }); return convertView; } private class ViewHolder { private TextView cityName; private TextView isHasNewData; private TextView dataPakSize; private Button deleteMapBtn; private Button seeMapDetailBtn; } }

可以看到由于“下載中”有開始和暫停兩個按鈕,所以比“下載完成”稍微麻煩1些,而下載完成以后便可以查看地圖,即根據經緯坐標去加載改城市的地圖,代碼很簡單就是官方Demo中的那個BaseMapActivity。item的布局也很簡單,模仿百度地圖的樣式拼湊1下就行了,后面會貼上動態效果圖,其實到這里離線地圖模塊的核心功能都已完成,最后看看如何通過點擊Item去開啟1個下載任務吧。


Step 4 

通過上面的3個步驟就已完成了離線地圖的所有準備工作了,下面只剩下點擊列表項開啟下載任務了,仍然是參考百度地圖,簡單的流程是這樣的:

點擊任意列表中的任意項(包括熱門城市的ListView、全國省市的ExpandableListView的子項),如果被點擊的城市沒有下載,那末新開1個下載任務在“正在下載”的列表,如果被點擊的城市“正在下載”或“已暫?!保悄┲恍栌们袚Q到“下載管理列表”便可,最后如果被點擊的城市“已下載完成”,那末一樣的只是切換1下便可。


下面貼上剩余全部代碼,包括初始化ListView和添加Item點擊:

// 初始化ListView private void initListView() { // 熱門城市 hotCitieslistView = (HotCitiesListView) findViewById(R.id.id_hotcities_lv); mHotCityAdapter = new HotCityAdapter(); hotCitieslistView.setAdapter(mHotCityAdapter); // 全國省市 allCitieslistView = (NationalCitiesListView) findViewById(R.id.id_allcities_exp_lv); mNationalCityAdapter = new NationalCityAdapter(); allCitieslistView.setAdapter(mNationalCityAdapter); // 下載管理――下載中 downLoadingListView = (DownLoadingListView) findViewById(R.id.id_download_manager_lv); downLoadingListView.setAdapter(mDownLoadingAdapter); // 下載管理――下載完成 downLoadedListView = (DownLoadedListView) findViewById(R.id.id_download_manager_lv_2); downLoadedListView.setAdapter(mDownLoadedAdapter); // 設置熱門城市的Item點擊事件 hotCitieslistView .setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // // TODO Auto-generated method stub OfflineMapItemBean offlineMapItemBean = mHotCityDatas .get(position); int cityId = offlineMapItemBean.getCityId(); String cityName = offlineMapItemBean.getCityName(); MKOLUpdateElement element = mOfflineMap .getUpdateInfo(cityId); // 如果進度為0,則下載。否則僅僅切換過去 if (element == null) { // 開始下載 mOfflineMap.start(cityId); offlineMapItemBean .setDownloadStatus(DownLoadStatus.DOWNLOADING); // 切換到下載管理 tb.setChecked(false); llayout1.setVisibility(View.VISIBLE); llayout2.setVisibility(View.GONE); Toast.makeText(OfflineActitivty.this, "開始下載" + cityName + "離線地圖", Toast.LENGTH_SHORT).show(); // 更新界面顯示 isDoingUpdateMapList = mOfflineMap .getAllUpdateInfo(); if (isDoingUpdateMapList == null) { isDoingUpdateMapList = new ArrayList<MKOLUpdateElement>(); } // 現在就有更新信息了 element = mOfflineMap.getUpdateInfo(cityId); downLoadingMapList.add(element); mDownLoadingAdapter.notifyDataSetChanged(); mHotCityAdapter.notifyDataSetChanged(); } else { // 僅僅跳轉 // 切換到下載管理 tb.setChecked(false); llayout1.setVisibility(View.VISIBLE); llayout2.setVisibility(View.GONE); } } }); // 設置全國省市的Item點擊事件 allCitieslistView.setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { OfflineMapItemBean offlineMapItemBean = allCityDatas .get(groupPosition).getChildCities().get(childPosition); int cityId = offlineMapItemBean.getCityId(); String cityName = offlineMapItemBean.getCityName(); // Toast.makeText(OfflineActitivty.this, cityId+","+cityName, // Toast.LENGTH_SHORT).show(); MKOLUpdateElement element = mOfflineMap.getUpdateInfo(cityId); // 如果進度為0,則下載。否則僅僅切換過去 if (element == null) { // 開始下載 mOfflineMap.start(cityId); offlineMapItemBean .setDownloadStatus(DownLoadStatus.DOWNLOADING); // 切換到下載管理 tb.setChecked(false); llayout1.setVisibility(View.VISIBLE); llayout2.setVisibility(View.GONE); Toast.makeText(OfflineActitivty.this, "開始下載" + cityName + "離線地圖:", Toast.LENGTH_SHORT) .show(); // 更新界面顯示 isDoingUpdateMapList = mOfflineMap.getAllUpdateInfo(); if (isDoingUpdateMapList == null) { isDoingUpdateMapList = new ArrayList<MKOLUpdateElement>(); } // 現在就有更新信息了 element = mOfflineMap.getUpdateInfo(cityId); downLoadingMapList.add(element); mDownLoadingAdapter.notifyDataSetChanged(); mHotCityAdapter.notifyDataSetChanged(); } else { // 僅僅跳轉 // 切換到下載管理 tb.setChecked(false); llayout1.setVisibility(View.VISIBLE); llayout2.setVisibility(View.GONE); } return false; } }); }

最后做1些說明,包括我整體代碼的不足和重點需要注意的地方

1.肯定有的朋友發現我在寫“熱門城市”的列表的時候還通過自定義的OfflineMapItemBean對數據進行了封裝,在后面做“下載列表”的時候壓根就沒有再封裝了,而是直接用SDK中的MKOLUpdateElement對象去取值了。這塊是我做的不好,由于下載列表要拆分成“正在下載”和“已完成”兩部份,每次獲得更新對象再遍歷拆分感覺也不是個辦法,所以干脆就不封裝了,我也沒有想到更好的辦法去處理,有更好的方法的朋友可以給我指導12。

2.當ScrollView嵌套ListView以后item的點擊事件是失效的,包括ExpandableListView的子item也是1樣。對這個我選擇了在item的布局文件中添加1個屬性:android:descendantFocusability="blocksDescendants"來解決的,但這不是個好辦法,聽說會讓ViewHolder失效,問了其他朋友說是讓ScrollView中的onTouch返回false之類的,我嘗試了沒有到達預期效果,如果哪位大神知道最優的解決方案還請給小弟指導12,感激不盡。

3.由于項目周期緊,還有很多小效果沒來得及實現,比如:下載狀態(已暫停、已完成等)應當在“下載管理”和“城市列表”中能實時的同步的更新等,但是整體上看效果還是挺不錯的吧,下面就貼上效果圖:



由于在摹擬器上調試時沒法開始下載(offlineMap.start方法調用以后MKOLUpdateElement返回的更新對象的status始終是WAITING的狀態,而在真機調試時調用start以后更新對象的status會立刻變成DOWNING,摹擬器的網絡也沒有問題,不知道是否是BUG),所以這里只貼上兩張真機運行截圖好了,UI比較粗糙,但是核心功能都沒問題,到了這里離線地圖的全部內容就已算是記錄終了了。



3、總結



寫到這里關于我們項目中的LBS服務就已全部介紹終了了,在做地圖模塊的同時學到了許多新的東西,在這里也要感謝鴻洋大神對我的幫助,目前準備和同事1起再做1個以LBS為主的APP,等做好以后可能還會寫1個博客吧,這個APP的點子不錯,目前暫且先不透漏,透漏了也沒幾個人會看到,哈哈。路漫漫其修遠兮,吾將上下而求索,我的Android之路才剛剛開始,今后還應當更加努力!加油!Raito!

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 免费jizz在线播放视频 | 亚洲国产精品看片在线观看 | 男女啪啪成人免费网站 | 日本韩国欧美在线观看 | 欧美成人一区二区三区不卡视频 | 亚洲午夜免费视频 | 日本一区二区三区不卡在线看 | 国产色综合一区二区三区 | 国产欧美日韩不卡一区二区三区 | 网站四虎1515hhcom| 自拍视频一区二区 | 亚洲久久色| jizz亚洲高清在线观看 | 欧美日本二区 | 欧美jizzhd精品欧美巨大 | 国内精品伊人久久大香线焦 | 最近免费中文字幕完整7 | 天堂在线www| 中文字幕国产欧美 | 日韩字幕无线乱码 | 欧美另类bbwhd | 荷兰videos| haodiaose在线精品免费视频 | 自拍自偷 | 看亚洲a级一级毛片 | 精品福利一区二区免费视频 | 久久久久久久国产精品 | 99r8这里精品热视频免费看 | 亚洲国产精品综合一区在线 | 视频三区精品中文字幕 | 欧美69视频在线 | 97碰碰碰免费公开在线视频 | 国产日韩欧美精品 | 亚洲人成在线观看男人自拍 | 手机在线看福利 | 亚洲国产第一区二区三区 | 最新欧美精品一区二区三区不卡 | 国产视频一区在线观看 | 国产老妇女 | 国模一区二区三区视频一 | 嫩草影院久久精品 |