您的位置:首页 > 其它

仿半塘图片添加标签功能

2016-02-02 11:51 232 查看
模仿半塘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, labelTextHe
4000
ight);
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  半塘 标签 动画 图片