搭建一个android项目的准备工作

我们开始一个主流的android项目至少或者最好包含哪些内容呢

图片加载框架( fresco http://www.fresco-cn.org/
http网络框架(https://github.com/hongyangAndroid/okhttputils
crash收集机制(bugly https://bugly.qq.com/v2/
多渠道打包( http://blog.csdn.net/szydwy/article/details/50854676
app统计、apk升级、推送等(友盟)

沉浸式的状态栏(https://github.com/D-clock/AndroidSystemUiTraining/tree/master/note
http接口的数据缓存
统一的工具栏toolbar(https://github.com/D-clock/AndroidSystemUiTraining/tree/master/note

统一对话框、toast、PopupWindows、SharePrefrence、log等使用工具类
注解框架Butterknife
基类的设计BaseActivity,BaseFragment等
viewpager+fragment模式懒加载
列出来的这些内容都是最基本的,当然以上这些根据自身项目需要自行增加或删除,就像沉浸式状态不需要也可以。
下面我们看下如何搭建项目,把上面这些基本功能加进来。

我们先来看下效果

这里写图片描述

这里写图片描述

公用的libray

项目使用传统的MVC架构,我们要新建一个libray项目,包括业务无关的逻辑,主工程引用此项目。
library工程目录
那么是哪些业务无关的的逻辑呢?
base包中存放的是业务无关的BaseActivity,BaseFragment
okhttp包中存放的是网络框架的封装补充
view包存存放一些共用的自定义控件
utils包中存放统一对话框、toast、PopupWindows、SharePrefrence、log等使用工具类
为什么要单独设计一个存放业务无关逻辑的library项目?
试想一下,随着项目的逐渐增大,引用的library越来越多,如果其他library也要使用网络访问,对话框等,是不是又得重新写一份。
如果我们有个共用的library,其他的library应用这个共用的,那么里面的类都可以共同使用了。

library中base包
BaseActivity的实现如下

public abstract class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getContentViewResID());
        ButterKnife.bind(this);//必须setContentView后调用
        initVariables();
        initViews(savedInstanceState);
        loadData();
    }

    /**
     * 初始化变量,包括intent传递进来的数据
     */
    protected abstract void initVariables();

    /**
     * 初始化控件
     * @param savedInstanceState
     */
    protected abstract void initViews(Bundle savedInstanceState);

    /**
     * layout xml
     * @return
     */
    public abstract int getContentViewResID();
    /**
     * 逻辑处理
     */
    protected abstract void loadData();

    @Override
    protected void onResume() {
        super.onResume();
        MobclickAgent.onResume(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        MobclickAgent.onPause(this);
    }
}

在onResume()和onPause()中定义了友盟的统计,继承至BaseActivity的Activity 可以实现统计功能,当然也可以选择其他的第三方统计方式
oncreate中ButterKnife.bind(this);继承至BaseActivity的Activity可以方便使用ButterKnife
oncreate中调用initVariables();initViews(savedInstanceState);loadData();这3个abstract方法,继承至BaseActivity的Activity必须实现这3个方法,这样Activity看起来相对清晰

BaseIndicatorActivity实现

public abstract class BaseIndicatorActivity extends AppCompatActivity {
    public String[] mTitles;
    public SimpleViewPagerIndicator mIndicator;
    public LazyViewPager mViewPager;
    protected Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        initViews();
        setTitles();
        initDatas();
        initEvents();
    }

    public abstract void initViews();


    public abstract void setTitles();


    public abstract int getFragmentCount();

    public abstract Fragment getFragment(int posation);


    public void onPause() {
        super.onPause();
        MobclickAgent.onPause(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        MobclickAgent.onResume(this);
    }

    private void initEvents() {
        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                mIndicator.setTextColor(position);
            }

            @Override
            public void onPageScrolled(int position, float positionOffset,
                                       int positionOffsetPixels) {
                mIndicator.scroll(position, positionOffset);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

    }

    private void initDatas() {
        mIndicator.setTitles(mTitles);
        LazyFragmentPagerAdapter lazyFragmentPagerAdapter = new LazyFragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            protected Fragment getItem(ViewGroup container, int position) {
                return getFragment(position);
            }

            @Override
            public int getCount() {
                return getFragmentCount();
            }
        };
        mViewPager.setAdapter(lazyFragmentPagerAdapter);
        mIndicator.setViewPager(mViewPager);
    }

集成BaseIndicatorActivity,实现setTitles,getFragment方法可以很方便实现首页指示器导航,viewpager+fragment模式懒加载

utils包
ChannelUtil是多渠道打包工具类,不清楚的可以看下http://blog.csdn.net/szydwy/article/details/50854676,现在360渠道要单独加固,加固后会重新打包签名,META-INF下的渠道标识会删除掉,所以最后增加配置,从manifest中再读一次渠道号。

mChannel = getAppMetaData(context,"UMENG_CHANNEL");
if(!TextUtils.isEmpty(mChannel)){
   //保存sp中备用
   saveChannelBySharedPreferences(context, mChannel);
   return mChannel;
}

DialogUtils是统一的对话框工具类,参考https://github.com/afollestad/material-dialogs
实现如下:

public class DialogUtils {
    public interface OnClickDialogLinstener {
        public void clickOK(Dialog mBindDialog);

        public void clickCancel(Dialog mBindDialog);

    }
    public static void showMdDialog(Context context, String title, String ok, String cancel, final OnClickDialogLinstener onClickDialogLinstener) {
        new MaterialDialog.Builder(context)
                .title(title)
                .positiveText(ok)
                .negativeText(cancel)
                .onAny(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        if(which.ordinal()==0){
                            onClickDialogLinstener.clickOK(dialog);
                        }else if(which.ordinal()==2){
                            onClickDialogLinstener.clickCancel(dialog);
                        }
                    }
                })
                .show();
    }


    public static void showDialog(Context context, final OnClickDialogLinstener onClickDialogLinstener, int title, int... buttons) {
        if (buttons.length == 1) {
            showMdDialog(context, context.getString(title), context.getString(buttons[0]), null, onClickDialogLinstener);
        } else if (buttons.length == 2) {
            showMdDialog(context, context.getString(title), context.getString(buttons[0]), context.getString(buttons[1]), onClickDialogLinstener);
        }
    }
    public static void showDialog(Context context, final OnClickDialogLinstener onClickDialogLinstener, String title, String... buttons) {
        if (buttons.length == 1) {
            showMdDialog(context, title, buttons[0], null, onClickDialogLinstener);
        } else if (buttons.length == 2) {
            showMdDialog(context, title, buttons[0], buttons[1], onClickDialogLinstener);
        }
    }
}

定义了OnClickDialogLinstener ,如果以后要修改对话框样式,可以统一修改,使用的话:

DialogUtils.showDialog(getActivity(), new DialogUtils.OnClickDialogLinstener() {
    @Override
    public void clickOK(Dialog mBindDialog) {

    }

    @Override
    public void clickCancel(Dialog mBindDialog) {

    }
},"showDialog", "cancel", "ok");

ObjectCacheManager是缓存http接口数据使用,根据接口的入参做为缓存数据的key,自定义缓存时间,避免每次都重点内容请求网络,节省用户流量

主工程
我们看下主工程的包结构,将相应的activity、adapter、entity都放入各种对应的包中,小组内开发定义好统一的命名规范和编码规范。
主工程目录

首页使用首页DrawerLayout+FragmentTabHost+Toolbar
网络框架使用okhttp,使用鸿洋已经封装好的框架https://github.com/hongyangAndroid/okhttputils
图片框架使用facebok fresco http://www.fresco-cn.org/
关于框架的选择可根据实际情况自行选择
appstroe中定义需要调用的接口方法,使用起来比较清晰,直接查看IInfoSource就可以知道有哪些http接口

demo下载地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值