常规及高级UI编程 | 青训营笔记

103 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第3天

常规UI组件

组件 Java Class Package

文本组件 TextView android.widget.TextView

图片组件 ImageView android.widget.ImageView

按钮组件 Button android.widget.Button

输入框组件 EditText android.widget.EditText

复选框组件 CheckBox android.widget.CheckBox

单选按钮 RadioButton android.widget.RadioButton

f0f74a24-f8ba-4e0e-b3e2-edeedbcd0e6a.png 高级UI组件

组件 Java Class

滑动组件 ScrollView

列表组件 ListView/RecyclerView

下拉刷新组件 PullToRefresh

分页组件 ViewPager

布局组件 LinearLayout/RealtiveLayout/...

常用布局

65e76d54-6901-41a8-8fc9-8974b5bf7a44.png

布局页面如何渲染?

  • 布局加载
  • 注册Manifest
  • 设置布局文件

布局加载-setContentView

setContentView究竟做了什么?

@Override getDelegate0.setContentView(layoutResiD); public void setContentView(@LayoutRes int layoutResID){创建了DecorView,最终 由LayoutInflater来加载了 XML文件private static AppCompatDelegate create(Context contextWindow window, AppCompatCallback callback){ ifBuild VERSION SDK INT>-24){ @Override return new AppCompatDelegateImpIN(context,window, callback); public void setContentView(int resId) { } else if (Build VERSION SDK INT>-23{ensureSubDecorO; return new AppCompatDelegateImplV23(context,window, callback); ViewGroup contentParent=(ViewGroup)mSubDecor } else if (Build VERSION SDK INT>= 14) { findViewById(android.R.id.content); return new AppCompatDelegateImplV14(context,window, callback); contentParent removeAllViewsO: } else if(BuildVERSIONSDKINT>-11{LayoutInfiater.from(wContext).infiate(resid, contentParent); return new AppCompatDelegateImplV11(contextwindow,callback) mOriginalWindowCallback.onContentChangedo; }else { return new AppCompatDelegateImplV9(context,window, callback);

**布局解析-LayoutInflater **

Layoutinflater究竟做了什么?

Layoutinnater解析了XML文件,并根据 public View inflate(@LayoutRes int resource, @Nullable XML文件生成了View实例,并将View实例 ViewGroup rootboolean attachToRoot){ 添加了到了其ViewGroup中 final Resources res=getContextO.getResources: final XmiResourceParser parser =res.getLayout(resource); try { return inflate(parser,root, attachToRoot);}} finally { parser.closeO; void rinflate(XmPullParser parser, View parent,Context context AttributeSet attrs, boolean finishInflate)throws XmiPullParserException, IOException while (((type = parser nextO)!=XmiPullParser END TAG}parser getDepthO>depth) && type !=XmIPullParser END DOCUMENT){//省略/核心代码public View inflate(XmIPullParser parser, @Nullable ViewGroup final ViewGroup viewGroup=(ViewGroup)parent final View view =createViewFromTag(parent, name, context, attrs);11省略 root.boolean attachToRoot){ rInflateChildren(parser, view, attrs, true); final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); //核心代码 rinflate(parser, root, inflaterContext, attrs, false), } viewGroup.addView(view,params);

**布局解析-createView **

XML中的View是如何生成实例的?
switch (name){View createViewFromTag(View parentString name.Context context case "TextView" try { AttributeSet attrs, boolean ignoreThemeAttr{ break view=new AppCompatTextView(context,attrs) case "ImageView": View view; if(mFactory2!=nul) { view=mFactory2.onCreateView(parent namecontextattrs); break view =new AppCompatmageView(context,attrs) } else if (mFactory!= null){ case "Button" } else { view=mFactory onCreateView(namecontextattrs) break, view=new AppCompatButton(context,attrs); view = null case "EditText" view =new AppCompatEditText(context,attrs) break}if (view = null && originalContext != context) {根据XML中View类名来找到相应View,并 view =createViewFromTag(context, name, attrs); 并作为第二个参数传给了View构造器将XVL中的描述属性解析为AttributeSet, if(view !=null) { checkOnClickListener(view, attrs);return view

微信图片_20220831220829.jpg 交互

常用交互事件监听器

回调方法 事件监听器

onClickO View.OnClickListener 当用户轻触项目(在触摸模式下),或者使用导航键或轨迹球聚焦于项目,然后按适用的“Enter”键或按下轨迹球时,系统会调用此方法。

onLongClick0 View.OnLongClickListener 当用户轻触并按住项目(在触摸模式下)时,或者使用导航键或轨迹球聚焦于项目,然后按住适用的“Enter”键或按住轨迹球(持续一秒钟)时,系统会调用此方法。

onFocusChangeO View.OnFocusChangeListener 当用户使用导航键或轨迹球转到或离开项目时,系统会调用此方法。

onKey0 View.OnFocusChangeListener 当用户聚焦于项目并按下或释放设备上的硬件按键时,系统会调用此方法。

onTouchO View.OnTouchListener 当用户执行可视为触摸事件的操作时,包括按下、释放或屏幕上的任何移动手势(在项目边界内),系统会调用此方法。

一些内容小温也没太弄懂,新手小白还需努力,打扰啦!