搜档网
当前位置:搜档网 › Android自定义组件一

Android自定义组件一

Android自定义组件一
Android自定义组件一

1.

2.

3.

4.

5.

6.

format类型,参见:Android中attr自定义属性详解。

2)item.xml

只要是xml的resources标签内即可,单独弄出来呢最好。用以下方式定义一个id,用于View.setId(int id),主要用于相对布局时,相对于某个id的View什么的。

ViewPager扩展组件定义的内容:

1.

3)创建组件

其类中引用属性资源。并看下ViewPager的使用说明吧:OnPageChangeListener 接口方法和PagerAdapter适配器内方法的注释。

1.public class TitleViewPager extends RelativeLayout implements

2. OnPageChangeListener, View.OnClickListener {

3.

4.private Context mContext; // 上下文

5.private LayoutInflater mInflater; // 布局加载器

6.

7.private int titleLayoutId; // 标题栏布局id

8.private int bgImageResId; // item背景图片资源id

9.private int bgLeftMargin; // 背景初始左边距

10.

11.private View titleLayout; // 标题栏布局

12.private ImageView mBgImage; // item背景图片

13.private ArrayList mItemViews; // 标题项视图集合

14.

15.private ViewPager mViewPager; // ViewPager组件

16.private ArrayList mPageViews; // 页面视图集合

17.

18.private int prevOffset = -1; // 前次偏移值,这里用了int值像素

19.private int currentIndex; // 当前页面索引

20.private int previousIndex; // 前次页面索引

21.private boolean isTitleClicked; // 标题项点击

22.

23.private OnPageChangeListener mOnPageChangeListener; // 页面变化监

听事件

24.

25.// private final int REFRESH_RATE = 20; // 刷新速率20msec

26.// private Scroller mScroller; // 滚动器

27.// private static final Interpolator sInterpolator = new Interp

olator() {

28.// public float getInterpolation(float t) {

29.// t -= 1.0f;

30.// return t * t * t + 1.0f;

31.// }

32.// };

33.

34.public TitleViewPager(Context context, AttributeSet attrs) {

35.super(context, attrs);

36.

37. mContext = context;

38. mInflater = (LayoutInflater) context

39. .getSystemService(https://www.sodocs.net/doc/2b7007089.html,YOUT_INFLATER_SERVICE);

40.

41.// 获得TypedArray对象

42. TypedArray typedArray = context.obtainStyledAttributes(attr

s,

43. R.styleable.TitleViewPager);

44.// 获取标题栏布局id,默认0

45. titleLayoutId = typedArray.getResourceId(

46. R.styleable.TitleViewPager_tLayout, 0);

47.// 获取item背景图片资源id,默认0

48. bgImageResId = typedArray.getResourceId(

49. R.styleable.TitleViewPager_bImage, 0);

50.// 获取背景初始左边距,默认0

51. bgLeftMargin = typedArray.getInt(R.styleable.TitleViewPager

_bMargin, 0);

52.

53. initLayout(); // 初始化标题栏&ViewPager

54.

55. mItemViews = new ArrayList();

56. mPageViews = new ArrayList();

57. }

58.

59.// 初始化标题栏&ViewPager

60.private void initLayout() {

61. RelativeLayout containerLayout = new RelativeLayout(mContex

t); // 创建标题栏容器布局

62. containerLayout.setId(R.id.containerLayout); // 设置标识符

63. LayoutParams containerParams = new LayoutParams(

64. LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT

); // 宽度WRAP_CONTENT,高度WRAP_CONTENT

65. 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 != bgImageResId) {

71. mBgImage = new ImageView(mContext); // 创建item背景图片

72. mBgImage.setImageResource(bgImageResId); // 设置item背景

图片

73. LayoutParams imageParams = new LayoutParams(

74. LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CO

NTENT); // 宽度WRAP_CONTENT,高度WRAP_CONTENT

75. imageParams.addRule(RelativeLayout.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, fa

lse); // 获得标题栏布局

82. LayoutParams titleParams = new LayoutParams(

83. LayoutParams.FILL_PARENT, LayoutParams.WRAP_CON

TENT); // 宽度WRAP_CONTENT,高度WRAP_CONTENT

84. titleParams.addRule(RelativeLayout.CENTER_HORIZONTAL,

85. RelativeLayout.TRUE); // 水平居中

86. titleParams.addRule(RelativeLayout.CENTER_VERTICAL,

87. RelativeLayout.TRUE); // 垂直居中

88. containerLayout.addView(titleLayout, titleParams); //

标题栏容器增加标题栏布局

89. }

90. mViewPager = new ViewPager(mContext); // 创建ViewPager

91. mViewPager.setAdapter(new MPagerAdapter()); // 设置

ViewPager适配器

92. mViewPager.setOnPageChangeListener(this); // 设置页面改变的监

听接口

93. LayoutParams viewPagerParams = new LayoutParams(

94. LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)

; // 宽度FILL_PARENT,高度FILL_PARENT

95. viewPagerParams.addRule(RelativeLayout.BELOW, containerLayo

ut.getId()); // 布于标题栏容器下方

96. viewPagerParams.addRule(RelativeLayout.CENTER_HORIZONTAL,

97. RelativeLayout.TRUE); // 水平居中

98. addView(mViewPager, viewPagerParams); // 当前布局增加容器

ViewPager

99. }

100.

101.// 增加一个绑定页面

102.public void addBindedPage(int pageViewId, int titleItem Id) {

103. mPageViews.add(mInflater.inflate(pageViewId, this, false));

104. View item = titleLayout.findViewById(titleItemId);

105. item.setOnClickListener(this);

106. mItemViews.add(item);

107. }

108.

109.// 获得页面数量

110.public int getCount() {

111.return mPageViews.size();

112. }

113.

114.// 初始化页面(需要在UI加载完后,可以覆写

onWindowFocusChanged())

115.public void setPage(int index) {

116. setImagePosition(index); // 设置图像至标题项位置

117. mViewPager.setCurrentItem(index, false); // 设置ViewPager当前页面

118. }

119.

120.// 设置当前页面

121.public void setCurrentPage(int index, boolean isAnim) {

122. previousIndex = currentIndex; // 记录前次页面索引123. currentIndex = index; // 设置当前页面索引

124. mViewPager.setCurrentItem(index, isAnim); // 设置ViewPager当前页面

125.// Title移动绑定在ViewPager的滚动事件内

126. }

127.

128.// 设置图像至标题项位置

129.private void setImagePosition(int index) {

130. previousIndex = currentIndex; // 记录前次页面索引131. currentIndex = index; // 设置当前页面索引

132.if (null == mBgImage) {

133.return;

134. }

135. LayoutParams params = (https://www.sodocs.net/doc/2b7007089.html,youtParams) mBgImage

136. .getLayoutParams(); // 获得图片布局

137. View item = mItemViews.get(index); // 标题项

138.// 注:UI加载完后getLeft()才有值

139.int targetLeftMargin = (int) (item.getLeft() + item .getWidth() / 2.0 - mBgImage

140. .getWidth() / 2.0); // 目标左边距

141.// 位置未变时直接返回,以避免多次setLayoutParams(...) 142.if (params.leftMargin == targetLeftMargin) {

143.return;

144. }

145. params.leftMargin = targetLeftMargin;

146. mBgImage.setLayoutParams(params); // 使设置生效

147. }

148.

149.// 设置图像移动像素距离

150.private void moveImagePosition(int offset) {

151.if (null == mBgImage) {

152.return;

153. }

154. LayoutParams params = (https://www.sodocs.net/doc/2b7007089.html,youtParams) mBgImage

155. .getLayoutParams(); // 获得图片布局

156. params.leftMargin += offset;

157. mBgImage.setLayoutParams(params); // 使设置生效

158. }

159.

160./*

161. * 当前页滚动时调用,无论是程序控制的平滑滚动还是用户发起的触摸滚动。

162. * arg0:第一个页面当前显示的位置索引。如果页面偏移不是0,下一个页面将会可见。

163. * arg1:表示第二个页面位置偏移量的比例值,[0, 1)。(右侧页面所占屏幕百分比)

164. * arg2:表示第二个页面位置偏移量的像素值。(右侧页面距右边的像素值)

165. */

166.@Override

167.public void onPageScrolled(int position, float position Offset,

168.int positionOffsetPixels) {

169.// 判断是否不在动画,用positionOffsetPixels判断判断原因是:

170.// 1)position,在选中了页面时就会改变,自动动画时的不能判断171.// 2)positionOffset,动画完变为0.0,但float不好直接等于判断

172.// 3)positionOffsetPixels,动画完变为0,int型^^

173.if (positionOffsetPixels == 0) {

174. setImagePosition(position);

175. prevOffset = -1;

176. isTitleClicked = false;

177.return;

178. }

179.// 刚移动时,记录下该次值

180.if (prevOffset == -1) {

181. prevOffset = positionOffsetPixels;

182.return;

183. }

184.int pageOffset = positionOffsetPixels - prevOffset;

// 页面偏移距离

185. prevOffset = positionOffsetPixels;

186.if (null != mBgImage) {

187.try {

188.if (pageOffset < 0) { // 左->右

189.int prevIndex, nextIndex;

190.if (isTitleClicked) {

191. prevIndex = previousIndex;

192. nextIndex = currentIndex;

193. } else {

194. prevIndex = currentIndex;

195. nextIndex = currentIndex - 1; 196. }

197.// 两菜单项间的距离

198.int itemDistance = mItemViews.get(prevI ndex).getLeft()

199. - mItemViews.get(nextIndex).get Left();

200.// 图片偏移距离

201.int imageOffset = pageOffset * itemDist ance

202. / mViewPager.getWidth();

203.// 设置图像移动像素距离

204. moveImagePosition(imageOffset);

205. } else if (pageOffset > 0) { // 右->左

206.int prevIndex, nextIndex;

207.if (isTitleClicked) {

208. prevIndex = previousIndex;

209. nextIndex = currentIndex;

210. } else {

211. prevIndex = currentIndex;

212. nextIndex = currentIndex + 1; 213. }

214.// 两菜单项间的距离

215.int itemDistance = mItemViews.get(nextI ndex).getLeft()

216. - mItemViews.get(prevIndex).get Left();

217.// 图片偏移距离

218.int imageOffset = pageOffset * itemDist ance

219. / mViewPager.getWidth();

220.// 设置图像移动像素距离

221. moveImagePosition(imageOffset);

222. }

223. } catch (IndexOutOfBoundsException e) {

224.// 类似在中间左右左右的来回拖拽==,判断还不够啊T^T 225. setImagePosition(currentIndex);

226. isTitleClicked = false;

227. }

228. }

229.if (null != mOnPageChangeListener) {

230. mOnPageChangeListener.onPageScrolled(position, positionOffset,

231. positionOffsetPixels);

232. }

233. }

234.

235./*

236. * 当一个新页面被选中时被调用。动画不一定必须完成。

237. * arg0:新选中页面的位置索引

238. */

239.@Override

240.public void onPageSelected(int position) {

241.if (null != mOnPageChangeListener) {

242. mOnPageChangeListener.onPageSelected(position);

243. }

244. }

245.

246./*

247. * 滚动状态改变时调用。用于发现用户何时开始拖动、页面何时自动沉降到当前页(用户不拖动时)、或者何时完全停止/空闲。

248. * arg0:新的滚动状态。SCROLL_STATE_DRAGGING、SCROLL_STATE_SETTLING、SCROLL_STATE_IDLE

249. */

250.@Override

251.public void onPageScrollStateChanged(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 PagerAdapter { 262.

263./*

264. * 移除一个给定位置的页面。适配器有责任从它的容器中移除视图,虽然这仅必须确认动作是在finishUpdate()后按时间完成的。

265. * arg0:容器视图,从中将移除页面。

266. * arg1:移除的页面位置

267. * arg2:和instantiateItem(View, int)返回的一样的对象268. */

269.@Override

270.public void destroyItem(View arg0, int arg1, Object arg2) {

271. ((ViewPager) arg0).removeView(mPageViews.get(ar g1));

272. }

273.

274./*

275. * 当显示的界面完成变化后调用。在这里,你应当必须确保所有的页面已经真正的从容器中增加或删除。

276. * arg0:容器视图,用于显示适配器的页面视图

277. */

278.@Override

279.public void finishUpdate(View arg0) {

280. }

281.

282.// 返回可用界面的数量

283.@Override

284.public int getCount() {

285.return mPageViews.size();

286. }

287.

288./*

289. * 创建一个给定位置的界面。适配器有责任给这边给出的容器增加一个视图,虽然这仅必须确认动作是在finishUpdate()后按时间完成的。

290. * arg0:容器视图,在里面将显示页面。

291. * arg1:要被装载的页面位置

292. * Object:返回一个展现新画面的对象。这不必须是一个View,也可以是一些其他的页面容器。

293. */

294.@Override

295.public Object instantiateItem(View arg0, int arg1) {

296. ((ViewPager) arg0).addView(mPageViews.get(arg1) , 0);

297.return mPageViews.get(arg1);

298. }

299.

300.// 是否是由对象生成的视图

301.@Override

302.public boolean isViewFromObject(View arg0, Object a rg1) {

303.return arg0 == (arg1);

304. }

305.

306.// 恢复状态

307.@Override

308.public void restoreState(Parcelable arg0, ClassLoad er arg1) {

309. }

310.

311.// 保存状态,返回序列化对象

312.@Override

313.public Parcelable saveState() {

314.return null;

315. }

316.

317./*

318. * 当显示的页面将要开始变化时调用

319. * arg0:容器视图,用于显示适配器的页面视图

320. */

321.@Override

322.public void startUpdate(View arg0) {

323. }

324. }

325.

326.@Override

327.public void onClick(View v) {

328.int size = mItemViews.size(); // 大小

329.for (int i = 0; i < size; i++) {

330.if (mItemViews.get(i).getId() == v.getId()) {

331. isTitleClicked = true;

332. setCurrentPage(i, true);

333.break;

334. }

335. }

336. }

337.

338.// 获得标题项视图集合

339.public ArrayList getItemViews() {

340.return mItemViews;

341. }

342.

343.// 获得页面视图集合

344.public ArrayList getPageViews() {

345.return mPageViews;

346. }

347.

348.// 设置页面变化监听事件

349.public void setOnPageChangeListener(OnPageChangeListene r listener) {

350. mOnPageChangeListener = listener;

351. }

352.

353.}

android 自定义圆角头像以及使用declare-styleable进行配置属性解析

android 自定义圆角头像以及使用declare-styleable进行配置属性解析由于最新项目中正在检查UI是否与效果图匹配,结果关于联系人模块给的默认图片是四角稍带弧度的圆角,而我们截取的图片是正方形的,现在要给应用统一替换。应用中既用到大圆角头像(即整个头像是圆的)又用到四角稍带弧度的圆角头像,封装一下以便重用。以下直接见代码 [java] view plain copy 在CODE上查看代码片派生到我的代码片 package com.test.demo; import com.test.demo.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader.TileMode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.widget.ImageView; /** * 圆角imageview */ public class RoundImageView extends ImageView { private static final String TAG = "RoundImageView"; /** * 图片的类型,圆形or圆角 */ private int type; public static final int TYPE_CIRCLE = 0; public static final int TYPE_ROUND = 1; /** * 圆角大小的默认值

android studio 控件常用属性

android studio 控件常用属性 下面是RelativeLayout各个属性 1.android:layout_above="@id/xxx" --将控件置于给定ID控件之上 2.android:layout_below="@id/xxx" --将控件置于给定ID控件之下 3. android:layout_toLeftOf="@id/xxx" --将控件的右边缘和给定ID控件的左边缘对齐 4.android:layout_toRightOf="@id/xxx" --将控件的左边缘和给定ID控件的右边缘对齐 5. android:layout_alignLeft="@id/xxx" --将控件的左边缘和给定ID控件的左边缘对齐 6.android:layout_alignTop="@id/xxx" --将控件的上边缘和给定ID控件的上边缘对齐 7.android:layout_alignRight="@id/xxx" --将控件的右边缘和给定ID控件的右边缘对齐 8.android:layout_alignBottom="@id/xxx" --将控件的底边缘和给定ID控件的底边缘对齐 9.android:layout_alignParentLeft="true" --将控件的左边缘和父控件的左边缘对齐 10. android:layout_alignParentTop="true" --将控件的上边缘和父控件的上边缘对齐 11. android:layout_alignParentRight="true" --将控件的右边缘和父控件的右边缘对齐 12.android:layout_alignParentBottom="true" --将控件的底边缘和父控件的底边缘对齐 13.android:layout_centerInParent="true" --将控件置于父控件的中心位置 14.android:layout_centerHorizontal="true" --将控件置于水平方向的中心位置 15.android:layout_centerVertical="true" --将控件置于垂直方向的中心位置 android:layout_width 设置组件的宽度 android:layout_height 设置组件的高度 android:id 给组件定义一个id值,供后期使用 android:background 设置组件的背景颜色或背景图片 android:text 设置组件的显示文字 android:textColor 设置组件的显示文字的颜色 android:layout_below 组件在参考组件的下面 android:alignTop 同指定组件的顶平行

Android平台我的日记设计文档

Android平台我的日记 设计文档 项目名称:mydiray 项目结构示意: 阶段任务名称(一)布局的设计 开始时间: 结束时间: 设计者: 梁凌旭 一、本次任务完成的功能 1、各控件的显示 二、最终功能及效果 三、涉及知识点介绍 四、代码设计 activity_main.xml:

android:layout_centerHorizontal="true" android:layout_marginTop="88dp" android:text="@string/wo" android:textSize="35sp"/>