您的位置:首页 > 其它

从框架到完整项目搭建,实战项目《约个球》(1)-从splashActivity说起

2016-01-15 14:08 471 查看
项目github地址:https://github.com/CameloeAnthony/DatingBall

今天开始做自己的一个项目《约个球》,参考以前的项目,从零开始搭建。在整个项目的过程中会一步一步的搭建我们程序的框架。当然这个框架在以后的开发中是可以不断的用到的。不多说,开干。

项目开发环境:IntelliJ Idea

第1步:splashActivity也就是我们项目的启动的页面,也就是闪屏界面(可能会暂停三秒钟)。因为每一个项目中都会用到。所以我们在这里将它抽象出来,以后所有的类只需要继承这个类就可以了。

package com.nsu.library.app;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import com.nsu.library.R;
import com.nsu.library.utils.NetUtil;

/**
* Create By Anthony on 2016/1/15
* 当前类注释:splashActivity的超类。完成跳转和加载数据的功能
*
*/
public class SplashActivity extends AbsFragmentActivity {
private final short SPLASH_SHOW_SECONDS = 3;
private Context mContext = this;
private long mShowMainTime;

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

mShowMainTime = System.currentTimeMillis() + SPLASH_SHOW_SECONDS * 1000;
//step 1 全屏
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//step 2  网络连接判断
if (!NetUtil.isConntected(AbsApplication.app())) {
Toast.makeText(AbsApplication.app(),
getResources().getText(R.string.please_connnect_network),
Toast.LENGTH_SHORT).show();
}
//step3 TODO 初始化数据
initData();
//step4 TODO 跳转到其他activity
showView();
}

protected void initData() {
}

private void showView() {
AsyncTask showMainTask = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
if (System.currentTimeMillis() < mShowMainTime) {
try {
long sleepTime = mShowMainTime - System.currentTimeMillis();
if (sleepTime > 0) {
Thread.sleep(mShowMainTime - System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}

@Override
protected void onPostExecute(Object o) {
showMain();
finish();
}
};

showMainTask.execute();
}

protected void showMain() {
ViewDisplayer.showMainActivity(this);
}
}
分析:我们的activity会是一张全屏图片。在这里我们会做出网络的判断,也会加载数据和跳转到我们的MainActivity。

第2步:上面的SplashActivity继承自AbsFragmentActivity,这是我自定义的一个父类,继承自FrammentActivity(来自v4包):

package com.nsu.library.app;

import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.TextView;

import com.nsu.library.R;
import com.nsu.library.fragment.AbsFragment;

/**
* Create By Anthony on 2016/1/15
* 当前类注释:自定义的FragmentActivity,本项目中的所有的带Fragment的activity都将继承这个类
* 已实现:加载fragment,
* 待实现:广播的注册和监听,服务的绑定,友盟数据初始化等公共代码
*/
public abstract class AbsFragmentActivity extends FragmentActivity {

public static final String EXTRA_TITLE = "title";
private DisplayMetrics metric;

private Handler mHandler = new Handler();
private Fragment mFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
mHandler.post(new Runnable() {
@Override
public void run() {
mFragment = createFragment();
if (mFragment != null) {
getSupportFragmentManager().beginTransaction().replace(getFragmentContainerID(), mFragment).commit();
if (mFragment instanceof AbsFragment) {
((AbsFragment) mFragment).notifyDisplay();
}
}
}
});

}

@Override
protected void onDestroy() {
super.onDestroy();

}

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

@Override
protected void onResume() {
super.onResume();

TextView titleView = (TextView) findViewById(R.id.header_title);
if (titleView != null) {
setTitle(getIntent().getStringExtra(EXTRA_TITLE));
titleView.setText(getTitle());
}
}

/**
子类通过覆写这个方法传入的fragment将被这个类初始化
*/
protected Fragment createFragment() {
return null;
}

protected int getFragmentContainerID() {
return 0;
}

public boolean hasBack() {
return true;
}

public boolean hasHome() {
return true;
}

public boolean hasSetting() {
return true;
}

public float getmWidth() {
return metric.widthPixels;
}

public float getmHeight() {
return metric.heightPixels;
}

public float getScale() {
return getResources().getDisplayMetrics().density;
}

public void onBtnBackClick(View view) {
finish();
}

}
分析:在这个父类中我们定义Fragment的实现。以后就不需要每次复杂的写了。只需要调用createFragment和getFragmentContainerID两个方法。这里在后面的章节用到的时候会继续分析。

第3步: 在上面进行网络判断的时候我们应用了AbsApplication类。这是自己定义的一个Application类

package com.nsu.library.app;

import android.app.Application;
import com.nsu.library.utils.log.LocalFileUncaughtExceptionHandler;

/**
* Create By Anthony on 2016/1/15
* 当前类注释:Application的子类,本项目中的Application将继承本类。
* 当前功能:单例模式,异常捕获,由子类实现的获取url
*/
public abstract class AbsApplication extends Application {
private static AbsApplication sInstance;

public static AbsApplication app(){
return sInstance;
}

@Override
public void onCreate() {
super.onCreate();

sInstance = this;

Thread.setDefaultUncaughtExceptionHandler(new LocalFileUncaughtExceptionHandler(this,
Thread.getDefaultUncaughtExceptionHandler()));

}

/***************** About URL ***********************/
public static enum SourceType{
JSON, XML,SOAP
}
abstract public String getApplicationConfigUrl();
abstract public SourceType getSourceType();
abstract public String getFirstClassUrl();

}
第4步:在上面ViewDisplayer.showMainActivity(this);这个方法中我们就把MainActivity显示出来了,那么具体是怎么做到的呢?可以看看这个类:

package com.nsu.library.app;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import com.nsu.library.constants.Constants;
import com.nsu.library.utils.CommonUtils;

import java.util.HashMap;

/**
* Create By Anthony on 2016/1/15
* 当前类注释:用于activity的展示,通过设置type,获取对应的activity,面向对象的抽象
* 键值对将在raw://type_activity_map_base文件中定义
*
*/
public class ViewDisplayer {
private static HashMap<String, String> sTypeActivityNameMap = new HashMap<String, String>();
public static void initialize(Context context){
sTypeActivityNameMap.putAll(CommonUtils.simpleProperty2HashMap(context, Constants.BASE_TYPE_ACTIVITY_MAP_PATH));
sTypeActivityNameMap.putAll(CommonUtils.simpleProperty2HashMap(context, Constants.EXT_TYPE_ACTIVITY_MAP_PATH));
}

public static void showFragmentActivity(Context context, String type){
//TODO
}

public static void showMainActivity(Context context){
showMainActivity(context,"1001");
}

public static void showMainActivity(Context context, String type){
String activityName = sTypeActivityNameMap.get(type);
if(activityName != null){
Intent intent = new Intent();
intent.setClassName(context, activityName);
if(!(context instanceof Activity)){
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
}
}
}


分析:看到上面的类,可能大家都明白了。通过设置type,获取对应的activity,键值对将在raw://type_activity_map_base文件中定义。我们只是将这个键值对保存在了HashMap中,然后作比较。当前传入的showMainActivity(context,"1001");是1001,所以打开目录结构:



里面的内容很简单:

1001=com.nsu.datingball.activity.MainActivity


也就是说1001对应我们的MainActivity。所以跳转页就实现了呢。

第五步: 好了,从我们的框架搭建完成了。开始我们自己项目中,我们将上面的包当做library,我们就可以写出自己的SplashAcrivity了,简化了许多步骤。

package com.nsu.datingball.activity;

import android.os.Bundle;

import com.nsu.datingball.R;

/**
* Create By Anthony on 2016/1/15
*/
public class SplashActivity extends com.nsu.library.app.SplashActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_splash);
}

@Override
protected void initData() {
//        super.initData();
//TODO 在这里异步加载数据哦
}

@Override
protected void showMain() {
super.showMain();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: