从零开始做开发——开发中项目框架结构搭建

最详细的结构目录搭建(MVC模式)

一. 刚建好的项目结构

上面是我刚建好的项目,只有工具自动生成的 mainactivity和对应的xml文件,在日常开发工作中,我们会用到很多的类,大点的项目单Activity就可以霸占你一整个屏幕的高度,何况还要加上fragment、工具类和自定义的控件等等。如果把它们都放在同一个文件夹里,维护起来得有多难,试想一下在上百个文件里找你要的那个,简直丧心病狂。所以我们都需要整理我们的目录树,提前思考项目开发中会用到的类并进行分类。下图是我做的一个简单例子:
  • activity用来放置activity界面
  • adapter用来放适配器,无论是recyclview还是viewpager,几乎都会用到
  • base用来放置我们的基类
  • config放置常量
  • fragment里放fragment界面
  • model用来放数据模型
  • utils里放的是工具类
  • view文件夹放的是我们的自定义view

分类明确后,再要找到指定类就简单方便多了,当然还可以根据项目需求新增其他的文件夹,可以根据项目的模块再在每个分类下再分类,没有谁规定死一定要怎么样构建你的项目,怎么做方便就怎么样来。

二.关于基类

基类,顾名思义就是基础类。就像盖房子需要打地基,地基打得稳了,房子才稳。
基类在面向对象设计中被定义为包含所有实体共性的class类。基类可以简化我们的代码,减少我们代码冗余,让我们的代码变得更简单易懂。
下面简单写出用于activity和fragment的基类,我会写上详细的注释。

/**
 * 作者:Created by qujifan on 2018/10/17.
 * 邮箱:joker_qjf@foxmail.com
 * 描述: 公共接口
 *
 */

public interface IBase {

    /**
     * 显示进度条
     * @param flag 是否可取消
     * @param message 要显示的信息
     */
    void showProgress(boolean flag, String message);

    /** 隐藏进度条 */
    void hideProgress();

    /**
     * 根据资源文件id弹出toast
     * @param resId 资源文件id
     */
    void showToast(int resId);

    /**
     * 根据字符串弹出toast
     * @param msg 提示内容
     */
    void showToast(String msg);

    /**
     * 显示自定义的加载框
     * @param msg   提示内容
     * @param cancelable   是否可取消
     */
    void showLoadingDialog(String msg, boolean cancelable);

    /**
     * 自定义样式的right弹框
     * @param msg   提示内容
     * @param delay  显示的时长
     */
    void showRightDialog(String msg, int delay);

    /**
     * 自定义样式的error弹框
     * @param msg   提示内容
     * @param delay  显示的时长
     */
    void showErrorDialog(String msg, int delay);

    /** 隐藏自定义的弹框 */
    void dissDialog();


}
/**
 * 作者:Created by qujifan on 2018/10/17.
 * 邮箱:joker_qjf@foxmail.com
 * 描述: activity的基类,不限制继承FragmentActivity,写的时候可以根
 * 据项目需求更改,最终的父类都是Activity
 */

public abstract class BaseActivity extends FragmentActivity implements IBase, DialogInterface.OnDismissListener {
    //根据所在界面输出log日志
    public String TAG = this.getClass().getSimpleName();
    //提示弹出框
    private Dialog mDialog;
    private Handler disHandler;
    private Runnable disRunnable;

    private TextView tvToastText;
    private Toast mToast;
    private MMKV mkv;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        disHandler = new Handler();
        disRunnable = () ->{
            mDialog.dismiss();
        };

        initContentView();
        initView();
        initController();
        initListener();
    }

    /**
     * 初始化布局
     */
    public abstract void initContentView();

    /**
     * 初始化控件
     */
    public abstract void initView();

    /**
     * 初始化控制中心
     */
    public abstract void initController();

    /**
     * 初始化监听事件
     */
    public abstract void initListener();

    @Override
    public void showProgress(boolean flag, String message) {

    }

    @Override
    public void hideProgress() {

    }

    /**
     * 获取mmkv实例
     * @return
     */
    public MMKV getMmkv(){
        if(mkv!=null){
         return mkv;
        }
        return mkv =  MMKV.defaultMMKV();
    }

    /**
     * 初始化toast
     * @param msg
     */
    private void initToast(String msg){
        View view = getLayoutInflater().inflate(R.layout.layout_toast, null);
        tvToastText = view.findViewById(R.id.tv_toast_text);
        mToast = new Toast(this);
        mToast.setGravity(Gravity.CENTER,0,0);
        mToast.setDuration(Toast.LENGTH_SHORT);
        mToast.setView(view);
        tvToastText.setText(msg);
        mToast.show();
    }

    @Override
    public void showToast(int resId) {
        showToast(getString(resId));
    }

    @Override
    public void showToast(String msg) {
        if(mToast!=null){
            tvToastText.setText(msg);
            mToast.show();
        }else{
            initToast(msg);
        }
    }

    @Override
    public void showLoadingDialog(String msg, boolean cancelable) {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
        }
        LayoutInflater inflater = LayoutInflater.from(this);
        View v = inflater.inflate(R.layout.layout_dialog_loding, null);

        TextView tvText =  v.findViewById(R.id.tv_text);

        tvText.setText(msg);

        mDialog = new Dialog(BaseActivity.this, R.style.dialog);
        mDialog.setCancelable(cancelable);
        mDialog.setContentView(v, new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mDialog.setOnDismissListener(this);
        mDialog.show();
    }

    @Override
    public void showRightDialog(String msg, int delay) {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
        }
        LayoutInflater inflater = LayoutInflater.from(this);
        View v = inflater.inflate(R.layout.layout_dialog_right, null);

        ImageView image =  v.findViewById(R.id.iv_img);
        TextView tvText =  v.findViewById(R.id.tv_text);

        image.setImageResource(R.drawable.icon_complete);
        tvText.setText(msg);

        mDialog = new Dialog(BaseActivity.this, R.style.dialog);
        mDialog.setCancelable(true);
        mDialog.setContentView(v, new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mDialog.setOnDismissListener(this);
        mDialog.show();
        //delay时间后关闭弹框
        disHandler.postDelayed(disRunnable,delay);
    }

    @Override
    public void showErrorDialog(String msg, int delay) {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
        }
        LayoutInflater inflater = LayoutInflater.from(this);
        View v = inflater.inflate(R.layout.layout_dialog_right, null);


        ImageView image =  v.findViewById(R.id.iv_img);
        TextView tvText =  v.findViewById(R.id.tv_text);

        image.setImageResource(R.drawable.icon_error);
        tvText.setText(msg);

        mDialog = new Dialog(BaseActivity.this, R.style.dialog);
        mDialog.setCancelable(true);
        mDialog.setContentView(v, new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mDialog.setOnDismissListener(this);
        mDialog.show();
        disHandler.postDelayed(disRunnable,delay);
    }

    @Override
    public void dissDialog() {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
        }
    }

    /**
     * mDialog 的Dismiss事件监听
     * @param dialog
     */
    @Override
    public void onDismiss(DialogInterface dialog) {

    }

    /**
     * 统一处理back操作,因为每个界面都会需要返回操作
     * @param v
     */
    public void back(View v) {
        onBackPressed();
    }

    /**
     * 打开一个新的activity
     *
     * @param pClass  目标activity
     */
    protected void openActivity(Class<?> pClass) {
        openActivity(pClass, null);
    }

    /**
     * 打开一个新的activity并传递数据
     *
     * @param pClass   目标activity
     * @param pBundle  Bundle类型参数传递
     */
    protected void openActivity(Class<?> pClass, Bundle pBundle) {
        Intent intent = new Intent(this, pClass);
        if (pBundle != null) {
            intent.putExtras(pBundle);
        }
        startActivity(intent);
    }

}
/**
 * 作者:Created by qujifan on 2018/10/17.
 * 邮箱:joker_qjf@foxmail.com
 * 描述: fragment的基类
 */

public abstract class BaseFragment extends Fragment {
    public FragmentActivity mActivity;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    /**
     * 返回一个需要展示的View
     *
     * @param inflater
     * @param container
     * @param savedInstanceState
     * @return
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mActivity = (FragmentActivity) getActivity();
        View view = initView(inflater);
        initFindViewById(view);
        return view;
    }

    /*
     * 当Activity初始化之后可以在这里进行一些数据的初始化操作
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initData();
        initEvent();
    }

    /**
     * 子类实现此抽象方法返回View进行展示
     *
     * @return
     */
    public abstract View initView(LayoutInflater inflater);

    /**
     * 初始化控件
     */
    protected abstract void initFindViewById(View view);

    /**
     * 子类在此方法中实现数据的初始化
     */
    public abstract void initData();

    /**
     * 子类可以复写此方法初始化事件
     */
    protected void initEvent() {

    }
}

然后我们的activity就可以写成这样:

fragment就成了这样:

三.end

不难看出来,子类的“共性”被放在了基类里面,我们activity及fragment中所写的代码就少了很多,看上去也更加的简洁明了。我只是简单介绍了基类的使用,他还有很多种写法,可以更方便性能更好,我们也可以把它用在adapter、view等等的class类上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值