前兩天分析了菜鳥裹裹的具體業務,菜鳥裹裹可以成功快遞行業的王牌產品,業務固然是很是重要的一環,不過App的操做體驗,以及可以讓用戶使用上更加方便快捷,也是成功的重要因素,因此此次就來分析菜鳥裹裹的UI框架設計。
此次對主要功能頁面進行分析,分析工具:php
menu_and_navigation_bar_container
和內容區域
navigation_bar_content
佈局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@id/navigation_bar_root" android:clipChildren="false" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout android:layout_gravity="top" android:id="@id/navigation_bar_content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginBottom="@dimen/navigation_bar_height" />
<ViewStub android:id="@id/navigation_bar_loading_view" android:layout="@layout/cainiao_progress_dialog" android:inflatedId="@id/rn_loading_view" android:layout_width="fill_parent" android:layout_height="fill_parent" />
<FrameLayout android:layout_gravity="bottom" android:id="@id/menu_and_navigation_bar_container" android:clipChildren="false" android:layout_width="fill_parent" android:layout_height="@dimen/navigation_bar_height">
<com.cainiao.commonlibrary.navigation.NavigationBarView android:gravity="bottom" android:layout_gravity="center_vertical" android:id="@id/navigation_bar_view" android:clipChildren="false" android:layout_width="fill_parent" android:layout_height="fill_parent" />
</FrameLayout>
<ViewStub android:id="@id/full_screen_splash_view" android:layout="@layout/libs_full_screen_splash_view" android:inflatedId="@id/splash_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" />
</FrameLayout>
複製代碼
內容區域佈局:java
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<com.cainiao.wireless.uikit.view.feature.PtrBirdFrameLayout android:id="@id/store_house_ptr_frame" android:background="@color/full_transparent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@id/header_title_view">
<ListView android:id="@id/package_listview" android:background="@color/homepage_fragment_listview_background" android:scrollbars="none" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginBottom="10.0dip" android:listSelector="#00000000" android:divider="@null" android:choiceMode="singleChoice" android:overScrollMode="never" />
</com.cainiao.wireless.uikit.view.feature.PtrBirdFrameLayout>
<LinearLayout android:orientation="vertical" android:id="@id/homepage_fragment_scrollable_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@id/header_title_view">
<com.cainiao.wireless.homepage.presentation.view.widget.newfeatureview.HomepageNewFeatureLayout android:id="@id/home_page_fragment_new_grid_feature_enter_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" />
</LinearLayout>
<com.cainiao.wireless.homepage.presentation.view.widget.HomepageTitleView android:id="@id/header_title_view" android:layout_width="fill_parent" android:layout_height="45.0dip" />
</RelativeLayout>
複製代碼
佈局文件的具體結構圖: android
menu_and_navigation_bar_container
主要包含了NavigationBarView
,底部導航內容:首頁,取件,寄件,驛站,我。navigation_bar_content
:內容區域。經過底部導航的切換,內容顯示不一樣的頁面。main_activity_content
:首頁的內容區域顯示。分爲三部分:
header_title_view
:經過自定義ViewHomepageTitleView
實現homepage_fragment_scrollable_layout
:經過HomepageNewFeatureLayout
實現store_house_ptr_frame
:展示列表和下拉刷新,分別經過ListView
和PtrBirdFrameLayout
實現不過從反編譯中沒法找到對應的佈局xml,經過關鍵字logistic
在AndroidManifest.xml文件搜索到相關的Activity。發現com.cainiao.wireless.logisticsdetail.presentation.view.activity.ShowGoodInfoActivity
有相關性,ShowGoodInfoActivity
中使用ShowGoodInfoFragment
渲染, ShowGoodInfoFragment
中有個方法會真正進入到詳情的邏輯。weex
public void showGoodInfo(List<LogisticsDetailGoodsDO> packageItems) {
if (packageItems != null) {
if (packageItems.size() == 0) {
Bundle bundle = new Bundle();
bundle.putString("orderCode", this.mOrderCode);
bundle.putString("mailNo", this.mMailNo);
bundle.putString("cpCode", this.mCpCode);
//進入詳情的Router聲明
Router.from(getActivity()).withExtras(bundle)
.toUri("guoguo://go/logistic");
getActivity().overridePendingTransition(0, 0);
finish();
}
if (packageItems.size() == 1) {
Router.from(getActivity()).toUri(((LogisticsDetailGoodsDO) packageItems.get(0)).taobaoGoodUrl);
getActivity().overridePendingTransition(0, 0);
finish();
return;
}
this.mSlideShowView.setDatas(packageItems);
}
}
複製代碼
該方法經過Router進行跳轉到guoguo://go/logistic
,在AndroidManifest.xml有對應的聲明:框架
<activity android:configChanges="keyboardHidden|orientation" android:exported="false" android:name="com.taobao.cainiao.newlogistic.LogisticDetailActivity" android:screenOrientation="portrait" android:theme="@style/Theme.NoBackgroundAndTitle.TabPage" android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="go" android:path="/logistic" android:scheme="guoguo"/>
</intent-filter>
<meta-data android:name="bundleLocation" android:value="com.taobao.cainiao"/>
</activity>
複製代碼
沒錯就是它, LogisticDetailActivity
就是咱們要找的顯示物流詳情的頁面。 反編譯的代碼中沒有對應的LogisticDetailActivity
的源碼,這些部分應該是經過Atlas動態部署的。 LogisticDetailActivity
在Atlas框架中的聲明less
package android.taobao.atlas.framework;
public class FrameworkProperties {
public static String autoStartBundles = "com.android.update,com.cainiao.wireless.pr";
public static String bundleInfo = "
...
{\"activities\":[\"com.taobao.cainiao.newlogistic.LogisticDetailActivity\"],\"contentProviders\":[],\"dependency\":[],\"isInternal\":true,\"pkgName\":\"com.taobao.cainiao\",\"receivers\":[],\"services\":[],\"unique_tag\":\"67520454e3fdb8fd2307b1c08c602abf\",\"version\":\"4.7.1@1.1.1.12\"}
....";
public static String group = "cainiao4android";
public static String outApp = "false";
private String version = "4.7.1";
public String getVersion() {
return this.version;
}
}
複製代碼
cn_wx_page_container
,看id的名字判斷出這是weex頁面。 UI佈局:
<LinearLayout android:orientation="vertical" android:background="#fff2f2f2" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<com.cainiao.android.cnweexsdk.weex.view.CNWXTopBar android:id="@id/cn_wx_page_topbar" android:layout_width="fill_parent" android:layout_height="?cnWXTopBarHeightStyle" />
<FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:id="@id/cn_wx_page_container" android:background="#ffffffff" android:layout_width="fill_parent" android:layout_height="fill_parent" />
<FrameLayout android:layout_gravity="bottom" android:id="@id/cn_wx_page_cover" android:background="@color/cn_wx_transparent" android:layout_width="fill_parent" android:layout_height="wrap_content" />
<TextView android:textSize="16.0sp" android:textColor="@color/cn_wx_exception_msg_color" android:layout_gravity="center" android:id="@id/cn_wx_container_page_exception" android:visibility="gone" android:layout_width="140.0dip" android:layout_height="80.0dip" android:text="@string/cn_wx_reload_weex_txt" />
</FrameLayout>
</LinearLayout>
複製代碼
這個頁面,經過抓包分析,該頁面的請求url: https://cn.alicdn.com/cainiao-weex/order_center/0.3.0/main/order-center-homepage.js?navtype=weex&fc=true&bs=black&orderType=send&referrer=guoguo%3A%2F%2Fgo%2Fsendpackage 裏面主要是Vue編寫的頁面代碼和邏輯。ide
分析了App三個主要的功能,大體對菜鳥裹裹的UI框架有所瞭解。 在Android工程師角度分析App使用的開源框架-3.菜鳥裹裹一文中,羅列了App使用的一些框架。 經過分析,物流詳情中使用了Atlas,寄件記錄使用了Weex,其餘的頁面,有興趣的同窗能夠自行分析。 雖然物流App,不像電商App(淘寶,天貓,京東等)那樣要求很高的動態化,不過菜鳥裹裹App使用了不少動態化框架,在不影響操做體驗的前提下,又增長了運營能夠操做性,仍是很是值得學習的。 之後有關菜鳥裹裹的分享,會集中在從零開始高仿菜鳥裹裹App(計劃中),但願同窗們多多支持。工具