自己写一个快速开发android模板
有时候有些代码以前写过,再开发的时候拿来用,就可以节约很多时间,毕竟写过的以前肯定有所了解,再写一次就没必要了,所以这次自己总结出很多应用都需要的一些共性的东西,写到一个模板,以后直接拿来用。首先分析一下:
1.一个应用,首先需要一个欢迎页面,用于展示公司logo啊,或者应用logo,大概展示两三秒。
2.然后就是登陆注册页面,几乎没有应用是没有登陆注册的吧?
3.打印吐司,activity跳转,activity覆盖别的activity,这些基本方法。
4.网络连接,处理json
5.主页面framents,大部分应用有,也加上吧
6.自定义actionbar,不用系统自带的,自定义的会比较灵活
总结了6点,以后还有的话,继续补充,首先一步一步来....
一,一个应用,首先需要一个欢迎页面,用于展示公司logo啊,或者应用logo,大概展示两三秒。
这个简单,学过安卓的都会,直接上代码:
public class UiSlashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.ui_slash);
}
@Override
protected void onStart() {
super.onStart();
new Handler().postDelayed(new Thread() {
@Override
public void run() {
startActivity(new Intent(UiSlashActivity.this,UiStartActivity.class));
finish();
}
}, 3000);
}
}
我这里展示的是三秒,可根据实际需求更改,这里注意的是要全屏展示,至于布局代码就不贴了,我的布局只是一个imageview。
二,然后就是登陆注册页面,几乎没有应用是没有登陆注册的吧?
在slashactivity和login,register之间还有一个选择注册还是登陆的startactivity,这个startactivity只有两个按钮,登陆,或者注册,代码很简单,就不贴了,便于理解,上图吧
我看过很多应用的这个页面都是登陆注册按钮不同颜色的,其中注册按钮比较多的是白色,但是还是按自己需求,更改颜色。
然后就是登陆注册页面啦,这两个页面都是startactivity的子页面,可以在主配置文件配置,代码如下:
<activity
android:name="com.example.ui.UiLoginActivity"
android:label="@string/login"
android:parentActivityName="com.example.ui.UiStartActivity">
</activity>
<activity
android:name="com.example.ui.UiRegisterActivity"
android:parentActivityName="com.example.ui.UiStartActivity"
android:label="@string/register"
>
</activity>
这样做的效果是登陆注册页面都有一个返回按钮在actionbar上面。登陆注册页面代码每个应用差别略大,这里不说,我自己写的就只有一个editext和两个按钮。登陆进去了,就是主页面了。下面介绍主页面。
三.主页面framents,大部分应用有,也加上吧
我这里开始没有按上面总结的来写了,因为感觉从自己登陆进去写这个角度会比较顺。从总体到详细嘛。
主页面比较复杂,一个activity,好几个frament。先说底下的导航栏,可以用button,也可以自己重写view,这里选择重写view,同时为了实现横拖,也可以转换frament还要有个viewpaper,我这里以三个frament为例。
public class UiMyFramentActivity extends FragmentActivity implements EventListener,OnPageChangeListener,OnClickListener{
private ViewPager mViewPager;
//下面三个frament
private ContactFragment contactFragment;
private MyInformationFragment myInformationFragment;
private RecentFragment recentFragment;
private Fragment[] fragments;
private FragmentPagerAdapter mAdapter;
private int index;
private int currentTabIndex;//当前是哪个frament
private List<BottomTabView> views = new ArrayList<BottomTabView>();//存放底部导航栏的view
BottomTabView one = null;
BottomTabView two = null;
BottomTabView three = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frament_footer);
initView();
}
private void initView(){
mViewPager = (ViewPager) findViewById(R.id.id_viewpager);
initTab();
mAdapter = new FragmentPagerAdapter(getSupportFragmentManager())
{
@Override
public int getCount()
{
return fragments.length;
}
@Override
public Fragment getItem(int arg0)
{
return fragments[arg0];
}
};
mViewPager.setAdapter(mAdapter);
// mViewPager.setPageTransformer(true, new MyTransformer());
mViewPager.setOnPageChangeListener(this);
one = (BottomTabView) findViewById(R.id.id_indicator_one);
two = (BottomTabView) findViewById(R.id.id_indicator_two);
three = (BottomTabView) findViewById(R.id.id_indicator_three);
views.add(one);
views.add(two);
views.add(three);
one.setOnClickListener(this);
two.setOnClickListener(this);
three.setOnClickListener(this);
one.setIconAlpha(1.0f);
}
private void initTab(){
recentFragment = new RecentFragment();
contactFragment = new ContactFragment();
myInformationFragment = new MyInformationFragment();
fragments = new Fragment[] {recentFragment, contactFragment ,myInformationFragment };
// getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, recentFragment).
// add(R.id.fragment_container, contactFragment).add(R.id.fragment_container, myInformationFragment).hide(contactFragment).show(recentFragment).commit();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
private static long firstTime;
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
if (firstTime + 2000 > System.currentTimeMillis()) {
super.onBackPressed();
} else {
Toast.makeText(UiMyFramentActivity.this,"one more click to quit",Toast.LENGTH_LONG).show();
}
firstTime = System.currentTimeMillis();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
/**
* 此方法是在状态改变的时候调用,其中arg0这个参数有三种状态(0,1,2)。
* arg0 ==1的时辰默示正在滑动,arg0==2的时辰默示滑动完毕了,arg0==0的时辰默示什么都没做。
*/
@Override
public void onPageScrollStateChanged(int arg0) {
if (arg0>0){
ContactFragment temp = (ContactFragment)fragments[1];
// temp.resetSideBar();
}
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
if (positionOffset > 0)
{
BottomTabView left = views.get(position);
BottomTabView right = views.get(position + 1);
left.setIconAlpha(1 - positionOffset);
right.setIconAlpha(positionOffset);
}
}
@Override
public void onPageSelected(int arg0) {
Log.i("frament", "create "+arg0);
fragments[arg0].onResume();
if(arg0==1){
one.setDrawFlag(false);
}
}
@Override
public void onClick(View v) {
resetOtherTabs();
switch (v.getId())
{
case R.id.id_indicator_one:
views.get(0).setIconAlpha(1.0f);
//views.get(0).setDrawFlag(!views.get(0).getDrawFlag());
mViewPager.setCurrentItem(0, false);
break;
case R.id.id_indicator_two:
views.get(1).setIconAlpha(1.0f);
mViewPager.setCurrentItem(1, false);
break;
case R.id.id_indicator_three:
views.get(2).setIconAlpha(1.0f);
mViewPager.setCurrentItem(2, false);
break;
}
}
/**
* 重置其他的Tab
*/
private void resetOtherTabs()
{
for (int i = 0; i < views.size(); i++)
{
views.get(i).setIconAlpha(0);
}
}
}
这样就可以实现点击底部导航栏,或者横拖实现framents的切换了,
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
if (firstTime + 2000 > System.currentTimeMillis()) {
super.onBackPressed();
} else {
Toast.makeText(UiMyFramentActivity.this,"one more click to quit",Toast.LENGTH_LONG).show();
}
firstTime = System.currentTimeMillis();
}
上面的函数值得注意,很多应用有个防止由于用户错误操作导致应用退出的方案,就是一定时间内点击返回键两次才退出应用,上面这个函数就是实现这个功能的,两秒内,点击返回键两次将退出应用!至于frament这里就不说了,每个应用差别太大,这里只写大概相同的地方。
四,自定义的actionbar
actionbar也是千变万化的,比较常见的就是中间一个标题,左右两个各一个图标,或者右边有个隐藏多个选项的按钮,这里就说说第一种
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/ActionBar"
android:baselineAligned="false"
android:focusable="true" >
<LinearLayout
android:id="@+id/header_layout_leftview_container"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
</LinearLayout>
<LinearLayout
android:id="@+id/header_layout_middleview_container"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:id="@+id/header_htv_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="@+id/header_layout_rightview_container"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:gravity="center_vertical|right"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
这是中间的标题。使用即可,主要是变化太多。根据需求可以更改。
五,杂七杂八的工具类
加密,压缩,处理字符串等。
public class AppUtil {
/* md5 加密 */
static public String md5 (String str) {
MessageDigest algorithm = null;
try {
algorithm = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (algorithm != null) {
algorithm.reset();
algorithm.update(str.getBytes());
byte[] bytes = algorithm.digest();
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
hexString.append(Integer.toHexString(0xFF & b));
}
return hexString.toString();
}
return "";
}
/* 首字母大写 */
static public String ucfirst (String str) {
if (str != null && str != "") {
str = str.substring(0,1).toUpperCase()+str.substring(1);
}
return str;
}
/* 为 EntityUtils.toString() 添加 gzip 解压功能 */
public static String gzipToString(final HttpEntity entity, final String defaultCharset) throws IOException, ParseException {
if (entity == null) {
throw new IllegalArgumentException("HTTP entity may not be null");
}
InputStream instream = entity.getContent();
if (instream == null) {
return "";
}
// gzip logic start
if (entity.getContentEncoding().getValue().contains("gzip")) {
instream = new GZIPInputStream(instream);
}
// gzip logic end
if (entity.getContentLength() > Integer.MAX_VALUE) {
throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
}
int i = (int)entity.getContentLength();
if (i < 0) {
i = 4096;
}
String charset = EntityUtils.getContentCharSet(entity);
if (charset == null) {
charset = defaultCharset;
}
if (charset == null) {
charset = HTTP.DEFAULT_CONTENT_CHARSET;
}
Reader reader = new InputStreamReader(instream, charset);
CharArrayBuffer buffer = new CharArrayBuffer(i);
try {
char[] tmp = new char[1024];
int l;
while((l = reader.read(tmp)) != -1) {
buffer.append(tmp, 0, l);
}
} finally {
reader.close();
}
return buffer.toString();
}
/* 为 EntityUtils.toString() 添加 gzip 解压功能 */
public static String gzipToString(final HttpEntity entity)
throws IOException, ParseException {
return gzipToString(entity, null);
}
public static SharedPreferences getSharedPreferences (Context ctx) {
return ctx.getSharedPreferences("com.app.demos.sp.global", Context.MODE_PRIVATE);
}
public static SharedPreferences getSharedPreferences (Service service) {
return service.getSharedPreferences("com.app.demos.sp.global", Context.MODE_PRIVATE);
}
/
// 业务逻辑
/* 判断int是否为空 */
static public boolean isEmptyInt (int v) {
Integer t = new Integer(v);
return t == null ? true : false;
}
/* 获取毫秒数 */
public static long getTimeMillis () {
return System.currentTimeMillis();
}
/* 获取耗费内存 */
public static long getUsedMemory () {
long total = Runtime.getRuntime().totalMemory();
long free = Runtime.getRuntime().freeMemory();
return total - free;
}
}
六,网络连接,json处理
网络连接,我使用了android-async-http框架,使用别人的框架会比较安全,因为别人做的时候考虑到了网络链接上很多安全的问题,而这一块的知识我没太深入了解,所以还是用别人的好,处理json就一个工具类就可以了,也是根据需求自己改了,因为有的人喜欢把收到的json信息 封装到一个类里面,有的时候又不需要。
七,总结
写个博客总结可以说是温故而知新啊,以前写的东西,现在都忘得差不多,重新看以后发现有代码上面还有很多不足,还需要对这些代码进行优化,继续努力!
代码下载:http://download.youkuaiyun.com/detail/u013013970/8930227