当前位置: 首页 > news >正文

湖北建设厅网站怎么打不开哪个微信公众号有a

湖北建设厅网站怎么打不开,哪个微信公众号有a ,新闻发稿时间,班级优化大师使用心得Android的布局方式有两种#xff0c;一种是通过xml布局#xff0c;一种是通过java代码布局#xff0c;两种布局方式各有各的好处#xff0c;当然也可以相互混合使用。很多人都习惯用xml布局#xff0c;那xml布局是如何转换成view的呢#xff1f;本文从源码的角度来简单分…Android的布局方式有两种一种是通过xml布局一种是通过java代码布局两种布局方式各有各的好处当然也可以相互混合使用。很多人都习惯用xml布局那xml布局是如何转换成view的呢本文从源码的角度来简单分析下整个过程。首先创建一个新的项目默认生成一个activity其中xml布局很简单就一个RelativeLayout套了一个ImageView代码及效果如下public class MainActivity extends Activity {Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}}界面1其中关键之处在于调用了父类Activity的setContentView方法/*** Set the activity content from a layout resource. The resource will be* inflated, adding all top-level views to the activity.** param layoutResID Resource ID to be inflated.*/public void setContentView(int layoutResID) {getWindow().setContentView(layoutResID);}getWindow返回的是PhoneWindow实例那我们直接来看PhoneWindow中的setContentView方法Overridepublic void setContentView(int layoutResID) {if (mContentParent null) {installDecor();} else {mContentParent.removeAllViews();}mLayoutInflater.inflate(layoutResID, mContentParent);final Callback cb getCallback();if (cb ! null) {cb.onContentChanged();}}我们知道每个activity实际都对应一个PhoneWindow拥有一个顶层的DecorViewDecorView继承自FrameLayout作为根View其中包含了一个标题区域和内容区域这里的mContentParent就是其内容区域。关于PhoneWindow和DecorView的具体内容读者可自行查阅。这段代码的意思很简单如果DecorView的内容区域为null就先初始化否则就先把内容区域的子View全部移除最后再引入layout布局所以关键在于mLayoutInflater.inflate(layoutResID, mContentParent); 代码继续往下看public View inflate(int resource, ViewGroup root) {return inflate(resource, root, root ! null);}public View inflate(int resource, ViewGroup root, boolean attachToRoot) {if (DEBUG) System.out.println(INFLATING from resource: resource);XmlResourceParser parser getContext().getResources().getLayout(resource);try {return inflate(parser, root, attachToRoot);} finally {parser.close();}}这里首先根据layout布局文件的Id生成xml资源解析器然后再调用inflate(parser, root, attachToRoot)生成具体的view。XmlResourceParser是继承自XmlPullParser和AttributeSet的接口这里的parser其实是XmlBlock的内部类Parser的实例。public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {synchronized (mConstructorArgs) {final AttributeSet attrs Xml.asAttributeSet(parser);Context lastContext (Context)mConstructorArgs[0];mConstructorArgs[0] mContext;View result root;try {// Look for the root node.int type;while ((type parser.next()) ! XmlPullParser.START_TAG type ! XmlPullParser.END_DOCUMENT) {// Empty}if (type ! XmlPullParser.START_TAG) {throw new InflateException(parser.getPositionDescription() : No start tag found!);}final String name parser.getName();if (DEBUG) {System.out.println(**************************);System.out.println(Creating root view: name);System.out.println(**************************);}if (TAG_MERGE.equals(name)) {if (root null || !attachToRoot) {throw new InflateException( can be used only with a valid ViewGroup root and attachToRoottrue);}rInflate(parser, root, attrs);} else {// Temp is the root view that was found in the xmlView temp createViewFromTag(name, attrs);ViewGroup.LayoutParams params null;if (root ! null) {if (DEBUG) {System.out.println(Creating params from root: root);}// Create layout params that match root, if suppliedparams root.generateLayoutParams(attrs);if (!attachToRoot) {// Set the layout params for temp if we are not// attaching. (If we are, we use addView, below)temp.setLayoutParams(params);}}if (DEBUG) {System.out.println(----- start inflating children);}// Inflate all children under temprInflate(parser, temp, attrs);if (DEBUG) {System.out.println(----- done inflating children);}// We are supposed to attach all the views we found (int temp)// to root. Do that now.if (root ! null attachToRoot) {root.addView(temp, params);}// Decide whether to return the root that was passed in or the// top view found in xml.if (root null || !attachToRoot) {result temp;}}} catch (XmlPullParserException e) {InflateException ex new InflateException(e.getMessage());ex.initCause(e);throw ex;} catch (IOException e) {InflateException ex new InflateException(parser.getPositionDescription() : e.getMessage());ex.initCause(e);throw ex;} finally {// Dont retain static reference on context.mConstructorArgs[0] lastContext;mConstructorArgs[1] null;}return result;}}第21行获取xml根节点名final String name parser.getName();第39行根据节点名创建临时View(temp)这个临时view(temp)也是xml布局的根viewView temp createViewFromTag(name, attrs);第61行在临时view(temp)的节点下创建所有子View显然这个方法里是通过遍历xml所有子view节点调用createViewFromTag方法生成子view并加载到根view中rInflate(parser, temp, attrs);第68到76行则是判断如果inflate方法有父view则把临时view(temp)加载到父view中再返回如果没有则直接返回临时view(temp)我们这里调用inflate方法的时候显然有父view即mContentParent也就是最顶层view DecorView的内容区域。这里最关键有两个方法一个是createViewFromTag另一个是rInflate现在来逐一分析createViewFromTag实际最终调用的是createView方法public final View createView(String name, String prefix, AttributeSet attrs)throws ClassNotFoundException, InflateException {Constructor constructor sConstructorMap.get(name);Class clazz null;try {if (constructor null) {// Class not found in the cache, see if its real, and try to add itclazz mContext.getClassLoader().loadClass(prefix ! null ? (prefix name) : name);if (mFilter ! null clazz ! null) {boolean allowed mFilter.onLoadClass(clazz);if (!allowed) {failNotAllowed(name, prefix, attrs);}}constructor clazz.getConstructor(mConstructorSignature);sConstructorMap.put(name, constructor);} else {// If we have a filter, apply it to cached constructorif (mFilter ! null) {// Have we seen this name before?Boolean allowedState mFilterMap.get(name);if (allowedState null) {// New class -- remember whether it is allowedclazz mContext.getClassLoader().loadClass(prefix ! null ? (prefix name) : name);boolean allowed clazz ! null mFilter.onLoadClass(clazz);mFilterMap.put(name, allowed);if (!allowed) {failNotAllowed(name, prefix, attrs);}} else if (allowedState.equals(Boolean.FALSE)) {failNotAllowed(name, prefix, attrs);}}}Object[] args mConstructorArgs;args[1] attrs;return (View) constructor.newInstance(args);} catch (NoSuchMethodException e) {InflateException ie new InflateException(attrs.getPositionDescription() : Error inflating class (prefix ! null ? (prefix name) : name));ie.initCause(e);throw ie;} catch (ClassNotFoundException e) {// If loadClass fails, we should propagate the exception.throw e;} catch (Exception e) {InflateException ie new InflateException(attrs.getPositionDescription() : Error inflating class (clazz null ? : clazz.getName()));ie.initCause(e);throw ie;}}其实这个方法很简单就是通过xml节点名通过反射获取view的实例再返回其中先去map中查询构造函数是否存在如果存在则直接根据构造函数创建实例这样做的好处是不用每次都通过class去获取构造函数再创建实例我们看第18行通过类实例获取构造函数constructor clazz.getConstructor(mConstructorSignature);其中mConstructorSignature定义如下private static final Class[] mConstructorSignature new Class[] {Context.class, AttributeSet.class};很显然这里用的是带有Context和AttributeSet两个参数的构造函数这也就是为什么自定义view一定要重载这个构造函数的原因。最后就是rInflate方法private void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs)throws XmlPullParserException, IOException {final int depth parser.getDepth();int type;while (((type parser.next()) ! XmlPullParser.END_TAG ||parser.getDepth() depth) type ! XmlPullParser.END_DOCUMENT) {if (type ! XmlPullParser.START_TAG) {continue;}final String name parser.getName();if (TAG_REQUEST_FOCUS.equals(name)) {parseRequestFocus(parser, parent);} else if (TAG_INCLUDE.equals(name)) {if (parser.getDepth() 0) {throw new InflateException( cannot be the root element);}parseInclude(parser, parent, attrs);} else if (TAG_MERGE.equals(name)) {throw new InflateException( must be the root element);} else {final View view createViewFromTag(name, attrs);final ViewGroup viewGroup (ViewGroup) parent;final ViewGroup.LayoutParams params viewGroup.generateLayoutParams(attrs);rInflate(parser, view, attrs);viewGroup.addView(view, params);}}parent.onFinishInflate();}实这个方法也很简单就是通过parser解析xml节点再生成对应View的过程。XML转换成View的过程就是这样了如有错误之处还望指正回到本文开头其实我们还可以这样写Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);View content LayoutInflater.from(this).inflate(R.layout.activity_main, null);setContentView(content);}界面2大家发现问题没相较于本文开头的写法后面的灰色布局变成全屏了我们来看看xml代码xmlns:toolshttp://schemas.android.com/toolsandroid:layout_width300dipandroid:layout_height300dipandroid:background#888888tools:context.MainActivity android:layout_width200dipandroid:layout_height200dipandroid:background#238712android:contentDescriptionnull /我明明设置了RelativeLayout的宽度和高度分别为300dip但为什么全屏了这是因为layout_width和layout_height是相对于父布局而言的我们这里inflate的时候设置的父布局为null所以这个属性设置也就无效了指定一个父布局就可以了例如Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);RelativeLayout rootView new RelativeLayout(this);View content LayoutInflater.from(this).inflate(R.layout.activity_main, rootView);setContentView(content);}现在界面显示效果就和“界面1”相同了。
http://www.zqtcl.cn/news/332745/

相关文章:

  • 网站漏洞解决办法投资
  • wordpress网站如何网页设计实训总结3000字大学篇
  • 用ps怎么做网站导航条wordpress 开启缩略图
  • 网上销售型的企业网站为什么要域名备案
  • 唐山网站建设方案优化国内酷炫网站
  • 国外网站备案吗网站做一样没有侵权吧
  • 谷歌怎么建网站ps中怎样做网站轮播图片
  • 汕头有没有做网站廊坊宣传片制作公司
  • 百度快速收录网站有些人做网站不用钱的 对吗
  • 如何规划一个网站网站建设预付费入什么科目
  • 北京做网站的好公司有哪些网站建设杭州缘择低价
  • 建设网站团队张掖响应式建站平台
  • 中国建设之乡是哪里网站优化连云港哪家强?
  • 网站建设报价是多少30号长沙封城最新消息
  • 常州专业网站建设费用电商推广技巧
  • 辽源市网站建设南通营销网站开发
  • 新站优化案例去韩国用什么地图导航
  • 宁波网站制作与推广WordPress怎么文章分类
  • mvc 做网站国内的搜索引擎有哪些
  • 设计视频网站腾讯云服务器网站域名备案
  • 网站建设费算费用还是固定资产镇赉县做网站的
  • 山西 旅游 英文 网站建设wordpress 设置登陆界面
  • 电商网站系统建设考试深圳网站建设培训哪家好
  • 工作室 网站项目策划书八篇案例
  • ui做网站流程建设统计网站进不去
  • 沧州网站建设优化公司网站改版
  • 网站开发工程师好不好注册科技公司流程和费用
  • wordpress站点费用vs手表官网
  • 网站买卖需要注意什么景安怎么把网站做别名
  • 网站建设网站建怎么做一个门户网站