轉載請注明出處
作者:developerHaoz
Github 地址:developerHaoz
本文為 手把手教你從零開始做一個好看的 APP - Day two ,如果想看該系列的其他文章,請點擊以下連接
手把手教你從零開始做一個好看的 APP - Day three
手把手教你從零開始做一個好看的 APP - Day four
手把手教你從零開始做一個好看的 APP - Day five
Day two
一、界面的設計及實現(xiàn)
既然我們想要完成一個好看的 APP,那么好看的界面便是必不可少的,這里我強烈推薦 APP 界面的設計必須盡量遵從 Google 提出的 Material Design,在這里推薦一個能夠讓我們實現(xiàn) Material Design 變得更加簡單的網(wǎng)站 material design palette,我這個 APP 的配色就是用這個網(wǎng)站完成的,貼幾張圖片,讓你感受一下它的強大


借助這個網(wǎng)站便能讓我們完成 APP 的配色以及圖標的收集,為下一步功能的實現(xiàn),先打好了基礎,至于界面的設計就仁者見仁智者見智了,篇幅有限,我就不多講了。
APP 的最終設計效果如下:

二、公共類的實現(xiàn)
因為這個項目有三個模塊,有一些東西其實是可以通用的,如果我們先把這些能夠通用的東西,封裝起來,供給所有的模塊調用的話,相信會大大提高我們的開發(fā)效率。
1、網(wǎng)絡工具類的封裝
這個 APP 中,很多地方都要用到網(wǎng)絡請求,因此也就很有必要將網(wǎng)絡請求封裝起來,因為這個 APP 的規(guī)模比較小,因此我選擇了 Volley 這個網(wǎng)絡框架作為我們網(wǎng)絡請求庫,把網(wǎng)絡請求封裝起來,那哪個地方需要,調用一下就行了。對于網(wǎng)絡請求,我覺得每個程序員都該懂點 HTTP,這里附上一篇有關 HTTP 的文章 程序員都該懂點 HTTP。
先讓我們來寫個將網(wǎng)絡請求進行回調的接口
public interface VolleyResponseCallback {
void onSuccess(String response);
void onError(VolleyError error);
}
然后將網(wǎng)絡請求封裝起來
public class VolleyHelper {
/**
* 用于發(fā)送 Get 請求的封裝方法
*
* @param context Activity 的實例
* @param url 請求的地址
* @param callback 用于網(wǎng)絡回調的接口
*/
public static void sendHttpGet(Context context, String url, final VolleyResponseCallback callback){
RequestQueue requestQueue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(url
, new Response.Listener<String>() {
@Override
public void onResponse(String s) {
callback.onSuccess(s);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
callback.onError(error);
}
});
requestQueue.add(stringRequest);
}
}
2、Json 解析的幫助類
因為我們這個 APP 中,獲取到的數(shù)據(jù)都是 Json 格式的,因此也就有必要將有關的 Json 解析封裝成一個工具類,傳入一個 String 類型的數(shù)據(jù),直接得到數(shù)據(jù)實體類的 List。
public class CommonParser {
/**
* 用來解析列表性的JSON數(shù)據(jù)
* 如:
* {"success":true,"fileList":[{"filename":"文件名1","fileSize":"文件大小1"},
* {"filename":"文件名2","fileSize":"文件大小2"}]}
*
* @param result 網(wǎng)絡返回來的JSON數(shù)據(jù) 比如:上面的整串數(shù)據(jù)
* @param successKey 判斷網(wǎng)絡是否成功的字段 比如:上面的success字段
* @param arrKey 列表的字段 比如:上面的fileList字段
* @param clazz 需要解析成的Bean類型
* @param <T> 需要解析成的Bean類型
* @return
*/
public static <T> List<T> parseForList(String result, String successKey, String arrKey, Class<T> clazz) {
List<T> list = new ArrayList<>();
JSONObject rootJsonObject = null;
try {
rootJsonObject = new JSONObject(result);
if (rootJsonObject.getBoolean(successKey)) {
JSONArray rootJsonArray = rootJsonObject.getJSONArray(arrKey);
Gson g = new Gson();
for (int i = 0; i < rootJsonArray.length(); i++) {
T t = g.fromJson(rootJsonArray.getJSONObject(i).toString(), clazz);
list.add(t);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
}
3、HomeActivity(主頁面)的封裝
主頁面我用的是 TabLayout + ViewPager + Fragment,也是現(xiàn)在主流 APP 主頁面的顯示方式。主界面底部是我們三個模塊的圖標和名稱,通過左右滑動能實現(xiàn)界面的跳轉。
底部圖標的實體類 CommonTabBean
public class CommonTabBean implements CustomTabEntity{
private int selectedIcon;
private int unselectedIcon;
private String title;
public CommonTabBean(String title){
this.title = title;
}
public CommonTabBean(String title, int selectedIcon, int unselectedIcon) {
this.title = title;
this.selectedIcon = selectedIcon;
this.unselectedIcon = unselectedIcon;
}
@Override
public String getTabTitle() {
return title;
}
@Override
public int getTabSelectedIcon() {
return selectedIcon;
}
@Override
public int getTabUnselectedIcon() {
return unselectedIcon;
}
}
ViewPager + Fragment 通用的 Adapter
public class CommonPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragments;
public CommonPagerAdapter(FragmentManager fragmentManager, List<Fragment> mFragments){
super(fragmentManager);
this.mFragments = mFragments;
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
}