菜鳥裹裹App分析系列-UI框架設計分析

前兩天分析了菜鳥裹裹的具體業務,菜鳥裹裹可以成功快遞行業的王牌產品,業務固然是很是重要的一環,不過App的操做體驗,以及可以讓用戶使用上更加方便快捷,也是成功的重要因素,因此此次就來分析菜鳥裹裹的UI框架設計。
此次對主要功能頁面進行分析,分析工具:php

  • UIAutomatorViewer-用來掃描和分析Android應用程序的UI組件的GUI工具
  • jadx-反編譯工具

首頁

圖中看出UI設計主要分爲了:底部的 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:展示列表和下拉刷新,分別經過ListViewPtrBirdFrameLayout實現

物流詳情

物流詳情的頁面比較有特點,地圖展現訂單的軌跡,列表展現從發貨到收貨各個節點信息。 UI結構圖:

  • 最底層是全屏mapview
  • 菜單操做層覆蓋在mapview上
  • 最上面一層是物流從發貨到收貨的節點列表

不過從反編譯中沒法找到對應的佈局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(計劃中),但願同窗們多多支持。工具

相關文章
相關標籤/搜索