商业级项目——基金客户端的架构设计与开发(下)(附源码)

简介: #项目简介 上一次的博文中详细分析了基金项目的整体架构和主界面的UI设计。今天分享地方是剩下的3个页面及相应功能的实现。#个人中心 个人中心界面,最开始会跳转到一个登陆界面,用户可以通过选择“身份证、基金账户、护照、户口本“,然后输入相应的账号和密码进行登陆。在这个界面中,还具有相应的记住密码,忘记密码功能。不输入是不允许进入账户的,当正确输入相应的账号密码后,通过和后台服务器进行验证
#项目简介
上一次的博文中详细分析了基金项目的整体架构和主界面的UI设计。今天分享地方是剩下的3个页面及相应功能的实现。
#个人中心
个人中心界面,最开始会跳转到一个登陆界面,用户可以通过选择“身份证、基金账户、护照、户口本“,然后输入相应的账号和密码进行登陆。在这个界面中,还具有相应的记住密码,忘记密码功能。不输入是不允许进入账户的,当正确输入相应的账号密码后,通过和后台服务器进行验证登陆,登陆进去之后是一个账户详情页,有持仓查询、盈亏查询、交易查询等功能,在持仓查询中hi有总资产,活期宝、今年收益的详细信息。在下面通过一个listview展示自己已买基金的名称、收益率、代号等信息。

#交易界面

在这个页面中,若用户未登录,则在该页面最上方会提示:您还未登录”同时在右上角会有一个登陆按钮,通过点击该按钮可跳转至登陆页面。在交易页面,有充值、快速提现、查询等操作。

private class MySpinnerAdapter extends BaseAdapter implements SpinnerAdapter {

    @Override
    public int getCount() {
        return mListData.size();
    }

    @Override
    public Object getItem(int position) {
        return mListData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.my_simple_spinner_item_recharge, null);
        }
        TextView view = (TextView) convertView
                .findViewById(R.id.recharge_spinner_view);
        view.setText(mListData.get(position).getName());
        if (mListData.get(position).getSupport_withhold() == 1) {
            view.setEnabled(true);
        } else {
            view.setEnabled(false);
        }
        return convertView;
    }

    @Override
    public View getDropDownView(int position, View convertView,
                                ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.my_simple_spinner_dropdown_item_recharge, null);
        }
        CheckedTextView view = (CheckedTextView) convertView.findViewById(R.id.recharge_spinner_item);
        view.setText(mListData.get(position).getName());
        if (mListData.get(position).getSupport_withhold() == 1) {
            view.setEnabled(true);
            view.setCompoundDrawablesWithIntrinsicBounds(null, null,
                    getResources().getDrawable(R.drawable.icon_withhold),
                    null);
        } else {
            view.setCompoundDrawablesWithIntrinsicBounds(null, null, null,
                    null);
            view.setEnabled(false);
        }
        return convertView;
    }

}

#帮助界面
最后一个节目就是一个帮助界面了,这里有消息中心、帮助、意见反馈、关于我们。当点击拨打客服电话后,会跳转到电话拨打界面。

/**
 * 获取帮助消息
 */
private Handler getHelpsHandler = new Handler() {
    public void handleMessage(Message msg) {
        dismissProgressDialog();
        switch (msg.what) {
            case BaseHandlerUI.TASK_NOTIFY_RETURN_DATA:
                if (msg.obj != null) {
                    try {
                        bean = (GetHelpsResultBean) msg.obj;
                        if (bean.state.equals("0")) {
                            mDatabaseAdapter.open_fund();
                            mDatabaseAdapter.deleteAllHelpsData();
                            List<TreeViewAdapter.TreeNode> treeNode = adapter.GetTreeNode();
                            treeNode.clear();
                            for (int i = 0; i < bean.list.size(); i++) {
                                mDatabaseAdapter.insertHelpsData(bean.list.get(i).ask, bean.list.get(i).reply);
                                TreeViewAdapter.TreeNode node = new TreeViewAdapter.TreeNode();
                                node.parent = bean.list.get(i).ask;
                                for (int ii = 0; ii < 1; ii++) {
                                    node.childs.add(bean.list.get(i).reply);
                                }
                                treeNode.add(node);
                            }
                            adapter.UpdateTreeNode(treeNode);
                            expandableList.setAdapter(adapter);
                            mDatabaseAdapter.close_funds();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                }
                break;
        }
    }
};


#异步任务类
我们都知道,在安卓的应用开发中,子线程是不能直接操作主线程的,所以,如果有耗时操作 又或者是密集操作,就只能放在子线程中去处理,但是,如果处理后的结果需要更改UI的显示内容,这时候,就只能使用handler或AsyncTask进行处理。

AsyncTask是一个异步任务类,可以很容易在子线程中处理耗时操作。里面包含三个泛型参数params、progress、result,分别表示:
1.params:在执行asynctack时需要传入的参数,可用于后台任务中使用。
2.progress:后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。
3.result:当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
一个简单的泛型类如下:
<span style="font-size:18px;">class DownloadTask extends AsyncTask<Void,Integer,Boolean>{}</span>
public HttpRequestAsyncTask(HttpRequestInfo request, TaskListener listener, Context context) {

    this.context = context;
    request.putParam("device_info", ConfigUtil.getImei(context))
            .putParam("app_version", ConfigUtil.getVersionName(context))
            .putParam("market", context.getString(R.string.channel_str));
    mListener = listener;
    mRequest = request;

}

public HttpRequestAsyncTask(HttpRequestInfo request, TaskListenerWithState taskListenerWithState,
                            Context context) {
    this.context = context;
    request.putParam("device_info", ConfigUtil.getImei(context))
            .putParam("app_version", ConfigUtil.getVersionName(context))
            .putParam("market", context.getString(R.string.channel_str));
    mListenerWithState = taskListenerWithState;
    mRequest = request;
}

@Override
protected HttpResponseInfo doInBackground(Void... params) {
    if (!ConfigUtil.isConnect(context)) {
        return new HttpResponseInfo(null, HttpTaskState.STATE_NO_NETWORK_CONNECT);
    }
    try {
        if (mRequest != null) {
            if (mRequest.getRequestID() == -2) {
                return new HttpResponseInfo(
                        HttpManager.postHttpRequest(mRequest),
                        HttpTaskState.STATE_OK);
            }
            return new HttpResponseInfo(
                    HttpManager.postHttpsRequest(mRequest),
                    HttpTaskState.STATE_OK);
        }
    } catch (SocketTimeoutException e) {
        e.printStackTrace();
        return new HttpResponseInfo("{\"result\":\"3\"}", HttpTaskState.STATE_OK);
    } catch (UnknownHostException e) {
        e.printStackTrace();
        return new HttpResponseInfo("{\"result\":\"3\"}", HttpTaskState.STATE_OK);
    } catch (Exception e) {
        e.printStackTrace();
        return new HttpResponseInfo("{\"result\":\"3\"}", HttpTaskState.STATE_OK);
    }
    return null;
}


#HTTP编程

Http编程有请求和响应,这里我们把对json数据年度解析放到这一部分来讲解:

/**
 * Http 请求
 */
public class HttpRequestInfo {

    public static final String TAG = "HttpRequestInfo";

    /* Http 请求的 URL */
    private String requestUrl;
    private int requestID;
    private Map<String, String> requestParams;

    public HttpRequestInfo(String url) {
        this.setRequestUrl(url);
        requestParams = new HashMap<String, String>();
    }

    public HttpRequestInfo(String url, Map<String, String> params) {
        this.setRequestUrl(url);
        this.setRequestParams(params);
    }

    public String getRequestUrl() {
        return requestUrl;
    }

    public void setRequestUrl(String requestUrl) {
        this.requestUrl = requestUrl;
    }

    public Map<String, String> getRequestParams() {
        return requestParams;
    }

    public void setRequestParams(Map<String, String> requestParams) {
        this.requestParams = requestParams;
    }

    public String getParamsStr() {
        String str = "";
        if (requestParams != null) {
            for (Entry<String, String> entry : requestParams.entrySet()) {
                String key = entry.getKey();
                String val = entry.getValue();
                key = URLEncoder.encode(key);
                val = URLEncoder.encode(val);
                str += key + "=" + val + "&";
            }
        }
        if (str.equals("")) {
            return null;
        }
        LogUtil.i(TAG, this.requestUrl + str);
        return str;
    }

    public HttpRequestInfo putParam(String key, String value) {
        this.requestParams.put(key, value);
        return this;
    }

    public int getRequestID() {
        return requestID;
    }

    public void setRequestID(int requestID) {
        this.requestID = requestID;
    }
}
对于响应:

/**
 * Http 响应
 */
public class HttpResponseInfo {
    public enum HttpTaskState {
        STATE_OK,
        STATE_NO_NETWORK_CONNECT,
        STATE_TIME_OUT,
        STATE_UNKNOWN,
    }

    public HttpResponseInfo(String result, HttpTaskState state) {
        this.result = result;
        this.state = state;
    }

    private HttpTaskState state;
    private String result;

    public HttpTaskState getState() {
        return state;
    }

    public void setState(HttpTaskState state) {
        this.state = state;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

}



#SqLite编程
数据库是一个非常重要的知识点,这里主要是分享一个这个基金中的数据库,这个数据库是一个小型的轻量级的数据库,

SQLiteOpenHelper有onCreate()、onUpgrade()两个方法。

private static class DatabaseHelper extends SQLiteOpenHelper {

    public DatabaseHelper(Context context, String name,
                          CursorFactory factory, int version) {
        super(context, DB_NAME, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建所有数据库表
        db.execSQL(DB_CREATE_FUND);
        db.execSQL(DB_CREATE_FAV_FUND);
        db.execSQL(DB_CREATE_HELPS_INFO);
        db.execSQL(DB_CREATE_FUND_DETAIL);
        db.execSQL(DB_CREATE_MSG);
    }

    // 更新基金数据
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion,
                          int newVersion) {

        db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_FUND);
        db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_FAV_FUND);
        db.execSQL("DROP TABLE IF EXISTS " + DB_CREATE_HELPS_INFO);
        db.execSQL("DROP TABLE IF EXISTS " + DB_CREATE_FUND_DETAIL);
        db.execSQL("DROP TABLE IF EXISTS " + DB_CREATE_MSG);

        onCreate(db);
    }
}

当然了,仅仅通过一篇博文是不可逆完全完整的说完整个项目了,这里写的仅仅是冰山一角,更多的内容还是希望读者自己去发现并学到里面的精华部分!当然咯,我相信有一部分人读了也基本上没看懂我写的是什么,那么请下载源码看看,互相学习咯!


源码下载地址:http://download.csdn.net/detail/sdksdk0/9461193


目录
相关文章
|
2天前
|
Kubernetes 监控 开发者
探索后端开发中的微服务架构实践
在现代软件开发领域,微服务架构作为一种灵活、可扩展的后端解决方案,正逐渐取代传统的单体式架构。本文将深入探讨微服务的设计理念、实施策略及其在企业级应用中的具体应用案例,旨在为读者提供一套系统的微服务实践指南。通过对比分析微服务与单体架构的性能差异,结合具体数据和案例研究,本文揭示了微服务在提高系统可维护性、可扩展性和敏捷性方面的优势。最后,文章讨论了微服务实施过程中可能遇到的挑战及解决策略,为后端开发者提供了宝贵的参考和启示。
|
2天前
|
JSON JavaScript 小程序
|
4天前
|
Kubernetes 搜索推荐 开发者
探索后端开发的未来之路:微服务架构与容器化技术
随着云计算技术的不断成熟和普及,后端开发领域正经历着前所未有的变革。本文将深入探讨微服务架构和容器化技术如何重塑后端开发的面貌,提升系统的可扩展性、灵活性和可靠性。通过分析现代后端系统面临的挑战,我们将展示微服务和容器化如何提供解决方案,并预测这些技术如何塑造后端开发的未来发展。
20 3
|
3天前
|
消息中间件 监控 Kubernetes
后端开发中的微服务架构实践与挑战
在数字化时代的浪潮下,后端开发不断演化,微服务架构应运而生,成为解决复杂系统设计问题的一种新范式。本文将深入探讨微服务架构的核心概念、实施策略以及面临的主要技术挑战,同时结合具体案例分析其在实际开发中的应用效果和价值体现,旨在为后端开发人员提供一套系统的微服务实践指南和思考框架。
|
6天前
|
敏捷开发 消息中间件 监控
探索后端开发中的微服务架构
本文深入探讨了微服务架构在后端系统设计中的关键作用,分析了其优势、挑战与实施策略。通过比较传统单体应用与微服务的异同,文章阐述了微服务如何促进敏捷开发和持续交付,同时指出了在采用微服务时可能遇到的技术债务和管理复杂性问题。结合具体案例,本文为读者提供了关于如何有效实施微服务的实用建议。 【7月更文挑战第21天】
|
2天前
|
监控 安全 前端开发
交易所系统开发(源码正式版)/需求逻辑/玩法详情/规则架构
交易所源码开发是指基于特定的需求和要求,从头开始构建一个自定义的交易所平台的开发过程。这种开发可以包括以下几个关键方面:
|
2天前
|
敏捷开发 运维 负载均衡
探索后端开发中的微服务架构:优势与挑战
本文深入探讨了微服务架构在后端开发中的应用,分析了其设计原则、技术优势及面临的主要挑战。通过对比传统单体架构,我们揭示了微服务如何促进敏捷开发和持续交付,同时指出了在采用微服务过程中可能遇到的复杂性和治理问题。文章旨在为后端开发者提供一份微服务实践的指南,帮助他们在架构选择上做出更明智的决定。 【7月更文挑战第24天】
|
6天前
|
运维
什么说Lambda架构给开发和运维带来了“深重的灾难”
什么说Lambda架构给开发和运维带来了“深重的灾难”
|
4天前
|
缓存 监控 负载均衡
探索微服务架构中的API网关模式
在微服务架构的海洋中,API网关如同一座灯塔,指引着服务间的通信。本文将深入探讨API网关的设计哲学、关键功能以及在实际应用中的考量因素。通过对比分析,我们将揭示API网关如何在提高系统可维护性、增强安全性和优化性能方面发挥其不可或缺的作用。此外,文章还将提供实践指南,帮助读者在构建或改进微服务架构时,做出明智的API网关选择和部署决策。
|
4天前
|
Kubernetes 持续交付 开发者
探索后端技术的未来:微服务架构与容器化部署的融合
在数字化时代的浪潮中,后端技术正经历着前所未有的变革。本文将深入探讨微服务架构和容器化部署如何共同推动后端技术的发展,提升应用的性能、可扩展性和可靠性。通过分析现代软件开发的需求,我们将揭示这两种技术如何互补,以及它们在未来后端开发中的潜力和挑战。