Android自定义组件(一)
在原生组件上避免不了覆写、组合等,以定义自己的组件,也方便以后复用。例如之前工程里出现了多次的文件浏览器组件。
嗯~,该怎么总结呢?
一、概述
自定义组件,大概可以这么分吧。一、View或SurfaceView上自绘;二、ViewGroup布局子类整合;三、不清楚了~,好像也没什么好分的==。
本文的工程,个人觉着主要还是属性资源的使用吧?工程主要例子介绍如下:
|
名称
|
效果
|
属性
|
|
Loading动态...的效果组件
|
loading...的动态效果
|
定义了如下四属性:
1)loadImage:load字图片,reference类型
2)pointImage:小点图片,reference类型
3)pointCount:小点数目,integer类型
4)msecRate:毫秒级变化速率,integer类型
|
|
Title背景移位的效果组件
|
集合View布局,形成标题栏。实现了标题项下的背景移动的小效果。
|
定义了如下属性:
1)titleLayout:标题栏布局
2)bgImage:item背景图片
3)bgLeftMargin:背景初始左边距
4)animTime:移动动画时间
|
|
ViewPager绑定标题的效果组件
|
ViewPager绑定标题栏,并实现了标题项下的背景移动的小效果。
|
效果特征如下:
1)背景随ViewPager滚动而同步在标题间滚动
2)点击标题时,ViewPager程序控制滚动&背景同步
属性定义如下:
1)tLayout:标题栏布局
2)bImage:item背景图片
3)bMargin:背景初始左边距
|
|
ListView增加抽屉的效果组件
|
ListView增加抽屉的效果组件。抽屉打开的界面只用了一个。
|
1)listViewId:列表视图id,reference类型
2)drawerContent:抽屉内容视图id,reference类型
3)drawerClose:抽屉内容的关闭按钮id,reference类型
|
|
自定义能隐藏更多标题的组件
|
集合View布局,形成标题栏。实现超过标题数限制时,自动显示更多的效果。
|
初始化时,需要进行如下步骤:
1)设置显示数限制,默认将为6。
2)绑定标题内容。为String[],将直接以TextView显示==
3)绑定更多操作的视图id。将自己加载,并为其设置点击事件。
4)绑定更多显示的视图。应为已有的ViewGroup。将自动加载超出限制的标题内容(TextView)。更多操作则将控制其显示或隐藏。
另外,提供刷新内容的方法,用于:一、标题栏内容的重新加载;二,更多显示内容的重新加载。
|
|
自绘实时动态数据线
|
利用View绘制的实时数据显示组件?
|
写该文档时才挪进来的了,感觉弄得乱乱的。
双点缩放好像很不正确啊?应该是两个触摸点没弄对,获得的是一个手指头触发的两个点,所以一下放大了。(猜测,总之我是不修了^^)
|
以下将以“ViewPager扩展组件”为例了,顺便能看下ViewPager组件^^。
二、步骤
带属性资源,整合布局构建自定义组件的步骤~
1
)attrs.xml
定义组件需要用的属性。不用的话,就相当于一个类为一个自定义组件,不和这些东西挂钩。“自定义能隐藏更多标题的组件”即是这样的,连属性都没定义==。
ViewPager扩展组件定义的内容:
-
- <declare-styleable name="TitleViewPager">
- <attr format="reference" name="tLayout" />
- <attr format="reference" name="bImage" />
- <attr format="integer" name="bMargin" />
- </declare-styleable>
2
)item.xml
只要是xml的resources标签内即可,单独弄出来呢最好。用以下方式定义一个id,用于View.setId(int id),主要用于相对布局时,相对于某个id的View什么的。
ViewPager扩展组件定义的内容:
- <item name="containerLayout" type="id"/>
3
)创建组件
其类中引用属性资源。并看下ViewPager的使用说明吧:OnPageChangeListener接口方法和PagerAdapter适配器内方法的注释。
- public class TitleViewPager extends RelativeLayout implements
- OnPageChangeListener, View.OnClickListener {
-
- private Context mContext;
- private LayoutInflater mInflater;
-
- private int titleLayoutId;
- private int bgImageResId;
- private int bgLeftMargin;
-
- private View titleLayout;
- private ImageView mBgImage;
- private ArrayList<View> mItemViews;
-
- private ViewPager mViewPager;
- private ArrayList<View> mPageViews;
-
- private int prevOffset = -1;
- private int currentIndex;
- private int previousIndex;
- private boolean isTitleClicked;
-
- private OnPageChangeListener mOnPageChangeListener;
-
-
-
-
-
-
-
-
-
-
- public TitleViewPager(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- mContext = context;
- mInflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-
- TypedArray typedArray = context.obtainStyledAttributes(attrs,
- R.styleable.TitleViewPager);
-
- titleLayoutId = typedArray.getResourceId(
- R.styleable.TitleViewPager_tLayout, 0);
-
- bgImageResId = typedArray.getResourceId(
- R.styleable.TitleViewPager_bImage, 0);
-
- bgLeftMargin = typedArray.getInt(R.styleable.TitleViewPager_bMargin, 0);
-
- initLayout();
-
- mItemViews = new ArrayList<View>();
- mPageViews = new ArrayList<View>();
- }
-
-
- private void initLayout() {
- RelativeLayout containerLayout = new RelativeLayout(mContext);
- containerLayout.setId(R.id.containerLayout);
- LayoutParams containerParams = new LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
- containerParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,
- RelativeLayout.TRUE);
- containerParams.addRule(RelativeLayout.CENTER_HORIZONTAL,
- RelativeLayout.TRUE);
- addView(containerLayout, containerParams);
- if (0 != bgImageResId) {
- mBgImage = new ImageView(mContext);
- mBgImage.setImageResource(bgImageResId);
- LayoutParams imageParams = new LayoutParams(
- LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
- imageParams.addRule(RelativeLayout.CENTER_VERTICAL,
- RelativeLayout.TRUE);
- imageParams.leftMargin = bgLeftMargin;
- containerLayout.addView(mBgImage, imageParams);
- }
- if (titleLayoutId != 0) {
- titleLayout = mInflater.inflate(titleLayoutId, this, false);
- LayoutParams titleParams = new LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
- titleParams.addRule(RelativeLayout.CENTER_HORIZONTAL,
- RelativeLayout.TRUE);
- titleParams.addRule(RelativeLayout.CENTER_VERTICAL,
- RelativeLayout.TRUE);
- containerLayout.addView(titleLayout, titleParams);
- }
- mViewPager = new ViewPager(mContext);
- mViewPager.setAdapter(new MPagerAdapter());
- mViewPager.setOnPageChangeListener(this);
- LayoutParams viewPagerParams = new LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
- viewPagerParams.addRule(RelativeLayout.BELOW, containerLayout.getId());
- viewPagerParams.addRule(RelativeLayout.CENTER_HORIZONTAL,
- RelativeLayout.TRUE);
- addView(mViewPager, viewPagerParams);
- }
-
-
- public void addBindedPage(int pageViewId, int titleItemId) {
- mPageViews.add(mInflater.inflate(pageViewId, this, false));
- View item = titleLayout.findViewById(titleItemId);
- item.setOnClickListener(this);
- mItemViews.add(item);
- }
-
-
- public int getCount() {
- return mPageViews.size();
- }
-
-
- public void setPage(int index) {
- setImagePosition(index);
- mViewPager.setCurrentItem(index, false);
- }
-
-
- public void setCurrentPage(int index, boolean isAnim) {
- previousIndex = currentIndex;
- currentIndex = index;
- mViewPager.setCurrentItem(index, isAnim);
-
- }
-
-
- private void setImagePosition(int index) {
- previousIndex = currentIndex;
- currentIndex = index;
- if (null == mBgImage) {
- return;
- }
- LayoutParams params = (RelativeLayout.LayoutParams) mBgImage
- .getLayoutParams();
- View item = mItemViews.get(index);
-
- int targetLeftMargin = (int) (item.getLeft() + item.getWidth() / 2.0 - mBgImage
- .getWidth() / 2.0);
-
- if (params.leftMargin == targetLeftMargin) {
- return;
- }
- params.leftMargin = targetLeftMargin;
- mBgImage.setLayoutParams(params);
- }
-
-
- private void moveImagePosition(int offset) {
- if (null == mBgImage) {
- return;
- }
- LayoutParams params = (RelativeLayout.LayoutParams) mBgImage
- .getLayoutParams();
- params.leftMargin += offset;
- mBgImage.setLayoutParams(params);
- }
-
-
-
-
-
-
-
- @Override
- public void onPageScrolled(int position, float positionOffset,
- int positionOffsetPixels) {
-
-
-
-
- if (positionOffsetPixels == 0) {
- setImagePosition(position);
- prevOffset = -1;
- isTitleClicked = false;
- return;
- }
-
- if (prevOffset == -1) {
- prevOffset = positionOffsetPixels;
- return;
- }
- int pageOffset = positionOffsetPixels - prevOffset;
- prevOffset = positionOffsetPixels;
- if (null != mBgImage) {
- try {
- if (pageOffset < 0) {
- int prevIndex, nextIndex;
- if (isTitleClicked) {
- prevIndex = 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();
-
- moveImagePosition(imageOffset);
- } else if (pageOffset > 0) {
- int prevIndex, nextIndex;
- if (isTitleClicked) {
- prevIndex = previousIndex;
- nextIndex = currentIndex;
- } else {
- prevIndex = currentIndex;
- nextIndex = currentIndex + 1;
- }
-
- int itemDistance = mItemViews.get(nextIndex).getLeft()
- - mItemViews.get(prevIndex).getLeft();
-
- int imageOffset = pageOffset * itemDistance
- / mViewPager.getWidth();
-
- moveImagePosition(imageOffset);
- }
- } catch (IndexOutOfBoundsException e) {
-
- setImagePosition(currentIndex);
- isTitleClicked = false;
- }
- }
- if (null != mOnPageChangeListener) {
- mOnPageChangeListener.onPageScrolled(position, positionOffset,
- positionOffsetPixels);
- }
- }
-
-
-
-
-
- @Override
- public void onPageSelected(int position) {
- if (null != mOnPageChangeListener) {
- mOnPageChangeListener.onPageSelected(position);
- }
- }
-
-
-
-
-
- @Override
- public void onPageScrollStateChanged(int state) {
- if (state == ViewPager.SCROLL_STATE_DRAGGING) {
- isTitleClicked = false;
- }
- if (null != mOnPageChangeListener) {
- mOnPageChangeListener.onPageScrollStateChanged(state);
- }
- }
-
-
- private class MPagerAdapter extends PagerAdapter {
-
-
-
-
-
-
-
- @Override
- public void destroyItem(View arg0, int arg1, Object arg2) {
- ((ViewPager) arg0).removeView(mPageViews.get(arg1));
- }
-
-
-
-
-
- @Override
- public void finishUpdate(View arg0) {
- }
-
-
- @Override
- public int getCount() {
- return mPageViews.size();
- }
-
-
-
-
-
-
-
- @Override
- public Object instantiateItem(View arg0, int arg1) {
- ((ViewPager) arg0).addView(mPageViews.get(arg1), 0);
- return mPageViews.get(arg1);
- }
-
-
- @Override
- public boolean isViewFromObject(View arg0, Object arg1) {
- return arg0 == (arg1);
- }
-
-
- @Override
- public void restoreState(Parcelable arg0, ClassLoader arg1) {
- }
-
-
- @Override
- public Parcelable saveState() {
- return null;
- }
-
-
-
-
-
- @Override
- public void startUpdate(View arg0) {
- }
- }
-
- @Override
- public void onClick(View v) {
- int size = mItemViews.size();
- for (int i = 0; i < size; i++) {
- if (mItemViews.get(i).getId() == v.getId()) {
- isTitleClicked = true;
- setCurrentPage(i, true);
- break;
- }
- }
- }
-
-
- public ArrayList<View> getItemViews() {
- return mItemViews;
- }
-
-
- public ArrayList<View> getPageViews() {
- return mPageViews;
- }
-
-
- public void setOnPageChangeListener(OnPageChangeListener listener) {
- mOnPageChangeListener = listener;
- }
-
- }
附件工程,见(二)。
本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/872734,如需转载请自行联系原作者