版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Android 自定义组件(一)在原生组件上避免不了覆写、组合等,以定义自己的组件,也方便以后复用。例如之前工程 里出现了多次的文件浏览器组件。嗯,该怎么总结呢?一、概述自定义组件,大概可以这么分吧。一、 View 或 SurfaceView 上自绘;二、 ViewGroup 布局子 类整合;三、不清楚了 ,好像也没什么好分的 = 。本文的工程,个人觉着主要还是属性资源的使用吧?工程主要例子介绍如下:名称效果属性Loading 动态 . 的效 果组件loading. 的动态效果定义了如下四属性:1) loadImage: load 字图片, reference类型2) pointImage:小
2、点图片, reference 类型3) pointCount :小点数目, integer 类型4) msecRate:毫秒级变化速率, integer 类型Title 背景移位的效果 组件集合 View 布局,形成标题 栏。实现了标题项下的背景移 动的小效果。定义了如下属性:1) titleLayout :标题栏布局2) bgImage:item 背景图片3) bgLeftMargin :背景初始左边距4) animTime :移动动画时间ViewPager 绑定标题 的效果组件ViewPager 绑定标题栏,并实 现了标题项下的背景移动的小 效果。效果特征如下:1 )背景随 ViewPag
3、er 滚动而同步在标题间滚动2)点击标题时, ViewPager程序控制滚动 & 背景同步 属性定义如下:1) tLayout :标题栏布局2) bImage:item 背景图片3) bMargin :背景初始左边距ListView 增加抽屉的 效果组件ListView 增加抽屉的效果组 件。抽屉打开的界面只用了一 个。1) listViewId :列表视图 id , reference类型2) drawerContent:抽屉内容视图 id, reference类型3) drawerClose:抽屉内容的关闭按钮 id ,reference类型自定义能隐藏更多标题的组件集合 View 布局,
4、形成标题 栏。实现超过标题数限制时, 自动显示更多的效果。初始化时,需要进行如下步骤:1)设置显示数限制,默认将为 6。2 )绑定标题内容。为 String ,将直接以 TextView 显示3)绑定更多操作的视图 id。将自己加载,并为其设置点 击事件。4)绑定更多显示的视图。应为已有的 ViewGroup 。将自 动加载超出限制的标题内容( TextView )。更多操作则 将控制其显示或隐藏。另外,提供刷新内容的方法,用于:一、标题栏内容的 重新加载;二,更多显示内容的重新加载。自绘实时动态数据线利用 View 绘制的实时数据显 示组件?写该文档时才挪进来的了,感觉弄得乱乱的。双点缩放好
5、像很不正确啊?应该是两个触摸点没弄对, 获得的是一个手指头触发的两个点,所以一下放大了。(猜测,总之我是不修了 )以下将以 “ ViewPage扩r 展组件 ”为例了,顺便能看下 ViewPager 组件 、步骤带属性资源,整合布局构建自定义组件的步骤 1) attrs.xml定义组件需要用的属性。不用的话,就相当于一个类为一个自定义组件,不和这些东西挂 钩。 “自定义能隐藏更多标题的组件 ”即是这样的,连属性都没定义 =。ViewPager 扩展组件定义的内容:3. format = reference name= tLayout /4. format = reference name= b
6、Image /5. format = integer name = bMargin /6.format 类型,参见: Android 中 attr 自定义属性详解 。2)item.xml只要是 xml 的 resources标签内即可,单独弄出来呢最好。用以下方式定义一个id ,用于View.setId(int id ,主要用于相对布局时,相对于某个id 的 View 什么的。ViewPager 扩展组件定义的内容:1. name= containerLayout type =id /3)创建组件其类中引用属性资源。并看下 ViewPager 的使用说明吧: OnPageChangeListe
7、ner接口方法和 PagerAdapter适配器内方法的注释。1. public class TitleViewPager extends RelativeLayout implements2.OnPageChangeListener, View.OnClickListener 3.4. private Context mContext; / 上下文5. private LayoutInflater mInflater; / 布局加载器6.7. private int titleLayoutId; / 标题栏布局 id8. private int bgImageResId; / item 背景
8、图片资源 id9. private int bgLeftMargin; / 背景初始左边距10.11. private View titleLayout; / 标题栏布局12. private ImageView mBgImage; / item 背景图片13. private ArrayList mItemViews; / 标题项视图集合15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.private ViewPager mViewPager; / V
9、iewPager 组件private ArrayList mPageViews; / 页面视图集合private int prevOffset = - 1; / 前次偏移值,这里用了 int 值像素private int currentIndex; / 当前页面索引private int previousIndex; / 前次页面索引private boolean isTitleClicked; / 标题项点击private OnPageChangeListener mOnPageChangeListener; / 页面变化监听事件/ private final int REFRESH_RAT
10、E = 20; / 刷新速率 20msec/ private Scroller mScroller; / 滚动器/ private static final Interpolator sInterpolator = new Interpolator( / public float getInterpolation(float t / t -= 1.0f;/ return t * t * t + 1.0f;/ / ;public TitleViewPager(Context context, AttributeSet attrs super(context, attrs;mContext = c
11、ontext;mInflater = (LayoutInflater context .getSystemService(Context.LAYOUT_INFLATER_SERVICE;/ 获得 TypedArray 对象TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleViewPager;/ 获取标题栏布局 id ,默认 0 titleLayoutId = typedArray.getResourceId(R.styleable.TitleViewPager_tLayout, 0 ;4
12、7. / 获取 item 背景图片资源 id,默认 048. bgImageResId = typedArray.getResourceId(49. R.styleable.TitleViewPager_bImage, 0;50. / 获取背景初始左边距,默认 051. bgLeftMargin = typedArray.getInt(R.styleable.TitleViewPager_bMargin, 0;52.53. initLayout(; / 初始化标题栏 &ViewPager54.55. mItemViews = new ArrayList (;56. mPageViews = n
13、ew ArrayList (;57. 58.59. / 初始化标题栏 &ViewPager60. private void initLayout( 61. RelativeLayout containerLayout = new RelativeLayout(mContext; / 创建标题栏容器布局62. containerLayout.setId(R.id.containerLayout; / 设置标识符63. LayoutParams containerParams = new LayoutParams(64. LayoutParams.FILL_PARENT, LayoutParams
14、.WRAP_CONTENT; / 宽度WRAP_CONTENT ,高度 WRAP_CONTENT65. containerParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,66. RelativeLayout.TRUE; / 贴于顶部67. containerParams.addRule(RelativeLayout.CENTER_HORIZONTAL,68. RelativeLayout.TRUE; / 水平居中69. addView(containerLayout, containerParams; / 当前布局增加容器布局70. if (0 !
15、= bgImageResId 71. mBgImage = new ImageView(mContext; / 创建 item 背景图片72. mBgImage.setImageResource(bgImageResId; / 设置 item 背景图片73. LayoutParams imageParams = new LayoutParams(74. LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT; / 宽度WRAP_CONTENT ,高度 WRAP_CONTENT75. imageParams.addRule(RelativeLay
16、out.CENTER_VERTICAL,76. RelativeLayout.TRUE; / 垂直居中77. imageParams.leftMargin = bgLeftMargin; / 左边距78. containerLayout.addView(mBgImage, imageParams; / 标题栏容器增加标题 item 背景图 片79. 80. if (titleLayoutId != 0 81. titleLayout = mInflater.inflate(titleLayoutId, this, false; / 获得标题栏布局82. LayoutParams titlePa
17、rams = new LayoutParams(83. LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT;/ 宽度WRAP_CONTENT ,高度 WRAP_CONTENT84. titleParams.addRule(RelativeLayout.CENTER_HORIZONTAL,85. RelativeLayout.TRUE; / 水平居中86. titleParams.addRule(RelativeLayout.CENTER_VERTICAL,87. RelativeLayout.TRUE; / 垂直居中88. container
18、Layout.addView(titleLayout, titleParams; / 标题栏容器增加标题栏布局89. 90. mViewPager = new ViewPager(mContext; / 创建 ViewPager91. mViewPager.setAdapter( new MPagerAdapter(; / 设置 ViewPager 适配器92. mViewPager.setOnPageChangeListener(this; / 设置页面改变的监听接口93. LayoutParams viewPagerParams = new LayoutParams(94. LayoutP
19、arams.FILL_PARENT, LayoutParams.FILL_PARENT; / 宽度FILL_PARENT ,高度 FILL_PARENT95. viewPagerParams.addRule(RelativeLayout.BELOW, containerLayout.getId(; / 布于标题栏容器下方96. viewPagerParams.addRule(RelativeLayout.CENTER_HORIZONTAL,97. RelativeLayout.TRUE; / 水平居中98. addView(mViewPager, viewPagerParams; / 当前布局
20、增加容器 ViewPager99. 100.101. / 增加一个绑定页面102. public void addBindedPage(int pageViewId, int titleItemId 103. mPageViews.add(mInflater.inflate(pageViewId, this, false;104. View item = titleLayout.findViewById(titleItemId;105. item.setOnClickListener( this;106. mItemViews.add(item;109.110.111.112.113.114.
21、115.116.117.118.119.120.121.122.123.124.125.126.127.128.129.130.131.132.133.134.135.136.137.138.139./ 获得页面数量public int getCount( return mPageViews.size(;/ 初始化页面(需要在 UI 加载完后,可以覆写 onWindowFocusChanged() public void setPage(int index setImagePosition(index; / 设置图像至标题项位置 mViewPager.setCurrentItem(index,
22、 false; / 设置 ViewPager 当前页面/ 设置当前页面public void setCurrentPage(int index, boolean isAnim previousIndex = currentIndex; / 记录前次页面索引 currentIndex = index; / 设置当前页面索引 mViewPager.setCurrentItem(index, isAnim; / 设置 ViewPager 当前页面 / Title 移动绑定在 ViewPager 的滚动事件内/ 设置图像至标题项位置private void setImagePosition(int i
23、ndex previousIndex = currentIndex; / 记录前次页面索引currentIndex = index; / 设置当前页面索引if (null = mBgImage return;LayoutParams params = (RelativeLayout.LayoutParams mBgImage .getLayoutParams(; / 获得图片布局View item = mItemViews.get(index; / 标题项/ 注: UI 加载完后 getLeft( 才有值int targetLeftMargin = ( int (item.getLeft( +
24、 item.getWidth( / 2.0 - mBgImage141.142.143.144.145.146.147.148.149.150.151.152.153.154.155.156.157.158.159.160.161.162.163.164.165.166.167.168.169.170.171.140.getWidth( / 2.0; / 目标左边距/ 位置未变时直接返回,以避免多次 setLayoutParams(.if (params.leftMargin = targetLeftMargin return ;params.leftMargin = targetLeftMa
25、rgin;mBgImage.setLayoutParams(params; / 使设置生效/ 设置图像移动像素距离private void moveImagePosition( int offset if (null = mBgImage return ;LayoutParams params = (RelativeLayout.LayoutParams mBgImage .getLayoutParams(; / 获得图片布局params.leftMargin += offset;mBgImage.setLayoutParams(params; / 使设置生效/* 当前页滚动时调用,无论是程序
26、控制的平滑滚动还是用户发起的触摸滚动。* arg0 :第一个页面当前显示的位置索引。如果页面偏移不是0,下一个页面将会可见* arg1 :表示第二个页面位置偏移量的比例值,0, 1。(右侧页面所占屏幕百分比)* arg2 :表示第二个页面位置偏移量的像素值。(右侧页面距右边的像素值)*/Overridepublic void onPageScrolled(int position, float positionOffset,int positionOffsetPixels / 判断是否不在动画,用 positionOffsetPixels 判断判断原因是:/ 1)position ,在选中了页
27、面时就会改变,自动动画时的不能判断/ 2 ) positionOffset ,动画完变为 0.0,但 float 不好直接等于判断172.173.174.175.176.177.178.179.180.181.182.183.184.185.186.187.188.189.190.191.192.193.194.195.196.197.198.199.200.201.202.203.204./ 3)positionOffsetPixels ,动画完变为 0,int 型 if (positionOffsetPixels = 0 setImagePosition(position;prevOffs
28、et = -1;isTitleClicked = false;return ;/ 刚移动时,记录下该次值if (prevOffset = -1 prevOffset = positionOffsetPixels;return ;int pageOffset = positionOffsetPixels - prevOffset; / 页面偏移距离 prevOffset = positionOffsetPixels;if (null != mBgImage try if (pageOffset 右int prevIndex, nextIndex;if (isTitleClicked prevIn
29、dex = previousIndex;nextIndex = currentIndex; else prevIndex = currentIndex;nextIndex = currentIndex - 1;/ 两菜单项间的距离int itemDistance = mItemViews.get(prevIndex.getLeft(- mItemViews.get(nextIndex.getLeft(;/ 图片偏移距离int imageOffset = pageOffset * itemDistance/ mViewPager.getWidth(;/ 设置图像移动像素距离moveImagePo
30、sition(imageOffset;205.206.207.208.209.210.211.212.213.214.215.216.217.218.219.220.221.222.223.224.225.226.227.228.229.230.231.232.233.234.235.236. elseif (pageOffset 0 / 右 -左int prevIndex, nextIndex;if (isTitleClicked prevIndex = previousIndex;nextIndex = currentIndex; else prevIndex = currentIndex
31、;nextIndex = currentIndex + 1;/ 两菜单项间的距离int itemDistance = mItemViews.get(nextIndex.getLeft(- mItemViews.get(prevIndex.getLeft(;/ 图片偏移距离int imageOffset = pageOffset * itemDistance/ mViewPager.getWidth(;/ 设置图像移动像素距离 moveImagePosition(imageOffset; catch (IndexOutOfBoundsException e / 类似在中间左右左右的来回拖拽 =
32、,判断还不够啊 TT setImagePosition(currentIndex;isTitleClicked = false;if ( null != mOnPageChangeListener mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels;/* 当一个新页面被选中时被调用。动画不一定必须完成。237. * arg0 :新选中页面的位置索引238. */239. Override240. public void onPageSelected(int position 24
33、1. if (null != mOnPageChangeListener 242. mOnPageChangeListener.onPageSelected(position;243. 244. 245.246. /*247. * 滚动状态改变时调用。用于发现用户何时开始拖动、页面何时自动沉降到当前页(用户 不拖动时)、或者何时完全停止 /空闲。248. * arg0 :新的滚动状态。 SCROLL_STATE_DRAGGING 、 SCROLL_STATE_SETTLING SCROLL_STATE_IDLE249. */250. Override251. public void onPag
34、eScrollStateChanged(int state 252. if (state = ViewPager.SCROLL_STATE_DRAGGING / 用户拖动时253. isTitleClicked = false;254. 255. if (null != mOnPageChangeListener 256. mOnPageChangeListener.onPageScrollStateChanged(state;257. 258. 259.260. / 自定义的 ViewPager 适配器261. private class MPagerAdapter extends Page
35、rAdapter 262.263. /*264. * 移除一个给定位置的页面。适配器有责任从它的容器中移除视图,虽然这仅必须确认 动作是在 finishUpdate( 后按时间完成的。265. * arg0 :容器视图,从中将移除页面。266. * arg1 :移除的页面位置267. * arg2 :和 instantiateItem(View, int返回的一样的对象268. */269. Override270. public void destroyItem(View arg0, int arg1, Object arg2 271. (ViewPager arg0.removeView(
36、mPageViews.get(arg1;272. 273.274. /*275. * 当显示的界面完成变化后调用。在这里,你应当必须确保所有的页面已经真正的从容 器中增加或删除。276. * arg0 :容器视图,用于显示适配器的页面视图277. */278. Override279. public void finishUpdate(View arg0 280. 281.282. / 返回可用界面的数量283. Override284.public int getCount( 285. return mPageViews.size(;286. 287.288. /*289. * 创建一个给定位置的界面。适配器有责任给这边给出的容器增加一个视图,虽然这仅 必须确认动作是在 finishUpdate( 后按时间完成的。290. * arg0 :容器视图,在里面将显示页面。29
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年高职网络工程(网络技术)试题及答案
- 2025年高职休闲体育服务与管理(体育俱乐部管理)试题及答案
- 2025年中职建筑装饰工程技术(建筑装饰工程)试题及答案
- 2025年大学地质(地质灾害防治)试题及答案
- 2025年高职第三学年(广告设计与制作)新媒体广告设计测试题及答案
- 2025年高职(烹调工艺与营养)宴席设计专项真题及答案
- 2025年中职(电梯维护)安全检测阶段测试卷
- 2025年大学三年级(机器人工程)机器人视觉技术试题及答案
- 2025年高职应用化学(化学分析)试题及答案
- 2025年中职(康复治疗)康复护理技术试题及答案
- 塔里木油田管理办法
- 整体护理病历课件
- 算法歧视法律规制-洞察及研究
- 《质量比较仪校准规范》
- 2025春季学期国开电大本科《人文英语4》一平台机考真题及答案(第八套)
- 2025-2030中国房地产与房地产软件行业市场发展趋势与前景展望战略研究报告
- R-Breaker交易系统策略(TB版)
- 光伏劳务居间合同范例
- 双氧水管理制度
- 公司环保迎检工作方案
- 石油化工行业安全生产智能化管理方案
评论
0/150
提交评论