仿半塘图片添加标签功能
来源:互联网 发布:ubuntu安装tomcat 编辑:程序博客网 时间:2024/05/29 17:02
模仿半塘app的图片添加标签功能,刚开始反编译了半塘的代码,结果代码太多了,用一些三方的东西,觉的比较麻烦,这里自己写了一下实现,感觉和半塘的没啥区别(自我感觉良好,嘿嘿)
一、半塘功能实现步骤
二、半塘实现分析
功能分析
- 本地相册选择
- 添加图片
- 添加标签
- 标签移动
- 标签动画切换
- 图片生成
实现说明
(1) 标签类型有两种 第一种是单个标签 第二种是两个标签
(2) 第一种标签的包含:原点和文字
(3) 第二步标签包含:原点、文字和横线
(4) 原点的位置是点击的位置
(5) 文字有两种样式,一种是向左的,一种是向右的(对应实现)
(6) 横线有四种样式
三、实现
(1)类结构图
(2)代码结构
(3)具体实现
圆点的实现
public class LabelRoundDot extends Drawable{ private Paint mPaint; private Bitmap mBitmap; private RectF rectF; public LabelRoundDot(Bitmap bitmap) { mBitmap = bitmap; BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setShader(bitmapShader); } @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); rectF = new RectF(left, top, right, bottom); } @Override public void draw(Canvas canvas) { canvas.drawRoundRect(rectF, 30, 30, mPaint); } @Override public int getIntrinsicWidth() { return mBitmap.getWidth(); } @Override public int getIntrinsicHeight() { return mBitmap.getHeight(); } @Override public void setAlpha(int alpha) { mPaint.setAlpha(alpha); } @Override public void setColorFilter(ColorFilter cf) { mPaint.setColorFilter(cf); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; }}
文字的实现
初始化
public LabelTextView(String labelText, int textType){ this.labelText = labelText; this.currentType = textType; mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setTextSize(TEXT_SIZE); initLabel(); } private void initLabel(){ Rect mBounds = new Rect(); mPaint.getTextBounds(this.labelText, 0, this.labelText.length(), mBounds); this.labelTextHeight = mBounds.height() + VIEW_PADDING; this.labelTextWidth = labelTextHeight/2 +(mBounds.width()<6? 6:mBounds.width()) + VIEW_PADDING; Log.i(TAG, "initLabel labelTextHeight = " + labelTextHeight + " labelTextWidth = " + labelTextWidth); }
画第一种类型
private void drawFrist(Canvas canvas){ mPaint.setStrokeWidth(3); mPaint.setColor(Color.parseColor("#99000000")); //画半圆 RectF oval = new RectF(0, 0, labelTextHeight, labelTextHeight); canvas.drawArc(oval, 270, -180, true, mPaint); Rect targetRect = new Rect(labelTextHeight/2, 0, labelTextWidth - VIEW_PADDING, labelTextHeight); canvas.drawRect(targetRect, mPaint); //画三角形 Path path = new Path(); path.moveTo(labelTextWidth - VIEW_PADDING, 0);// 此点为多边形的起点 path.lineTo(labelTextWidth, labelTextHeight/2); path.lineTo(labelTextWidth - VIEW_PADDING, labelTextHeight); path.close(); // 使这些点构成封闭的多边形 canvas.drawPath(path, mPaint); //写文字 mPaint.setColor(Color.parseColor("#ffffff")); Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt(); int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2; // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX() mPaint.setTextAlign(Paint.Align.CENTER); canvas.drawText(labelText, targetRect.centerX(), baseline, mPaint); }
画第二种类型
private void drawSecond(Canvas canvas){ Log.i(TAG, "onDrawSecond ---------"); mPaint.setStrokeWidth(3); mPaint.setColor(Color.parseColor("#99000000")); //画半圆 RectF oval = new RectF(labelTextWidth - labelTextHeight, 0, labelTextWidth, labelTextHeight); canvas.drawArc(oval,90, -180, true, mPaint); //画矩形 Rect targetRect = new Rect(VIEW_PADDING, 0, labelTextWidth-labelTextHeight/2, labelTextHeight); canvas.drawRect(targetRect, mPaint); //画三角形 Path path = new Path(); path.moveTo(VIEW_PADDING, 0);// 此点为多边形的起点 path.lineTo(0, labelTextHeight/2); path.lineTo(VIEW_PADDING, labelTextHeight); path.close(); // 使这些点构成封闭的多边形 canvas.drawPath(path, mPaint); //写文字 mPaint.setColor(Color.parseColor("#ffffff")); Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt(); int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2; // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX() mPaint.setTextAlign(Paint.Align.CENTER); canvas.drawText(labelText, targetRect.centerX(), baseline, mPaint); }
线条的实现
初始化
public LabelLineView (int type){ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStrokeWidth(3); mPaint.setColor(Color.parseColor("#99000000")); labelHeight = slashHeight; labelWidth = slashWidth + straightLine; this.currentType = type; Log.i(TAG, "onDrawFirst labelHeight = " + labelHeight + " labelWidth = " + labelWidth); }
四种类型
/** * * @param canvas */ private void drawFrist(Canvas canvas){ //画第一条直线 int lineSx = 0; int lineSy = 0; int lineEx = straightLine; int lineEy = 0; canvas.drawLine(lineSx, lineSy, lineEx, lineEy, mPaint);// 画线 lineSx = straightLine; lineSy = 0; lineEx = labelWidth; lineEy = labelHeight; canvas.drawLine(lineSx, lineSy, lineEx, lineEy, mPaint);// 画线 } /** * * @param canvas */ private void drawSecond(Canvas canvas){ //画第一条直线 int lineSx = 0; int lineSy = labelHeight; int lineEx = straightLine; int lineEy = labelHeight; canvas.drawLine(lineSx, lineSy, lineEx, lineEy, mPaint);// 画线 lineSx = straightLine; lineSy = labelHeight; lineEx = labelWidth; lineEy = 0; canvas.drawLine(lineSx, lineSy, lineEx, lineEy, mPaint);// 画线 } private void drawThird(Canvas canvas){ int lineSx = 0; int lineSy = labelHeight; int lineEx = slashWidth; int lineEy = 0; canvas.drawLine(lineSx, lineSy, lineEx, lineEy, mPaint);// 画线 lineSx = slashWidth; lineSy = 0; lineEx = labelWidth; lineEy = 0; canvas.drawLine(lineSx, lineSy, lineEx, lineEy, mPaint);// 画线 } private void drawFourth(Canvas canvas){ //画第一条直线 int lineSx = 0; int lineSy = 0; int lineEx = slashWidth; int lineEy = slashHeight; canvas.drawLine(lineSx, lineSy, lineEx, lineEy, mPaint);// 画线 lineSx = slashWidth; lineSy = slashHeight; lineEx = labelWidth; lineEy = labelHeight; canvas.drawLine(lineSx, lineSy, lineEx, lineEy, mPaint);// 画线 }
LabelViewListener标签的实现监听
包含:标签的位置、切换样式、显示和隐藏动画、更新坐标(中心)、更新内容、判断是否点击到中心等方法。
只有一个内容的标签
有两种绘制模式,包含原点和文字,记录中心位置和当前的模式
包含绘制两种模式的方法、显示和隐藏的动画、提供view的大小和位置等。
第一种模式
/** * 绘制第一模式 * * @param canvas */ private void onDrawFirst(Canvas canvas) { Log.i(TAG, "onDrawFirst ---------"); canvas.drawBitmap(Utils.drawableToBitmap(labelTextView),4,0,mPaint); //画原点 int xBmp = labelViewWidth-originPic.getWidth(); int yBmp = (labelViewHeight-originPic.getWidth())/2; canvas.drawBitmap(originPic, xBmp, yBmp, null); Log.i(TAG, "onDrawFirst xBmp = " + xBmp + " yBmp = " + yBmp); }
第二种模式
/** * 绘制第二模式 * * @param canvas */ private void onDrawSecond(Canvas canvas) { Log.i(TAG, "onDrawSecond ---------"); canvas.drawBitmap(Utils.drawableToBitmap(labelTextView), originPic.getWidth()-4, 0, mPaint); //画原点 int xBmp = 0; int yBmp = (labelViewHeight-originPic.getWidth())/2; canvas.drawBitmap(originPic, xBmp, yBmp, null); Log.i(TAG, "onDrawFirst xBmp = " + xBmp + " yBmp = " + yBmp); }
显示动画
@Override public ValueAnimator getLabelShowAnim() { ValueAnimator anim = null; if (currentType == FRIST_MODEL) { anim = ValueAnimator.ofInt(labelViewWidth, 0); } else if (currentType == SECOND_MODEL) { anim = ValueAnimator.ofInt(0, labelViewWidth); } if (anim == null) { return null; } anim.setDuration(500); return anim; }
隐藏动画
@Override public ValueAnimator getLabelHideAnim() { ValueAnimator anim = null; if (currentType == FRIST_MODEL) { anim = ValueAnimator.ofInt(0, labelViewWidth); } else if (currentType == SECOND_MODEL) { anim = ValueAnimator.ofInt(labelViewWidth, 0); } if (anim == null) { return null; } anim.setDuration(500); return anim; }
有两个内容的标签
包含圆点、线条和文字
有四种绘制模式
第一种模式
/** * 绘制第一模式 * * @param canvas */ private void onDrawFirst(Canvas canvas) { Log.i(TAG, "onDrawFirst ---------"); //上面的文字 canvas.drawBitmap(Utils.drawableToBitmap(labelTextViewFirst), labelViewWidth-originPic.getWidth()-labelLineViewFirst.getIntrinsicWidth()-labelTextViewFirst.getIntrinsicWidth(), 0,mPaint); //上面的线条 canvas.drawBitmap(Utils.drawableToBitmap(labelLineViewFirst), labelViewWidth-originPic.getWidth()-labelLineViewFirst.getIntrinsicWidth(), labelTextViewFirst.getIntrinsicHeight()/2, mPaint); //下面的文字 canvas.drawBitmap(Utils.drawableToBitmap(labelTextViewSecond), labelViewWidth - originPic.getWidth() - labelLineViewSecond.getIntrinsicWidth() - labelTextViewSecond.getIntrinsicWidth(), labelViewHeight - labelTextViewSecond.getIntrinsicHeight(), mPaint); //下面的线条 canvas.drawBitmap(Utils.drawableToBitmap(labelLineViewSecond), labelViewWidth - originPic.getWidth() - labelLineViewSecond.getIntrinsicWidth(), labelTextViewFirst.getIntrinsicHeight() / 2 + labelLineViewFirst.getIntrinsicHeight(), mPaint); //画原点 int xBmp = labelViewWidth - originPic.getWidth(); int yBmp = (labelViewHeight - originPic.getWidth()) / 2; canvas.drawBitmap(originPic, xBmp, yBmp, null); Log.i(TAG, "onDrawFirst xBmp = " + xBmp + " yBmp = " + yBmp); }
第二种模式
/** * 绘制第二模式 * * @param canvas */ private void onDrawSecond(Canvas canvas) { Log.i(TAG, "onDrawSecond ---------"); //上面条线 canvas.drawBitmap(Utils.drawableToBitmap(labelLineViewFirst), originPic.getWidth(), labelTextViewFirst.getIntrinsicHeight()/2, mPaint); //上面文字 canvas.drawBitmap(Utils.drawableToBitmap(labelTextViewFirst), originPic.getWidth()+labelLineViewFirst.getIntrinsicWidth(), 0, mPaint); //下面线条 canvas.drawBitmap(Utils.drawableToBitmap(labelLineViewSecond), originPic.getWidth(), labelTextViewFirst.getIntrinsicHeight()/2+labelLineViewFirst.getIntrinsicHeight(), mPaint); //下面文字 canvas.drawBitmap(Utils.drawableToBitmap(labelTextViewSecond), originPic.getWidth()+labelLineViewSecond.getIntrinsicWidth(), labelViewHeight - labelTextViewSecond.getIntrinsicHeight(), mPaint); //画原点 int xBmp = 0; int yBmp = (labelViewHeight-originPic.getWidth())/2; canvas.drawBitmap(originPic, xBmp, yBmp, null); Log.i(TAG, "onDrawSecond xBmp = " + xBmp + " yBmp = " + yBmp); }
第二种模式
/** * 第三种绘制 */ private void onDrawThird(Canvas canvas){ Log.i(TAG, "onDrawSecond ---------"); //左边的文字 canvas.drawBitmap(Utils.drawableToBitmap(labelTextViewFirst), 0, 0, mPaint); //上面条线 canvas.drawBitmap(Utils.drawableToBitmap(labelLineViewFirst), labelTextViewFirst.getIntrinsicWidth(), labelTextViewFirst.getIntrinsicHeight()/2, mPaint); //画原点 int xBmp = labelTextViewFirst.getIntrinsicWidth()+labelLineViewFirst.getIntrinsicWidth(); int yBmp = (labelViewHeight-originPic.getHeight())/2; canvas.drawBitmap(originPic, xBmp, yBmp, null); Log.i(TAG, "onDrawSecond xBmp = " + xBmp + " yBmp = " + yBmp); //下面线条 canvas.drawBitmap(Utils.drawableToBitmap(labelLineViewSecond), labelTextViewFirst.getIntrinsicWidth()+labelLineViewFirst.getIntrinsicWidth()+originPic.getWidth(), labelViewHeight/2, mPaint); //下面文字 canvas.drawBitmap(Utils.drawableToBitmap(labelTextViewSecond), labelViewWidth - labelTextViewSecond.getIntrinsicWidth(), labelViewHeight - labelTextViewSecond.getIntrinsicHeight(), mPaint); }
第四种模式
/** * 第四种绘制 */ private void onDrawFourth(Canvas canvas){ Log.i(TAG, "onDrawFourth ---------"); //左边文字 canvas.drawBitmap(Utils.drawableToBitmap(labelTextViewFirst), 0, labelViewHeight-labelTextViewFirst.getIntrinsicHeight(), mPaint); //左边条线 canvas.drawBitmap(Utils.drawableToBitmap(labelLineViewFirst), labelTextViewFirst.getIntrinsicWidth(), labelViewHeight-labelTextViewFirst.getIntrinsicHeight()/2-labelLineViewFirst.getIntrinsicHeight(), mPaint); //画原点 int xBmp = labelTextViewFirst.getIntrinsicWidth()+labelLineViewFirst.getIntrinsicWidth(); int yBmp = (labelViewHeight-originPic.getWidth())/2; canvas.drawBitmap(originPic, xBmp, yBmp, null); Log.i(TAG, "onDrawSecond xBmp = " + xBmp + " yBmp = " + yBmp); //右边线条 canvas.drawBitmap(Utils.drawableToBitmap(labelLineViewSecond), labelTextViewFirst.getIntrinsicWidth()+labelLineViewFirst.getIntrinsicWidth()+originPic.getWidth(), labelTextViewSecond.getIntrinsicHeight()/2, mPaint); //右边文字 canvas.drawBitmap(Utils.drawableToBitmap(labelTextViewSecond), labelViewWidth-labelTextViewSecond.getIntrinsicWidth(), 0, mPaint); }
以上大致说了一下思路
这是代码链接
https://github.com/gyh/GCustomView
2 0
- 仿半塘图片添加标签功能
- <img>标签,添加图片
- 图片添加水印功能
- Java添加图片(标签)
- PHP添加图片水印功能
- fckeditor添加删除图片功能
- 图片添加文字水印功能
- 基于jquery 标签添加修改功能
- QTabWidget添加关闭子标签功能
- 环信更多功能添加标签
- a标签实现下载图片功能
- Ueditor上传图片添加a标签
- 为JPEG图片添加自定义标签(Android)
- Android图片添加标签:Android-PictureTagView
- Display标签功能扩展--添加列宽调整功能
- FCKeditor中添加删除图片的功能!
- [J2ME]为照相机添加图片保存功能
- FCKeditor中添加删除图片的功能!
- Hdu 1247 Hat’s Words
- CountDownLatch、CyclicBarrier和Semaphore区别
- 网上商城SSH各个类间的关系(二)
- java特种兵读书笔记(5-2)——并发之线程安全
- Null在Sass中的妙用
- 仿半塘图片添加标签功能
- 动态修改ListView
- 【Android基础学习】Android权限
- [self presentViewController:vc animated:YES completion:nil]的相互引用问题
- icare3.0程序中关于诊疗卡号长度的设置-------运维日志16
- Hbase笔记 - 快速安装(单机模式)
- 最简单的android弹出对话框
- linux下常用命令
- java最常用的设计模式之一外观模式