最后,如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。
小编在这里祝小伙伴们在未来的日子里都可以 升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰!!
不论遇到什么困难,都不应该成为我们放弃的理由!
很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习
如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

看到这个界面,大部分属性都应该能才出来了,我们重点看parameter,界面上每一个紫色框出来的部分都对应一个parameter,部分属性介绍:
-
id :唯一标识,最终通过该属性的值,获取用户输入值(文本框内容,是否选中)
-
name:界面上的类似label的提示语
-
type : 输入值类型
-
constraints:填写值的约束
-
suggest:建议值,比如填写ActivityName的时候,会给出一个布局文件的建议值。
-
default:默认值
-
help:底部显示的提升语
这个部分对应界面还是非常好理解的,大家可以简单的修改一些字符串,或者添加一个<parameter>,重启AS,看看效果。
template.xml的最下面的部分引入了globals.xml.ftl和recipe.xml.ftl。
这两个我们会详细介绍。
2.2 globals.xml.ftl
<?xml version="1.0"?><#include “…/common/common_globals.xml.ftl” />
通过名称可以猜到它是用于定义一些全局的变量,可以看到其内部有<global>标签,分别定义id,type,默认值。
同理,我们可以通过id的值访问到该值,例如:
${hasNoActionBar}的值为false。
2.3 recipe.xml.ftl
<copy from=“root/res/drawable-hdpi”
to=“${escapeXmlAttribute(resOut)}/drawable-hdpi” />
<merge from=“root/${resIn}/values/strings.xml.ftl”
to=“${escapeXmlAttribute(resOut)}/values/strings.xml” />
<instantiate from=“root/src/app_package/SimpleActivity.java.ftl”
to=“ e s c a p e X m l A t t r i b u t e ( s r c O u t ) / {escapeXmlAttribute(srcOut)}/ escapeXmlAttribute(srcOut)/{activityClass}.java” />
为了介绍,我将该xml中比较重要的几个标签都列出来了:
-
copy :从root中copy文件到我们的目标目录,比如我们的模板Activity需要使用一些图标,那么可能就需要使用copy标签将这些图标拷贝到我们的项目对应文件夹。
-
merge : 合并的意思,比如将我们使用到的strings.xml合并到我们的项目的stirngs.xml中
-
instantiate : 和copy类似,但是可以看到上例试将ftl->java文件的,也就是说中间会通过一个步骤,将ftl中的变量都换成对应的值,那么完整的流程是
ftl->freemarker process -> java。 -
open:在代码生成后,打开指定的文件,比如我们新建一个Activity后,默认就会将该Activity打开。
在介绍instantiate时,涉及到了freemarker,不可避免的需要对它进行简单的介绍。
目前我们已经基本了解了一个模板其内部的文件结构了,以及每个文件大致包含的东西,我们简单做个总结:
-
template 中parameter标签,主要用于提供参数
-
global.xml.ftl 主要用于提供参数
-
recipe.xml.ftl 主要用于生成我们实际需要的代码,资源文件等;例如,利用参数+MainActivity.java.ftl -> MainActivity.java;其实就是利用参数将ftl中的变量进行替换。
那么整体的关系类似下图:

图片来源:http://www.slideshare.net/murphonic/custom-android-code-templates-15537501
3、简单的freemarker语法
上面我们已经基本了解模板生成的大致的流程以及涉及到的文件,大致了解了我们生成的源码或者xml文件,需要经过:
ftl->freemarker process->java/xml
这样的流程,那么我们必须对freemarker有个简单的了解。
- 非常简单的例子
其实非常简单:
比如我们有个变量user=zhy;
有个ftl文件内容:helloL${user}
最后经过freemarker的输出结果即为 hello:zhy
- if语法
<#if generateLayout>
//生成layout文件
</#if>
看一眼就知道大概的意思了~有一定的编程经验,即使不知道这个叫freemarker,对于这些简单的语法还是能看懂的。
我们最后以Empty Activity模板的中的SimpleActivity为例:
root/src/app_package/SimpleActivity.java.ftl
package ${packageName};
import ${superClassFqcn};
import android.os.Bundle;
public class ${activityClass} extends ${superClass} {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
<#if generateLayout>
setContentView(R.layout.${layoutName});
</#if>
}
}
可以看到其内部包含很多变量,这些变量的值一般来源于用户输入和global.xml.ftl中预定义的值,经过recipe.xml.ftl中instantiate标签的处理,将变量换成实际的值,即可在我们的项目的指定位置,得到我们期望的Activity。
流程大致可用下图说明:

图片来源:http://www.slideshare.net/murphonic/custom-android-code-templates-15537501
看到这,最起码理解了,当我们选择创建不同的Activity类型,最终得到的不同的效果其中的原理原来在这。
4、具体的模板实例
了解了基本的理论之后,下面我们可以通过一个实例来将上面的知识点整合。
我们编写一个Activity模板叫做:ViewPagerWithTabActivity,用于创建一个携带TabLayout的ViewPager,效果如下:

当我们点击New->Activity->ViewPagerWithTabActivity 就可能完成上面的Activity的创建,而避免了编写布局文件,引入design库,以及一些简单的编码。
是不是感觉还是不错的,大家可以针对自己的需求,按照规范的格式随意定制模板。
建议大家copy一个现有的模板,再其基础上修改即可,比如本例是在Empty Activity基础之上修改的。
下面我们看上例的具体的实现。
4.1 template.xml的编写
通过上面的学习我们知道template.xml中可以定义我们创建面板的控件布局等,本例我们创建Activity的界面如下:

对应的template.xml如下:
<?xml version="1.0"?>template_vp_with_tab_activity.png
经过前面的学习应该很好理解,每个parameter对应界面上的一个控件,控件的这个id最终可以得到用户输入值,后面会用于渲染ftl文件。
4.2 用到的类
本例中最终需要生成Fragment和Activity,也就是说对应会有两个ftl文件分别用于最终生成这两个类。
root/src/app_package/MainActivity.java.ftl
package ${packageName};
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import ${packageName}.fragment.SimpleFragment;
public class ${activityClass} extends AppCompatActivity
{
private TabLayout mTabLayout;
private ViewPager mViewPager;
private int mTabCount = ${tabCount};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.${activityLayoutName});
mTabLayout = (TabLayout) findViewById(R.id.id_tablayout);
mViewPager = (ViewPager) findViewById(R.id.id_viewpager);
mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager())
{
@Override
public Fragment getItem(int position)
{
return new SimpleFragment();
}
@Override
public int getCount()
{
return mTabCount;
}
@Override
public CharSequence getPageTitle(int position)
{
return “Tab:” + position;
}
});
mTabLayout.setupWithViewPager(mViewPager);
}
}
注意不是.java文件而是.ftl文件,可以看到上面的代码基础上和Java代码没什么区别,实际上就是Java代码,把可变的部分都换成了${变量名}的方式而已。
例如:类名是用户填写的,我们就使用${activityClass}替代,其他同理。
root/src/app_package/SimpleFragment.java.ftl
package ${packageName}.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
- Created by zhy on 16/6/6.
*/
public class SimpleFragment extends Fragment
{
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
TextView tv = new TextView(getActivity());
tv.setGravity(Gravity.CENTER);
tv.setTextSize(40);
tv.setText(“just test”);
return tv ;
}
}
这个类更简单,除了package是动态的,其他都写好了,主要用于作为ViewPager的Fragment Item.
4.3 用到的布局文件
root/res/layout/activity_main.xml.ftl
<LinearLayout
xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“vertical”
tools:context=" p a c k a g e N a m e . {packageName}. packageName.{activityClass}">
最后
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
Android 基础知识点
Java 基础知识点
Android 源码相关分析
常见的一些原理性问题

希望大家在今年一切顺利,进到自己想进的公司,共勉!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
{activityClass}">
最后
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
Android 基础知识点
Java 基础知识点
Android 源码相关分析
常见的一些原理性问题
[外链图片转存中…(img-ZDx9bbmS-1715647344953)]
希望大家在今年一切顺利,进到自己想进的公司,共勉!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

被折叠的 条评论
为什么被折叠?



