前些日子幾大互聯網巨頭展開了一輪網盤空間大戰。一下子從G級別提高到了T級別。以后誰的空間沒有1T估計都不好意思開口了~~~
試用了一下360雲盤的客戶端,比較小清新(不是給360打廣告~~~)。剛好UI這一塊是我最不擅長的,於是萌發了練習模仿它的UI的念頭~~~順便把復習一下自定義控件的使用。
以下是完成的效果圖,左邊是官方的,右邊是我模仿的:


還挺像的吧~~~
先介紹一個神器:UI Automator Viewer
這個SDK的tools文件夾或DDMS中都可以找到。

它可以很方便地查看UI的視圖層級和UI控件的具體位置與實現。相當好用,有了它我們就不用去猜官方到底是怎么實現的、使用什么布局了。
具體實現
先從登錄頁面開始:
這個頁面是比較簡單的,從工具來看它的輸入框是這么實現的:

一下子就清晰了。邊框的線可以用一個“NinePath”圖片來做:

關於NinePath的用法,可以查看官方教程:
http://developer.android.com/intl/zh-cn/tools/help/draw9patch.html
接下來第就是自動定義按鈕樣式了。
首先,直接用一個背景圖片肯定是不夠的,因為這樣就沒有按下的效果了。也就是說我們要把一系列的圖片組成起來,讓它們根據控件的不同狀態去選擇。比如我們可以這么寫:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/btn_add_accounts_pressed" android:state_pressed="true"/> <item android:drawable="@drawable/btn_add_accounts_normal"/> </selector>
還是比較好理解的,但有一點要注意,一般要在最后給一個沒有android:state_xxx的item。這個item表示當前面的狀態都不匹配時,使用這個item。
這個xml一般放在res/drawable目錄下。然后我們就它設置到按鈕的背景上即可。
關於style的使用:
以前我寫布局的時候是比較少用style的,但這顯然是不利的。因為android引入style的目的就在於,提供一個類似於HTML的編寫方式,讓樣式可以重復使用,減少重復代碼。而且對於樣式的修改,只需要改動一處即可。
我個人的覺得,如果一個樣式只用到一次就沒必要把它抽到styles.xml文件中,因為抽出樣式會大大妨礙我們閱讀布局文件的。但如果這個樣式被重復使用了,那就很有必要了。
比如剛剛的邊框,就可以寫到一個style里面:
<style name="accountInputBorder"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">36dp</item> <item name="android:layout_marginLeft">18dp</item> <item name="android:layout_marginRight">18dp</item> <item name="android:background">@drawable/login_border</item> <item name="android:gravity">center_vertical</item> <item name="android:paddingLeft">10dp</item> <item name="android:orientation">horizontal</item> </style>
接下來是重點:

用到了SlidingMenu可以github上的一個開源項目:
https://github.com/jfeinstein10/SlidingMenu
左右切換可以用android-support-v4.jar提供的ViewPager,配合Fragment。

上邊的指示器,360是這么實現的:

我估計它是把下邊的藍色指示條用一個RelativeLayout來盛放了。但這個是可以不用的。比如我的實現:

可以用一個TextView就實現,對於要讓文字居中,只需要一個android:gravity=”center”即可。根據Android官方文檔,減少視圖的層級有利於程序的性能。
至於標識的切換,我們只需要給ViewPager設置一個OnPageChangeListener,然后在具體的方法中判斷當前頁面的編號,並改變相應的title顏色。
接下來我遇到的第一個麻煩,我該如何確定

的高度呢?(百度一下“gridview 高度”,發現好多人遇到這個問題)
顯然我是沒有辦法使用“硬編碼”的方式來實現的,因為android設備的屏幕分辨率太多,屏幕比例也很多奇葩的。
最后我只能通過動態計算的方式來實現:
第一個dp與px的轉化,dp(也叫dip density-independent pixels),引入這個單位的原因應該是考慮到屏幕分辨率的原因,比如同一個100px * 100px的控件,在相同尺寸分辨率為320p和1080p上看,大小相差很多的。而px與dp是存在一定的比例關系的,如果分辨率為160,那么就是1px = 1dp。如果分辨率為240,就是1.5px = 1dp。具體的換算和理詳細的介紹,請自選百度。
在代碼在,我們只需要getResources().getDisplayMetrics().density,就可以獲得這個比例系數了。
ListView其實沒什么好說的,基本上都是通過的寫法了,寫過一次就知道怎么用了~~~
SlidingMenu的使用,github上的SlidingMenu是很容易用的,官方的Demo也相當給力。看一下再試一下,基本知道怎么用了。比如在我的工程中:
slidingMenu = new SlidingMenu(this); slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE); // 滑動方式 slidingMenu.setShadowDrawable(R.drawable.shadow_right); // 陰影 slidingMenu.setShadowWidth(30); // 陰影寬度 slidingMenu.setBehindOffset(80); // 前面的視圖剩下多少 slidingMenu.setMode(SlidingMenu.RIGHT); // 左滑出不是右滑出 slidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT); slidingMenu.setMenu(R.layout.menu_frame); // 設置menu容器 FragmentManager fm = getSupportFragmentManager(); fm.beginTransaction().replace(R.id.menu_frame, new MenuFragment()).commit();
自定義進度條:
進度條和按鈕不同,它是有兩層的,使用的是layer-list這種drawable文件。它根據id來設置到不同的位置:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@android:id/background" android:drawable="@drawable/progress_bar_bg"> </item> <item android:id="@android:id/progress" android:drawable="@drawable/progress_bar_progress"/> </layer-list>
關於SlidingMenu的使用:
SlidingMenu是一個庫項目,在我們的項目中引用,只需要在Properties中Add即可。

源碼下載:
http://pan.baidu.com/share/link?shareid=1000621439&uk=1812042723
