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


    #项目简介
    上一次的博文中详细分析了基金项目的整体架构和主界面的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


  • 相关阅读:
    PowerDesigner反向工程操作步骤 以PowerDesigner15为例
    RegularExpressionValidator控件中正则表达式用法
    在C#中进行数据纵向不定行转横向列,多条信息成一行,例如员工薪资信息
    Oracle常见等待事件说明
    ORACLE 绑定变量用法总结(转)
    Configure Oracle 11gR2 RAC 一节点执行root.sh脚本报错
    ORACLE ASH/AWR
    db file sequential read 事件的优化(一)
    Redo Log Buffer的大小设置转载
    Oracle 判断 并 手动收集 统计信息 脚本
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6314857.html
Copyright © 2020-2023  润新知