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));
}
}
*/