由于初的layoutInflater.inflate(R.layout.main, null,false)函数,传入的是R.layout.main资源id,而对于我们的项目,布局文件是在线更新的,是间接存储在sd卡中,所以这种解析方式不行了,所幸LayoutInflater的api方法还提供了inflate(XmlPullParser parser, ViewGroup root,boolean attachToRoot)解析,根据文件保存路径生成需要的xmlPullParser:
  public XmlPullParser getXmlPullParser(String resource) {
  XmlPullParser parser = Xml.newPullParser();
  try {
  // InputStream is=mContext.getAssets().open("transfer_main.xml");
  FileInputStream is = new FileInputStream(resource);
  parser.setInput(is, "utf-8");
  } catch (Exception e) {
  e.printStackTrace();
  }
  return parser;
  }
  后面的第二步等其实都是一样的流程(我会在后面贴出实现demo)。但是有一点需要特别注意,也是必须实现的一点:
  因为所下载的布局文件得到的解析流,跟程序里res/layout/xxx.xml有一个非常大的不同,资源id!!程序中的布局文件,里面所注册的id以及text,或者drawble都是可以真实在R目录下找到的,而下载的布局文件是没有这个福利的,它是我们外面生成的,并没有经过apk编译过程。所以为了能得到下载文件里的布局各个id,我们需要自己实现对View的属性解析。
  protected View onCreateView(String name, AttributeSet attrs)
  throws ClassNotFoundException {
  // return createView(name, "android.view.", attrs);
  return createView(name, "com.xxx.xxxx.viewanalysis.view.VA", attrs);  //比如com.xx.view.VATextView 项目中自定义view 继承自TextView
  }
  布局中的控件代码编写,可以是TextView等原生的,也可以是自定义过的,因为TextView经过加前缀,再通过后面的反射方法,也会跑到相应的自定义方法,返回一个自定义View对象。不过因为终都是要跑自定义view,所以要求我们需要事先定义好会用到的,目前我定义好了9种,比如Button,GridView,RelativeLayout等。如果没有定义的view直接用在文件中,会导致编译出错(ClassNotFoundException)。
  VAButton类实现:
  public class VAButton extends android.widget.Button {
  public VAButton(Context context, AttributeSet attrs) {
  super(context);
  setAttributeSet(attrs);
  }
  @SuppressWarnings("deprecation")
  public void setAttributeSet(AttributeSet attrs) {
  HashMap<String, ParamValue> map = YDResource.getInstance().getViewMap();
  int count = attrs.getAttributeCount();
  for (int i = 0; i < count; i++) {
  ParamValue key = map.get(attrs.getAttributeName(i));
  if (key == null) {
  continue;
  }
  switch (key) {
  case id:
  this.setTag(attrs.getAttributeValue(i));
  break;
  case text:
  String value = YDResource.getInstance().getString(
  attrs.getAttributeValue(i));
  this.setText(value);
  break;
  //case... 
  default:
  break;
  }
  }
  }
  Ps: view id通过设置标志在外面可以获取到(具体可以看demo)
  属性方面的解析,我不多说了,网上的资料很多,有兴趣的可以去了解下。
  demo效果图:


  项目中的效果图:

  接下来看看demo中的代码结构:

  这里的代码主体在于YDLayoutInflater与ParamValue的实现,以及9种自定义view。
  YDLayoutInflater主要是仿照LayoutInflater实现的,做了一些适应布局文件的修改处理,上面已经说过了。
  具体的代码下载地址
  动态解析布局的思路讲完了,应用到项目中,效果也不错,虽然有一些限制规范,但是对于总体的功能设计是无关大雅的。关于主题呈现动态更新,如果有大神有更好的方式,请私信我哦!