Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
carrotech
doodle
提交
0759e26e
D
doodle
项目概览
carrotech
/
doodle
与 Fork 源项目一致
从无法访问的项目Fork
通知
5
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
doodle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0759e26e
编写于
9月 13, 2018
作者:
H
huangziwei
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Demo加入涂鸦原理教程代码
上级
cbbd2b51
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
621 addition
and
2 deletion
+621
-2
app/src/main/AndroidManifest.xml
app/src/main/AndroidManifest.xml
+1
-0
app/src/main/java/cn/hzw/doodledemo/MainActivity.java
app/src/main/java/cn/hzw/doodledemo/MainActivity.java
+9
-0
app/src/main/java/cn/hzw/doodledemo/guide/AdvancedDoodleView.java
...main/java/cn/hzw/doodledemo/guide/AdvancedDoodleView.java
+257
-0
app/src/main/java/cn/hzw/doodledemo/guide/DoodleGuideActivity.java
...ain/java/cn/hzw/doodledemo/guide/DoodleGuideActivity.java
+33
-0
app/src/main/java/cn/hzw/doodledemo/guide/MiddleDoodleView.java
...c/main/java/cn/hzw/doodledemo/guide/MiddleDoodleView.java
+147
-0
app/src/main/java/cn/hzw/doodledemo/guide/SimpleDoodleView.java
...c/main/java/cn/hzw/doodledemo/guide/SimpleDoodleView.java
+99
-0
app/src/main/res/layout/activity_guide.xml
app/src/main/res/layout/activity_guide.xml
+57
-0
app/src/main/res/layout/activity_main.xml
app/src/main/res/layout/activity_main.xml
+6
-0
app/src/main/res/values-en/strings.xml
app/src/main/res/values-en/strings.xml
+4
-0
app/src/main/res/values/strings.xml
app/src/main/res/values/strings.xml
+4
-0
doodle/src/main/java/cn/hzw/doodle/DoodleTouchDetector.java
doodle/src/main/java/cn/hzw/doodle/DoodleTouchDetector.java
+4
-2
未找到文件。
app/src/main/AndroidManifest.xml
浏览文件 @
0759e26e
...
...
@@ -17,6 +17,7 @@
</activity>
<activity
android:name=
".MosaicDemo"
/>
<activity
android:name=
".ScaleGestureItemDemo"
/>
<activity
android:name=
".guide.DoodleGuideActivity"
/>
</application>
</manifest>
\ No newline at end of file
app/src/main/java/cn/hzw/doodledemo/MainActivity.java
浏览文件 @
0759e26e
...
...
@@ -14,6 +14,7 @@ import cn.forward.androids.utils.LogUtil;
import
cn.hzw.doodle.DoodleActivity
;
import
cn.hzw.doodle.DoodleParams
;
import
cn.hzw.doodle.DoodleView
;
import
cn.hzw.doodledemo.guide.DoodleGuideActivity
;
import
cn.hzw.imageselector.ImageLoader
;
import
cn.hzw.imageselector.ImageSelectorActivity
;
...
...
@@ -34,6 +35,14 @@ public class MainActivity extends Activity {
ImageSelectorActivity
.
startActivityForResult
(
REQ_CODE_SELECT_IMAGE
,
MainActivity
.
this
,
null
,
false
);
}
});
findViewById
(
R
.
id
.
btn_guide
).
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
startActivity
(
new
Intent
(
getApplicationContext
(),
DoodleGuideActivity
.
class
));
}
});
findViewById
(
R
.
id
.
btn_mosaic
).
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
...
...
app/src/main/java/cn/hzw/doodledemo/guide/AdvancedDoodleView.java
0 → 100644
浏览文件 @
0759e26e
package
cn.hzw.doodledemo.guide
;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.graphics.RectF
;
import
android.util.Log
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
java.util.ArrayList
;
import
java.util.List
;
import
cn.forward.androids.ScaleGestureDetectorApi27
;
import
cn.forward.androids.TouchGestureDetector
;
/**
* 高级涂鸦
* 支持对图片涂鸦, 可移动缩放图片
* Created on 24/06/2018.
*/
public
class
AdvancedDoodleView
extends
View
{
private
final
static
String
TAG
=
"AdvancedDoodleView"
;
private
Paint
mPaint
=
new
Paint
();
private
List
<
PathItem
>
mPathList
=
new
ArrayList
<>();
// 保存涂鸦轨迹的集合
private
TouchGestureDetector
mTouchGestureDetector
;
// 触摸手势监听
private
float
mLastX
,
mLastY
;
private
PathItem
mCurrentPathItem
;
// 当前的涂鸦轨迹
private
PathItem
mSelectedPathItem
;
// 选中的涂鸦轨迹
private
Bitmap
mBitmap
;
private
float
mBitmapTransX
,
mBitmapTransY
,
mBitmapScale
=
1
;
public
AdvancedDoodleView
(
Context
context
,
Bitmap
bitmap
)
{
super
(
context
);
mBitmap
=
bitmap
;
// 设置画笔
mPaint
.
setColor
(
Color
.
RED
);
mPaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
mPaint
.
setStrokeWidth
(
20
);
mPaint
.
setAntiAlias
(
true
);
mPaint
.
setStrokeCap
(
Paint
.
Cap
.
ROUND
);
// 由手势识别器处理手势
mTouchGestureDetector
=
new
TouchGestureDetector
(
getContext
(),
new
TouchGestureDetector
.
OnTouchGestureListener
()
{
RectF
mRectF
=
new
RectF
();
// 缩放手势操作相关
Float
mLastFocusX
;
Float
mLastFocusY
;
float
mTouchCentreX
,
mTouchCentreY
;
@Override
public
boolean
onScaleBegin
(
ScaleGestureDetectorApi27
detector
)
{
Log
.
d
(
TAG
,
"onScaleBegin: "
);
mLastFocusX
=
null
;
mLastFocusY
=
null
;
return
true
;
}
@Override
public
void
onScaleEnd
(
ScaleGestureDetectorApi27
detector
)
{
Log
.
d
(
TAG
,
"onScaleEnd: "
);
}
@Override
public
boolean
onScale
(
ScaleGestureDetectorApi27
detector
)
{
// 双指缩放中
Log
.
d
(
TAG
,
"onScale: "
);
// 屏幕上的焦点
mTouchCentreX
=
detector
.
getFocusX
();
mTouchCentreY
=
detector
.
getFocusY
();
if
(
mLastFocusX
!=
null
&&
mLastFocusY
!=
null
)
{
// 焦点改变
float
dx
=
mTouchCentreX
-
mLastFocusX
;
float
dy
=
mTouchCentreY
-
mLastFocusY
;
// 移动图片
mBitmapTransX
=
mBitmapTransX
+
dx
;
mBitmapTransY
=
mBitmapTransY
+
dy
;
}
// 缩放图片
mBitmapScale
=
mBitmapScale
*
detector
.
getScaleFactor
();
if
(
mBitmapScale
<
0.1f
)
{
mBitmapScale
=
0.1f
;
}
invalidate
();
mLastFocusX
=
mTouchCentreX
;
mLastFocusY
=
mTouchCentreY
;
return
true
;
}
@Override
public
boolean
onSingleTapUp
(
MotionEvent
e
)
{
// 单击选中
float
x
=
toX
(
e
.
getX
()),
y
=
toY
(
e
.
getY
());
boolean
found
=
false
;
for
(
PathItem
path
:
mPathList
)
{
// 绘制涂鸦轨迹
path
.
mPath
.
computeBounds
(
mRectF
,
true
);
// 计算涂鸦轨迹的矩形范围
mRectF
.
offset
(
path
.
mX
,
path
.
mY
);
// 加上偏移
if
(
mRectF
.
contains
(
x
,
y
))
{
// 判断是否点中涂鸦轨迹的矩形范围内
found
=
true
;
mSelectedPathItem
=
path
;
break
;
}
}
if
(!
found
)
{
// 没有点中任何涂鸦
mSelectedPathItem
=
null
;
}
invalidate
();
return
true
;
}
@Override
public
void
onScrollBegin
(
MotionEvent
e
)
{
// 滑动开始
Log
.
d
(
TAG
,
"onScrollBegin: "
);
float
x
=
toX
(
e
.
getX
()),
y
=
toY
(
e
.
getY
());
if
(
mSelectedPathItem
==
null
)
{
mCurrentPathItem
=
new
PathItem
();
// 新的涂鸦
mPathList
.
add
(
mCurrentPathItem
);
// 添加的集合中
mCurrentPathItem
.
mPath
.
moveTo
(
x
,
y
);
}
mLastX
=
x
;
mLastY
=
y
;
invalidate
();
// 刷新
}
@Override
public
boolean
onScroll
(
MotionEvent
e1
,
MotionEvent
e2
,
float
distanceX
,
float
distanceY
)
{
// 滑动中
Log
.
d
(
TAG
,
"onScroll: "
+
e2
.
getX
()
+
" "
+
e2
.
getY
());
float
x
=
toX
(
e2
.
getX
()),
y
=
toY
(
e2
.
getY
());
if
(
mSelectedPathItem
==
null
)
{
// 没有选中的涂鸦
mCurrentPathItem
.
mPath
.
quadTo
(
mLastX
,
mLastY
,
(
x
+
mLastX
)
/
2
,
(
y
+
mLastY
)
/
2
);
// 使用贝塞尔曲线 让涂鸦轨迹更圆滑
}
else
{
// 移动选中的涂鸦
mSelectedPathItem
.
mX
=
mSelectedPathItem
.
mX
+
x
-
mLastX
;
mSelectedPathItem
.
mY
=
mSelectedPathItem
.
mY
+
y
-
mLastY
;
}
mLastX
=
x
;
mLastY
=
y
;
invalidate
();
// 刷新
return
true
;
}
@Override
public
void
onScrollEnd
(
MotionEvent
e
)
{
// 滑动结束
Log
.
d
(
TAG
,
"onScrollEnd: "
);
float
x
=
toX
(
e
.
getX
()),
y
=
toY
(
e
.
getY
());
if
(
mSelectedPathItem
==
null
)
{
mCurrentPathItem
.
mPath
.
quadTo
(
mLastX
,
mLastY
,
(
x
+
mLastX
)
/
2
,
(
y
+
mLastY
)
/
2
);
// 使用贝塞尔曲线 让涂鸦轨迹更圆滑
mCurrentPathItem
=
null
;
// 轨迹结束
}
invalidate
();
// 刷新
}
});
// 针对涂鸦的手势参数设置
// 下面两行绘画场景下应该设置间距为大于等于1,否则设为0双指缩放后抬起其中一个手指仍然可以移动
mTouchGestureDetector
.
setScaleSpanSlop
(
1
);
// 手势前识别为缩放手势的双指滑动最小距离值
mTouchGestureDetector
.
setScaleMinSpan
(
1
);
// 缩放过程中识别为缩放手势的双指最小距离值
mTouchGestureDetector
.
setIsLongpressEnabled
(
false
);
mTouchGestureDetector
.
setIsScrollAfterScaled
(
false
);
}
@Override
protected
void
onSizeChanged
(
int
width
,
int
height
,
int
oldw
,
int
oldh
)
{
//view绘制完成时 大小确定
super
.
onSizeChanged
(
width
,
height
,
oldw
,
oldh
);
int
w
=
mBitmap
.
getWidth
();
int
h
=
mBitmap
.
getHeight
();
float
nw
=
w
*
1
f
/
getWidth
();
float
nh
=
h
*
1
f
/
getHeight
();
float
centerWidth
,
centerHeight
;
// 1.计算使图片居中的缩放值
if
(
nw
>
nh
)
{
mBitmapScale
=
1
/
nw
;
centerWidth
=
getWidth
();
centerHeight
=
(
int
)
(
h
*
mBitmapScale
);
}
else
{
mBitmapScale
=
1
/
nh
;
centerWidth
=
(
int
)
(
w
*
mBitmapScale
);
centerHeight
=
getHeight
();
}
// 2.计算使图片居中的偏移值
mBitmapTransX
=
(
getWidth
()
-
centerWidth
)
/
2
f
;
mBitmapTransY
=
(
getHeight
()
-
centerHeight
)
/
2
f
;
invalidate
();
}
/**
* 将屏幕触摸坐标x转换成在图片中的坐标
*/
public
final
float
toX
(
float
touchX
)
{
return
(
touchX
-
mBitmapTransX
)
/
mBitmapScale
;
}
/**
* 将屏幕触摸坐标y转换成在图片中的坐标
*/
public
final
float
toY
(
float
touchY
)
{
return
(
touchY
-
mBitmapTransY
)
/
mBitmapScale
;
}
@Override
public
boolean
dispatchTouchEvent
(
MotionEvent
event
)
{
boolean
consumed
=
mTouchGestureDetector
.
onTouchEvent
(
event
);
// 由手势识别器处理手势
if
(!
consumed
)
{
return
super
.
dispatchTouchEvent
(
event
);
}
return
true
;
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
// 画布和图片共用一个坐标系,只需要处理屏幕坐标系到图片(画布)坐标系的映射关系(toX toY)
canvas
.
translate
(
mBitmapTransX
,
mBitmapTransY
);
canvas
.
scale
(
mBitmapScale
,
mBitmapScale
);
// 绘制图片
canvas
.
drawBitmap
(
mBitmap
,
0
,
0
,
null
);
for
(
PathItem
path
:
mPathList
)
{
// 绘制涂鸦轨迹
canvas
.
save
();
canvas
.
translate
(
path
.
mX
,
path
.
mY
);
// 根据涂鸦轨迹偏移值,偏移画布使其画在对应位置上
if
(
mSelectedPathItem
==
path
)
{
mPaint
.
setColor
(
Color
.
YELLOW
);
// 点中的为黄色
}
else
{
mPaint
.
setColor
(
Color
.
RED
);
// 其他为红色
}
canvas
.
drawPath
(
path
.
mPath
,
mPaint
);
canvas
.
restore
();
}
}
/**
* 封装涂鸦轨迹对象
*/
private
static
class
PathItem
{
Path
mPath
=
new
Path
();
// 涂鸦轨迹
float
mX
,
mY
;
// 轨迹偏移值
}
}
app/src/main/java/cn/hzw/doodledemo/guide/DoodleGuideActivity.java
0 → 100644
浏览文件 @
0759e26e
package
cn.hzw.doodledemo.guide
;
import
android.app.Activity
;
import
android.graphics.BitmapFactory
;
import
android.os.Bundle
;
import
android.view.ViewGroup
;
import
cn.hzw.doodledemo.R
;
public
class
DoodleGuideActivity
extends
Activity
{
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_guide
);
// 简单涂鸦
ViewGroup
simpleContainer
=
findViewById
(
R
.
id
.
container_simple_doodle
);
SimpleDoodleView
simpleDoodleView
=
new
SimpleDoodleView
(
this
);
simpleContainer
.
addView
(
simpleDoodleView
,
new
ViewGroup
.
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
MATCH_PARENT
));
// 中级涂鸦
ViewGroup
middleContainer
=
findViewById
(
R
.
id
.
container_middle_doodle
);
MiddleDoodleView
middleDoodleView
=
new
MiddleDoodleView
(
this
);
middleContainer
.
addView
(
middleDoodleView
,
new
ViewGroup
.
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
MATCH_PARENT
));
// 中级涂鸦
ViewGroup
advancedContainer
=
findViewById
(
R
.
id
.
container_advanced_doodle
);
AdvancedDoodleView
advancedDoodleView
=
new
AdvancedDoodleView
(
this
,
BitmapFactory
.
decodeResource
(
getResources
(),
R
.
drawable
.
thelittleprince2
));
advancedContainer
.
addView
(
advancedDoodleView
,
new
ViewGroup
.
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
MATCH_PARENT
));
}
}
app/src/main/java/cn/hzw/doodledemo/guide/MiddleDoodleView.java
0 → 100644
浏览文件 @
0759e26e
package
cn.hzw.doodledemo.guide
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.graphics.RectF
;
import
android.util.Log
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
java.util.ArrayList
;
import
java.util.List
;
import
cn.forward.androids.TouchGestureDetector
;
/**
* 中级涂鸦
* 单击时可以选择某个涂鸦,进行移动
* Created on 24/06/2018.
*/
public
class
MiddleDoodleView
extends
View
{
private
final
static
String
TAG
=
"MiddleDoodleView"
;
private
Paint
mPaint
=
new
Paint
();
private
List
<
PathItem
>
mPathList
=
new
ArrayList
<>();
// 保存涂鸦轨迹的集合
private
TouchGestureDetector
mTouchGestureDetector
;
// 触摸手势监听
private
float
mLastX
,
mLastY
;
private
PathItem
mCurrentPathItem
;
// 当前的涂鸦轨迹
private
PathItem
mSelectedPathItem
;
// 选中的涂鸦轨迹
public
MiddleDoodleView
(
Context
context
)
{
super
(
context
);
// 设置画笔
mPaint
.
setColor
(
Color
.
RED
);
mPaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
mPaint
.
setStrokeWidth
(
20
);
mPaint
.
setAntiAlias
(
true
);
mPaint
.
setStrokeCap
(
Paint
.
Cap
.
ROUND
);
// 由手势识别器处理手势
mTouchGestureDetector
=
new
TouchGestureDetector
(
getContext
(),
new
TouchGestureDetector
.
OnTouchGestureListener
()
{
RectF
mRectF
=
new
RectF
();
@Override
public
boolean
onSingleTapUp
(
MotionEvent
e
)
{
// 单击选中
boolean
found
=
false
;
for
(
PathItem
path
:
mPathList
)
{
// 绘制涂鸦轨迹
path
.
mPath
.
computeBounds
(
mRectF
,
true
);
// 计算涂鸦轨迹的矩形范围
mRectF
.
offset
(
path
.
mX
,
path
.
mY
);
// 加上偏移
if
(
mRectF
.
contains
(
e
.
getX
(),
e
.
getY
()))
{
// 判断是否点中涂鸦轨迹的矩形范围内
found
=
true
;
mSelectedPathItem
=
path
;
break
;
}
}
if
(!
found
)
{
// 没有点中任何涂鸦
mSelectedPathItem
=
null
;
}
invalidate
();
return
true
;
}
@Override
public
void
onScrollBegin
(
MotionEvent
e
)
{
// 滑动开始
Log
.
d
(
TAG
,
"onScrollBegin: "
);
if
(
mSelectedPathItem
==
null
)
{
mCurrentPathItem
=
new
PathItem
();
// 新的涂鸦
mPathList
.
add
(
mCurrentPathItem
);
// 添加的集合中
mCurrentPathItem
.
mPath
.
moveTo
(
e
.
getX
(),
e
.
getY
());
mLastX
=
e
.
getX
();
mLastY
=
e
.
getY
();
}
invalidate
();
// 刷新
}
@Override
public
boolean
onScroll
(
MotionEvent
e1
,
MotionEvent
e2
,
float
distanceX
,
float
distanceY
)
{
// 滑动中
Log
.
d
(
TAG
,
"onScroll: "
+
e2
.
getX
()
+
" "
+
e2
.
getY
());
if
(
mSelectedPathItem
==
null
)
{
// 没有选中的涂鸦
mCurrentPathItem
.
mPath
.
quadTo
(
mLastX
,
mLastY
,
(
e2
.
getX
()
+
mLastX
)
/
2
,
(
e2
.
getY
()
+
mLastY
)
/
2
);
// 使用贝塞尔曲线 让涂鸦轨迹更圆滑
mLastX
=
e2
.
getX
();
mLastY
=
e2
.
getY
();
}
else
{
// 移动选中的涂鸦
mSelectedPathItem
.
mX
=
mSelectedPathItem
.
mX
-
distanceX
;
mSelectedPathItem
.
mY
=
mSelectedPathItem
.
mY
-
distanceY
;
}
invalidate
();
// 刷新
return
true
;
}
@Override
public
void
onScrollEnd
(
MotionEvent
e
)
{
// 滑动结束
Log
.
d
(
TAG
,
"onScrollEnd: "
);
if
(
mSelectedPathItem
==
null
)
{
mCurrentPathItem
.
mPath
.
quadTo
(
mLastX
,
mLastY
,
(
e
.
getX
()
+
mLastX
)
/
2
,
(
e
.
getY
()
+
mLastY
)
/
2
);
// 使用贝塞尔曲线 让涂鸦轨迹更圆滑
mCurrentPathItem
=
null
;
// 轨迹结束
}
invalidate
();
// 刷新
}
});
}
@Override
public
boolean
dispatchTouchEvent
(
MotionEvent
event
)
{
boolean
consumed
=
mTouchGestureDetector
.
onTouchEvent
(
event
);
// 由手势识别器处理手势
if
(!
consumed
)
{
return
super
.
dispatchTouchEvent
(
event
);
}
return
true
;
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
for
(
PathItem
path
:
mPathList
)
{
// 绘制涂鸦轨迹
canvas
.
save
();
canvas
.
translate
(
path
.
mX
,
path
.
mY
);
// 根据涂鸦轨迹偏移值,偏移画布使其画在对应位置上
if
(
mSelectedPathItem
==
path
)
{
mPaint
.
setColor
(
Color
.
YELLOW
);
// 点中的为黄色
}
else
{
mPaint
.
setColor
(
Color
.
RED
);
// 其他为红色
}
canvas
.
drawPath
(
path
.
mPath
,
mPaint
);
canvas
.
restore
();
}
}
/**
* 封装涂鸦轨迹对象
*/
private
static
class
PathItem
{
Path
mPath
=
new
Path
();
// 涂鸦轨迹
float
mX
,
mY
;
// 轨迹偏移值
}
}
app/src/main/java/cn/hzw/doodledemo/guide/SimpleDoodleView.java
0 → 100644
浏览文件 @
0759e26e
package
cn.hzw.doodledemo.guide
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.util.Log
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
java.util.ArrayList
;
import
java.util.List
;
import
cn.forward.androids.TouchGestureDetector
;
/**
* 初级涂鸦
* 没有图片 仅支持 手绘
* Created on 24/06/2018.
*/
public
class
SimpleDoodleView
extends
View
{
private
final
static
String
TAG
=
"SimpleDoodleView"
;
private
Paint
mPaint
=
new
Paint
();
private
List
<
Path
>
mPathList
=
new
ArrayList
<>();
// 保存涂鸦轨迹的集合
private
TouchGestureDetector
mTouchGestureDetector
;
// 触摸手势监听
private
float
mLastX
,
mLastY
;
private
Path
mCurrentPath
;
// 当前的涂鸦轨迹
public
SimpleDoodleView
(
Context
context
)
{
super
(
context
);
// 设置画笔
mPaint
.
setColor
(
Color
.
RED
);
mPaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
mPaint
.
setStrokeWidth
(
20
);
mPaint
.
setAntiAlias
(
true
);
mPaint
.
setStrokeCap
(
Paint
.
Cap
.
ROUND
);
// 由手势识别器处理手势
mTouchGestureDetector
=
new
TouchGestureDetector
(
getContext
(),
new
TouchGestureDetector
.
OnTouchGestureListener
()
{
@Override
public
void
onScrollBegin
(
MotionEvent
e
)
{
// 滑动开始
Log
.
d
(
TAG
,
"onScrollBegin: "
);
mCurrentPath
=
new
Path
();
// 新的涂鸦
mPathList
.
add
(
mCurrentPath
);
// 添加的集合中
mCurrentPath
.
moveTo
(
e
.
getX
(),
e
.
getY
());
mLastX
=
e
.
getX
();
mLastY
=
e
.
getY
();
invalidate
();
// 刷新
}
@Override
public
boolean
onScroll
(
MotionEvent
e1
,
MotionEvent
e2
,
float
distanceX
,
float
distanceY
)
{
// 滑动中
Log
.
d
(
TAG
,
"onScroll: "
+
e2
.
getX
()
+
" "
+
e2
.
getY
());
mCurrentPath
.
quadTo
(
mLastX
,
mLastY
,
(
e2
.
getX
()
+
mLastX
)
/
2
,
(
e2
.
getY
()
+
mLastY
)
/
2
);
// 使用贝塞尔曲线 让涂鸦轨迹更圆滑
mLastX
=
e2
.
getX
();
mLastY
=
e2
.
getY
();
invalidate
();
// 刷新
return
true
;
}
@Override
public
void
onScrollEnd
(
MotionEvent
e
)
{
// 滑动结束
Log
.
d
(
TAG
,
"onScrollEnd: "
);
mCurrentPath
.
quadTo
(
mLastX
,
mLastY
,
(
e
.
getX
()
+
mLastX
)
/
2
,
(
e
.
getY
()
+
mLastY
)
/
2
);
// 使用贝塞尔曲线 让涂鸦轨迹更圆滑
mCurrentPath
=
null
;
// 轨迹结束
invalidate
();
// 刷新
}
});
}
@Override
public
boolean
dispatchTouchEvent
(
MotionEvent
event
)
{
boolean
consumed
=
mTouchGestureDetector
.
onTouchEvent
(
event
);
// 由手势识别器处理手势
if
(!
consumed
)
{
return
super
.
dispatchTouchEvent
(
event
);
}
return
true
;
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
for
(
Path
path
:
mPathList
)
{
// 绘制涂鸦轨迹
canvas
.
drawPath
(
path
,
mPaint
);
}
}
}
app/src/main/res/layout/activity_guide.xml
0 → 100644
浏览文件 @
0759e26e
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
>
<FrameLayout
android:id=
"@+id/container_simple_doodle"
android:layout_width=
"match_parent"
android:layout_height=
"0dp"
android:layout_weight=
"1"
android:background=
"#9BCD9B"
>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_horizontal"
android:layout_marginTop=
"5dp"
android:text=
"@string/simple_doodle"
android:textColor=
"#FFF"
android:textSize=
"12dp"
/>
</FrameLayout>
<FrameLayout
android:id=
"@+id/container_middle_doodle"
android:layout_width=
"match_parent"
android:layout_height=
"0dp"
android:layout_weight=
"1.5"
android:background=
"#9AC0CD"
>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_horizontal"
android:layout_marginTop=
"5dp"
android:text=
"@string/middle_doodle"
android:textColor=
"#FFF"
android:textSize=
"12dp"
/>
</FrameLayout>
<FrameLayout
android:id=
"@+id/container_advanced_doodle"
android:layout_width=
"match_parent"
android:layout_height=
"0dp"
android:layout_weight=
"2"
android:background=
"#8B7765"
>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_horizontal"
android:layout_marginTop=
"5dp"
android:text=
"@string/advanced_doodle"
android:textColor=
"#FFF"
android:textSize=
"12dp"
/>
</FrameLayout>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/activity_main.xml
浏览文件 @
0759e26e
...
...
@@ -75,6 +75,12 @@
android:layout_alignParentBottom=
"true"
android:orientation=
"horizontal"
>
<Button
android:id=
"@+id/btn_guide"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"@string/guide"
/>
<Button
android:id=
"@+id/btn_mosaic"
android:layout_width=
"wrap_content"
...
...
app/src/main/res/values-en/strings.xml
浏览文件 @
0759e26e
...
...
@@ -2,4 +2,8 @@
<string
name=
"app_name"
>
Doodle
</string>
<string
name=
"mosaic"
>
Mosaic
</string>
<string
name=
"scale_gesture_item"
>
Scale gesture
</string>
<string
name=
"guide"
>
Doodle Guide
</string>
<string
name=
"simple_doodle"
>
Simple doodle
</string>
<string
name=
"middle_doodle"
>
Middle doodle
</string>
<string
name=
"advanced_doodle"
>
Advanced doodle
</string>
</resources>
app/src/main/res/values/strings.xml
浏览文件 @
0759e26e
...
...
@@ -2,4 +2,8 @@
<string
name=
"app_name"
>
Doodle
</string>
<string
name=
"mosaic"
>
马赛克
</string>
<string
name=
"scale_gesture_item"
>
手势缩放
</string>
<string
name=
"guide"
>
涂鸦入门
</string>
<string
name=
"simple_doodle"
>
初级涂鸦
</string>
<string
name=
"middle_doodle"
>
中级级涂鸦
</string>
<string
name=
"advanced_doodle"
>
高级级涂鸦
</string>
</resources>
doodle/src/main/java/cn/hzw/doodle/DoodleTouchDetector.java
浏览文件 @
0759e26e
...
...
@@ -8,8 +8,10 @@ import cn.hzw.doodle.core.IDoodleTouchDetector;
public
class
DoodleTouchDetector
extends
TouchGestureDetector
implements
IDoodleTouchDetector
{
public
DoodleTouchDetector
(
Context
context
,
IOnTouchGestureListener
listener
)
{
super
(
context
,
listener
);
this
.
setScaleSpanSlop
(
1
);
this
.
setScaleMinSpan
(
1
);
// 下面两行绘画场景下应该设置间距为大于等于1,否则设为0双指缩放后抬起其中一个手指仍然可以移动
this
.
setScaleSpanSlop
(
1
);
// 手势前识别为缩放手势的双指滑动最小距离值
this
.
setScaleMinSpan
(
1
);
// 缩放过程中识别为缩放手势的双指最小距离值
this
.
setIsLongpressEnabled
(
false
);
this
.
setIsScrollAfterScaled
(
false
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录