自定义View实现项目中的需求
来源:互联网 发布:反编译软件为dede 编辑:程序博客网 时间:2024/06/10 14:53
今天我要说的是,在项目中遇到这种情况,就是在个人中心,购买的商品有五种状态,这五个图标将要是下面这样的排列如图:
要求:
1.位置1和位置2分别位于父容器的left和right,这是必须满足的条件
2.这5个View必须是平分父容器的
首先我先到了GrideView,然后发现无论怎么调整item布局都无法达到上述要求,位置5无法满足
然后,我用的是LinearLayout,写五个,发先还是不行,两边的确定了,中间区域和两边的区域的距离无法做到一致,本来先想弄个线程的布局写写就可以了,可是,浪费了一些时间,算了,还是自己定义吧!。
1.继承ViewGroup
2.重写OnMeasure()方法
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int modeW = MeasureSpec.getMode(widthMeasureSpec); int modeH = MeasureSpec.getMode(heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); measureChildren(widthMeasureSpec,heightMeasureSpec); if (mDirection==HORIZONTAL&&modeW==MeasureSpec.UNSPECIFIED){ //这里没有指定大小 throw new RuntimeException("if you sure this view's weight exactly"); } if (mDirection==VERTICAL&&modeW==MeasureSpec.UNSPECIFIED){ //这里没有指定大小 throw new RuntimeException("if you sure this view's height exactly"); } if (modeH!=MeasureSpec.EXACTLY) { //要测量子View的高度 switch (mDirection) { case HORIZONTAL: int hH = getHorizontalHeight(); setMeasuredDimension(width, hH); break; case VERTICAL: int hV = getVerticalWidth(); setMeasuredDimension(width, hV); break; } }else { setMeasuredDimension(width,height); }}
/**
* 垂直方向时,测量View的高度
* @return
*/
private int getVerticalWidth() { int w = 0; int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); MarginLayoutParams lp; //获取View的MarginLayoutParams实例 if (child.getLayoutParams() instanceof ViewGroup.MarginLayoutParams){ lp = (MarginLayoutParams) child.getLayoutParams(); }else { lp = new MarginLayoutParams(child.getLayoutParams()); } int childW = child.getMeasuredWidth()+lp.leftMargin+lp.rightMargin; Math.max(w,childW); } return w;}
/**
* 水平方向时,View的高度
* @return
*/
private int getHorizontalHeight() { int h = 0; int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); MarginLayoutParams lp; //获取View的MarginLayoutParams实例 if (child.getLayoutParams() instanceof ViewGroup.MarginLayoutParams){ lp = (MarginLayoutParams) child.getLayoutParams(); }else { lp = new MarginLayoutParams(child.getLayoutParams()); } int childH = child.getMeasuredHeight()+lp.topMargin+lp.bottomMargin; h=Math.max(h,childH); } return h;}
3.实现onLayout()方法
@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) { int count = getChildCount(); int margin; switch (mDirection) { case HORIZONTAL: margin = getHorizontalMargin(count); //layout layoutHorizontalChild(count,margin); break; case VERTICAL: margin = getVerticalMargin(count); layoutVerticalChild(count,margin); break; }} private void layoutHorizontalChild(int count,int margin) { int wNum = getPaddingLeft(); for (int i = 0; i < count; i++) { View child = getChildAt(i); child.layout(wNum,getTopOrDownMargin(child),wNum+child.getMeasuredWidth(),getTopOrDownMargin(child)+child.getMeasuredHeight()); wNum += child.getMeasuredWidth()+margin; }}private void layoutVerticalChild(int count,int margin) { int hNum = getPaddingTop(); for (int i = 0; i < count; i++) { View child = getChildAt(i); child.layout(getLeftOrRightMargin(child),hNum,getLeftOrRightMargin(child)+child.getMeasuredWidth(), hNum+child.getMeasuredHeight()); hNum += child.getMeasuredHeight()+margin; }}public int getTopOrDownMargin(View child){ int h = child.getMeasuredHeight(); return (getMeasuredHeight()-h)/2;}public int getLeftOrRightMargin(View child){ int w = child.getMeasuredWidth(); return (getMeasuredWidth()-w)/2;}private int getHorizontalMargin(int count) { int margin = getMeasuredWidth()-getPaddingLeft()-getPaddingRight(); for (int i = 0; i < count; i++) { View child = getChildAt(i); margin -= child.getMeasuredWidth(); } //真正的margin return margin/(count-1);}private int getVerticalMargin(int count) { int margin = getMeasuredHeight()-getPaddingTop()-getPaddingBottom(); for (int i = 0; i < count; i++) { View child = getChildAt(i); margin -= child.getMeasuredHeight(); } //真正的margin return margin/(count-1);}
好了,现在我们已经正确测量和layout了child,现在我们要设计数据的载入
public class Adapter<T>{ private List<Map<T,Object>> mList; private @LayoutRes int mLayout; private String[] key; private @IdRes int id[]; /** * 类似SimpleAdapter * @param mList 带有数据的集合 * @param mLayout 布局id * @param key Map中的key的数组 * @param id 与key一一对应的View的id */ public Adapter(List<Map<T, Object>> mList, int mLayout, String[] key, int[] id) { this.mList = mList; this.mLayout = mLayout; this.key = key; this.id = id; } private void addView(){ removeAllViews(); for (Map<T,Object> map:mList){ View view = LayoutInflater.from(getContext()).inflate(mLayout,null); int size = id.length; for (int i = 0; i <size ; i++) { Object obj = map.get(key[i]); if (obj instanceof String){ TextView tv = (TextView) view.findViewById(id[i]); tv.setText((String) obj); } if (obj instanceof Integer){ ImageView img = (ImageView) view.findViewById(id[i]); img.setImageResource((Integer) obj); } } GongGeView.this.addView(view); invalidate(); requestLayout(); } }}
这是一个内部类,负责将View加进父容器。
点击时间的监听
public interface ItemClickListener{ void click(View v,int position);}
点击时间接口抛出,留给用户
public void setOnItemClickListener(final ItemClickListener mItemClickListener){ this.mItemClickListener = mItemClickListener; int count = getChildCount(); for (int i = 0; i < count; i++) { View v = getChildAt(i); final int finalI = i; v.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mItemClickListener==null){ return; } mItemClickListener.click(v, finalI); } }); }}
好了,这就完成了,效果如下如图:
1 0
- 自定义View实现项目中的需求
- 自定义View实现TextView中的DrawableLeft缺陷
- 自定义 spring mvc 拦截器(近期项目需求实现)
- 关于自定义view 以及view中的动画实现
- 项目中的需求
- 项目中的隐藏需求
- 底部导航栏(自定义View+ViewPager实现) android项目详解
- 自定义View中的Mesure
- 自定义View中的事件
- 自定义View中的动画
- Android中的自定义View
- 自定义View中的测量
- 自定义view中的onLayout
- 自定义View中的问题
- AlertDialog中使用自定义View中的点击监听如何实现
- 自定义View中的控件实现页面的跳转
- Android自定义View实现
- 自定义View实现换灯片
- Android 跳转到其他APP/浏览器时,返回键和列表键无法使用
- 全卷积网络FCN论文阅读Fully Convolutional Networks for Semantic Segmentation
- linux指令识记
- MySQL 创建存储过程(MySQL 5.0)
- CS231n-01-Image Classification
- 自定义View实现项目中的需求
- Elasticsearch Bulk
- ubifs文件系统制作
- linux下的时间 date 和 hwclock命令
- mysql的varchar(20)和oracle的varchar2(20)有什么不同?
- 简单通用的缺陷跟踪管理系统,欢迎联系
- Android MVVM架构模式 详解和综合运用(一)
- 深入解读JavaScript中BOM和DOM
- 深入理解正则表达式