1. 组合控件 (组合两种已有的控件得来的自定义控件 通常继承自布局)
//public class PuzzleSumView extends RelativeLayout implements View.OnClickListener { // // private Context mContext; // private TextView mBackText; // private TextView mFontText; // // // public PuzzleSumView(Context context) { // this(context,null); // } // // public PuzzleSumView(Context context, AttributeSet attrs) { // super(context, attrs); // this.mContext=context; // init(); // // } // // @Override // public void onClick(View v) { // // } // // private void init() { // initView(); // initData(); // initEvent(); // } // // private void initData() { // } // // private void initView() { // View view= LayoutInflater.from(mContext).inflate(R.layout.puzzle_sum_view,null); // mBackText= (TextView) view.findViewById(R.id.puzzle_view_tv_next); // mFontText= (TextView) view.findViewById(R.id.tv_sum); // addView(view); // } // // private void initEvent() { // mBackText.setText("选图"); // mFontText.setText("0"); // // // } // // public void setNum(int sum){ // mFontText.setText(sum+""); // if(sum>=2){ // mBackText.setText("下一步"); // }else { // mBackText.setText("选图"); // } // } //}
public class SelectItem extends RelativeLayout { public static int mImageViewHeight; public final int mImageViewWidth; private ImageView mImageView; private ImageView mCheckImg; public SelectItem(Context context) { super(context); // setGravity(Gravity.CENTER); mImageView = new ImageView(context); mImageView.setAdjustViewBounds(true); mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP); mImageView.setPadding(DensityUtil.dip2px(context, 1), DensityUtil.dip2px(context, 1), DensityUtil.dip2px(context, 1), DensityUtil.dip2px(context, 1)); int selectPicWitdh = DensityUtil.dip2px(context, 70); int selectPicHeight = DensityUtil.dip2px(context, 70); LayoutParams mImageViewRLP = new LayoutParams(selectPicWitdh, selectPicHeight); mImageViewRLP.setMargins(DensityUtil.dip2px(context, 20), 0, 0, 0); addView(mImageView, mImageViewRLP); //添加红色删除图标 mCheckImg = new ImageView(context); mCheckImg.setImageResource(R.drawable.del_select_pic); LayoutParams checkImgRLP = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); checkImgRLP.setMargins(DensityUtil.dip2px(context, 70), DensityUtil.dip2px(context, 5), 0, 0); mImageViewHeight = mImageView.getHeight(); mImageViewWidth = mImageView.getWidth(); addView(mCheckImg, checkImgRLP); } public ImageView getmImageView() { return mImageView; } public ImageView getCheckImg() { return mCheckImg; } public View hideView() { mCheckImg.setVisibility(INVISIBLE); mImageView.setVisibility(INVISIBLE); return this; } }
二 继承控件 (扩展已有的控件,继承自该控件)
public class CustomTestView extends TextView { public CustomTestView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public CustomTestView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CustomTestView(Context context) { super(context); init(); } private void init() { Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "gotham-medium.otf"); setTypeface(tf); } }
三 自定义控件 继承自View构造函数1个参数 用于代码, 2个参数用于布局文件属性需要
public class DragView extends View { private Bitmap mBitmap = null; private Context mContext = null; private Rect mFrameRect = null; private Paint mPaint = null; private Rect mThumbnailRect = null; public DragView(Context c) { super(c); } public DragView(Context c, AttributeSet attr) { super(c, attr); if (mContext == null) { mContext = c; } init(); } private void drawFrame(Canvas canvas) { if (mFrameRect == null || mPaint == null) { return; } mPaint.setColor(Color.parseColor("#00fff0")); mPaint.setAlpha(255); canvas.drawRect(mFrameRect, mPaint); } private void drawThumbnail(Canvas canvas) { if (mThumbnailRect == null || mPaint == null || mBitmap == null || mBitmap.isRecycled()) { return; } mPaint.setAlpha(127); canvas.drawBitmap(mBitmap, null, mThumbnailRect, mPaint); } private void init() { if (mPaint == null) { mPaint = new Paint(); } int i = mContext.getResources().getDimensionPixelSize(R.dimen.dragview_stroke_w); mPaint.setStrokeWidth(i); mPaint.setColor(ContextCompat.getColor(mContext, R.color.grid_collage_background)); mPaint.setAntiAlias(true); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAlpha(127); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawThumbnail(canvas); drawFrame(canvas); } }
public class PuzzleView extends View { private Context context; private Path[] path; private Bitmap[] bitmaps; private boolean[] bitmapsFlag; private float[][] pathLT; private float[][] pathOffset; private int pathNum; private int viewWdh, viewHgt; private int leftMargin; private List<ImageBean> pics; private final static int MARGIN_HEIGHT = 100; private List<ImageItem> coordinateSetList; public PuzzleView(Context context) { super(context); this.context = context; } public PuzzleView(Context context, AttributeSet attributeSet) { super(context, attributeSet); this.context = context; initPath(); } public PuzzleView(Context context, AttributeSet attributeSet, int defStyle) { super(context, attributeSet, defStyle); this.context = context; initPath(); } public void setPathCoordinate(List<ImageItem> pathCoordinate) { this.coordinateSetList = pathCoordinate; initPath(); } public void setPics(List<ImageBean> imageBeans) { leftMargin = (AppUtil.getScreenWidth(context) - dp2px(320)) / 2; viewWdh = dp2px(320); viewHgt = dp2px(450); pics = new ArrayList<>(); if (imageBeans != null) { pics.addAll(imageBeans); } pathNum = pics.size(); } private void initPath() { path = new Path[pathNum]; for (int i = 0; i < pathNum; i++) { path[i] = new Path(); } bitmapsFlag = new boolean[pathNum]; pathLT = new float[pathNum][2]; pathOffset = new float[pathNum][2]; for (int i = 0; i < pathNum; i++) { bitmapsFlag[i] = false; pathLT[i][0] = 0f; pathLT[i][1] = 0f; pathOffset[i][0] = 0f; pathOffset[i][1] = 0f; } for (int i = 0; i < pathNum; i++) { for (int j = 0; j < coordinateSetList.get(i).getCoordinates().size(); j++) { float x = coordinateSetList.get(i).getCoordinates().get(j).getX(); float y = coordinateSetList.get(i).getCoordinates().get(j).getY(); if (j == 0) { path[i].moveTo(dp2px(x), dp2px(y)); } else { path[i].lineTo(dp2px(x), dp2px(y)); } } path[i].close(); } // get bitmap bitmaps = new Bitmap[pathNum]; for (int i = 0; i < pathNum; i++) { BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inJustDecodeBounds = true; BitmapFactory.decodeFile(pics.get(i).path, opt); int bmpWdh = opt.outWidth; int bmpHgt = opt.outHeight; Coordinates coordinate = caculateViewSize(coordinateSetList.get(i).getCoordinates()); int size = caculateSampleSize(bmpWdh, bmpHgt, dp2px(coordinate.getX()), dp2px(coordinate.getY())); opt.inJustDecodeBounds = false; opt.inSampleSize = size; bitmaps[i] = scaleImage(BitmapFactory.decodeFile(pics.get(i).path, opt), dp2px(coordinate.getX()), dp2px(coordinate.getY())); } } private Coordinates caculateViewSize(List<Coordinates> list) { float viewWidth; float viewHeight; viewWidth = caculateMaxCoordinateX(list) - caculateMinCoordinateX(list); viewHeight = caculateMaxCoordinateY(list) - caculateMinCoordinateY(list); return new Coordinates(viewWidth, viewHeight); } private int caculateSampleSize(int picWdh, int picHgt, int showWdh, int showHgt) { // 如果此时显示区域比图片大,直接返回 if (showWdh < picWdh && showHgt < picHgt) { int wdhSample = picWdh / showWdh; int hgtSample = picHgt / showHgt; // 利用小的来处理 int sample = wdhSample > hgtSample ? hgtSample : wdhSample; int minSample = 2; while (sample > minSample) { minSample *= 2; } return minSample >> 1; } else { return 0; } } private float caculateMinCoordinateX(List<Coordinates> list) { float minX; minX = list.get(0).getX(); for (int i = 1; i < list.size(); i++) { if (list.get(i).getX() < minX) { minX = list.get(i).getX(); } } return minX; } private float caculateMaxCoordinateX(List<Coordinates> list) { float maxX; maxX = list.get(0).getX(); for (int i = 1; i < list.size(); i++) { if (list.get(i).getX() > maxX) { maxX = list.get(i).getX(); } } return maxX; } private float caculateMinCoordinateY(List<Coordinates> list) { float minY; minY = list.get(0).getY(); for (int i = 1; i < list.size(); i++) { if (list.get(i).getY() < minY) { minY = list.get(i).getY(); } } return minY; } private float caculateMaxCoordinateY(List<Coordinates> list) { float maxY; maxY = list.get(0).getY(); for (int i = 1; i < list.size(); i++) { if (list.get(i).getY() > maxY) { maxY = list.get(i).getY(); } } return maxY; } //图片缩放 private static Bitmap scaleImage(Bitmap bm, int newWidth, int newHeight) { if (bm == null) { return null; } int width = bm.getWidth(); int height = bm.getHeight(); float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; float scale = 1; if (scaleWidth >= scaleHeight) { scale = scaleWidth; } else { scale = scaleHeight; } Matrix matrix = new Matrix(); matrix.postScale(scale, scale); Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); return newbm; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(viewWdh, viewHgt); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.TRANSPARENT);// 显示背景颜色 Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.WHITE); // canvas.drawPaint(paint); // draw1(canvas); startDraw(canvas, paint); } private void startDraw(Canvas canvas, Paint paint) { for (int i = 0; i < pathNum; i++) { canvas.save(); drawScene(canvas, paint, i); canvas.restore(); } } private void drawScene(Canvas canvas, Paint paint, int idx) { canvas.clipPath(path[idx]); canvas.drawColor(Color.GRAY); if (bitmapsFlag[idx]) { canvas.drawBitmap(bitmaps[idx], dp2px(caculateMinCoordinateX(coordinateSetList.get(idx).getCoordinates())) + pathOffsetX + pathOffset[idx][0], dp2px(caculateMinCoordinateY(coordinateSetList.get(idx).getCoordinates())) + pathOffsetY + pathOffset[idx][1], paint); } else { canvas.drawBitmap(bitmaps[idx], dp2px(caculateMinCoordinateX(coordinateSetList.get(idx).getCoordinates())) + pathOffset[idx][0], dp2px(caculateMinCoordinateY(coordinateSetList.get(idx).getCoordinates())) + pathOffset[idx][1], paint); } } private int dp2px(float point) { return DensityUtil.dip2px(getContext(), point); } float ptx, pty; float pathOffsetX, pathOffsetY; @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: for (int i = 0; i < pathNum; i++) { bitmapsFlag[i] = false; } ptx = event.getRawX() - dp2px(leftMargin); pty = event.getRawY() - dp2px(MARGIN_HEIGHT); pathOffsetX = 0; pathOffsetY = 0; int cflag = 0; for (cflag = 0; cflag < pathNum; cflag++) { if (contains(path[cflag], ptx, pty)) { bitmapsFlag[cflag] = true; break; } } break; case MotionEvent.ACTION_MOVE: pathOffsetX = event.getRawX() - dp2px(leftMargin) - ptx; pathOffsetY = event.getRawY() - dp2px(MARGIN_HEIGHT) - pty; invalidate(); break; case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_UP: for (int i = 0; i < pathNum; i++) { if (bitmapsFlag[i]) { pathOffset[i][0] += event.getRawX() - dp2px(leftMargin) - ptx; pathOffset[i][1] += event.getRawY() - dp2px(MARGIN_HEIGHT) - pty; if (pathOffset[i][0] > 0) { pathOffset[i][0] = 0; } if (pathOffset[i][0] < -(bitmaps[i].getWidth() - getViewWidth(coordinateSetList.get(i).getCoordinates()))) { pathOffset[i][0] = -(bitmaps[i].getWidth() - getViewWidth(coordinateSetList.get(i).getCoordinates())); } if (pathOffset[i][1] > 0) { pathOffset[i][1] = 0; } if (pathOffset[i][1] < -(bitmaps[i].getHeight() - getViewHeight(coordinateSetList.get(i).getCoordinates()))) { pathOffset[i][1] = -(bitmaps[i].getHeight() - getViewHeight(coordinateSetList.get(i).getCoordinates())); } bitmapsFlag[i] = false; break; } } invalidate(); break; default: break; } return true; } private boolean contains(Path parapath, float pointx, float pointy) { RectF localRectF = new RectF(); parapath.computeBounds(localRectF, true); Region localRegion = new Region(); localRegion.setPath(parapath, new Region((int) localRectF.left, (int) localRectF.top, (int) localRectF.right, (int) localRectF.bottom)); return localRegion.contains((int) pointx, (int) pointy); } private float getViewWidth(List<Coordinates> list) { return dp2px(caculateMaxCoordinateX(list) - caculateMinCoordinateX(list)); } private float getViewHeight(List<Coordinates> list) { return dp2px(caculateMaxCoordinateY(list) - caculateMinCoordinateY(list)); } } */