原创文章,转载请注明
实现目标
我们知道,android通过R类对资源进行管理,每个资源对应一个整型数字。那么如果我们能够通过注释指定该整型数字就能获得资源对象就好了。比如如下所示:
@Resource(value=R.id.common_time)
private ListView listView;
我们知道,每个界面,不论activity或者fragment都需要对应一个layout资源文件,那么这个关系是否也能通过注释指定呢?,比如如下所示:
@Layout(value=R.layout.activity_main)
public class MainActivity extends BaseActivity
实现方法
如何实现我们的目标呢?
这两个目标的实现相对前面两篇文章中的目标还是比较简单的,无非是通过反射去获取是否有该注释,如果有的话通过相应方法返回对象即可。
1、BaseFragment类
需要进行资源依赖注入的fragment必须继承该类
对于@Layout的实现
a、在该类的public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)方法中实现
b、判断自己是否有@Layout注释,如果有的话获得该注释的value,这样就获得资源id了
c、调用inflater.inflate(资源id, container, false) 就将layout资源文件和fragment绑定了
对于@Resource的实现
a、在该类的 View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)方法中实现
b、通过反射自己的成员变量,判断成员变量是否有@Resource注释,如果有的话获得该注释的value,这样就获得资源id了
c、调用View v=layout.findViewById(资源id)获得资源对象,注意layout为@Layout实现中调用inflate方法返回的对象。最后把该view对象赋值给该成员变量即可
2、BaseActivity类
该类和上面的类大同小异,只不过是在void onCreate(Bundle savedInstanceState)方法实现罢了
看一下代码吧
BaseFragment类
其中有控制跳转的代码,LayoutFactory类,AALayout类,可以无视掉
public class BaseFragment extends BackHandledFragment {
private Map<String,Object> fieldMap;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
Context context = getActivity();
Bundle bundle = this.getArguments();
//通过position获得指定的界面
position = (String) bundle.get("position");
View layout = null;
try {
Class<?> cls=Class.forName(position);
AALayout aalayout;
if(fieldMap!=null){
aalayout = LayoutFactory.create(cls,fieldMap);
}
else{
aalayout = LayoutFactory.create(cls);
}
//获取布局资源,依赖注入资源
Class<?> acls=aalayout.getClass();
//获取layout资源
if(acls.isAnnotationPresent(Layout.class)){
Layout layoutAnno=acls.getAnnotation(Layout.class);
int layoutXmlId=layoutAnno.value();
layout = inflater.inflate(layoutXmlId, container, false);
Field[] fields=cls.getDeclaredFields();
for(Field field : fields){
Class<?> fcls=field.getType();
if(View.class.isAssignableFrom(fcls)){
//获取Resource资源
if(field.isAnnotationPresent(Resource.class) && !Modifier.isStatic(field.getModifiers())){
field.setAccessible(true);
Resource resource=field.getAnnotation(Resource.class);
int rid=resource.value();
View v=layout.findViewById(rid);
field.set(aalayout, v);
}
}
}
}
//相当于页面跳转
aalayout.getLayout(inflater,container,savedInstanceState,context,bundle);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return layout;
}
@Override
public boolean onBackPressed() {
return false;
}
public void setFieldMap(Map<String, Object> fieldMap) {
this.fieldMap = fieldMap;
}
}
BaseActivity类
该类中有控制跳转的代码,@Root注释,BackHandledInterface接口,可以无视掉
public class BaseActivity extends FragmentActivity implements BackHandledInterface{
protected BackHandledFragment mBackHandedFragment;
public static DBHelper helper;
protected boolean isRoot=true;
private int xmlId;
private int layoutId;
@Override
protected void onCreate(Bundle savedInstanceState) {
//框架入口,进行类容器,实例容器,数据库映射工具初始化
LoadHelper.init();
Class<?> cls=getClass();
String childClassName=cls.getSimpleName();
if(childClassName!=null)
//解析root注释,获得入口资源id
try {
if(cls.isAnnotationPresent(Root.class)){
Root root=cls.getAnnotation(Root.class);
xmlId=root.xml_id();
}
//获得布局资源
if(cls.isAnnotationPresent(Layout.class)){
Layout layout=cls.getAnnotation(Layout.class);
layoutId=layout.value();
setContentView(layoutId);
}
//依赖注入资源
Field[] fields=cls.getDeclaredFields();
for(Field field : fields){
Class<?> fcls=field.getType();
if(View.class.isAssignableFrom(fcls)){
if(field.isAnnotationPresent(Resource.class) && !Modifier.isStatic(field.getModifiers())){
field.setAccessible(true);
Resource resource=field.getAnnotation(Resource.class);
int rid=resource.value();
Method m=cls.getMethod("findViewById", int.class);
View v=(View) m.invoke(this, rid);
field.set(this, v);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
super.onCreate(savedInstanceState);
}
@Override
public void onDestroy(){
super.onDestroy();
if(helper!=null){
helper.close();
}
}
@Override
public void setSelectedFragment(BackHandledFragment selectedFragment) {
this.mBackHandedFragment = selectedFragment;
}
@Override
public void setIsRoot(boolean flag) {
this.isRoot=flag;
}
public void setmBackHandedFragment(BackHandledFragment mBackHandedFragment) {
this.mBackHandedFragment = mBackHandedFragment;
}
public void routeFromRoot(String position,Map<String,Object> args){
if(isRoot){
if(getFragmentManager().getBackStackEntryCount() == 1)
isRoot=true;
else
isRoot=false;
route(position,args);
}
}
public void routeFromOthers(String position,Map<String,Object> args){
isRoot=false;
route(position,args);
}
private void route(String position,Map<String,Object> args){
BaseFragment baseFragment = new BaseFragment();
/*
if(this instanceof Activity)
baseFragment.setFieldMap(getExtraField());
*/
mBackHandedFragment=baseFragment;
Bundle bundle = new Bundle();
bundle.putString("position", position);
if(args!=null){
for(Map.Entry<String, Object> argEntry : args.entrySet()){
Object arg=argEntry.getValue();
if(arg instanceof String){
bundle.putString(argEntry.getKey(), (String) arg);
}
else if(arg instanceof Integer){
bundle.putInt(argEntry.getKey(), (Integer) arg);
}
else if(arg instanceof Long){
bundle.putLong(argEntry.getKey(), (Long) arg);
}
else if(arg instanceof Float){
bundle.putFloat(argEntry.getKey(), (Float) arg);
}
else if(arg instanceof Double){
bundle.putDouble(argEntry.getKey(), (Double) arg);
}
else if(arg instanceof Boolean){
bundle.putBoolean(argEntry.getKey(), (Boolean) arg);
}
else if(arg instanceof Serializable){
bundle.putSerializable(argEntry.getKey(), (Serializable) arg);
}
else if(arg instanceof IBinder){
bundle.putBinder(argEntry.getKey(), (IBinder) arg);
}
else if(arg instanceof Bundle){
bundle.putAll((Bundle) arg);
}
}
}
baseFragment.setArguments(bundle);
getFragmentManager().beginTransaction().replace(xmlId,baseFragment)
.addToBackStack(null)
.commit();
}
@Override
public void onBackPressed(){
if(mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()){
if(getFragmentManager().getBackStackEntryCount() == 0){
super.onBackPressed();
}else{
if(getFragmentManager().getBackStackEntryCount() == 1)
isRoot=true;
else
isRoot=false;
getFragmentManager().popBackStack();
}
}
}
@SuppressWarnings("rawtypes")
protected void startService(Class service) {
Intent i = new Intent(this, service);
i.setFlags(32);
//i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(i);
}
}
Resource注释类
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
int value();
}
Layout注释类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Layout {
int value();
}