Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
门心叼龙
android-custom-view
提交
a9edaa04
A
android-custom-view
项目概览
门心叼龙
/
android-custom-view
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
android-custom-view
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
a9edaa04
编写于
10月 16, 2019
作者:
门心叼龙
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
code perfect
上级
1efaeee6
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
401 addition
and
15 deletion
+401
-15
.idea/codeStyles/Project.xml
.idea/codeStyles/Project.xml
+116
-0
app/src/main/AndroidManifest.xml
app/src/main/AndroidManifest.xml
+11
-15
app/src/main/java/com/mxdl/customview/MainActivity.java
app/src/main/java/com/mxdl/customview/MainActivity.java
+7
-0
app/src/main/java/com/mxdl/customview/RectCaptureViewActivity.java
...ain/java/com/mxdl/customview/RectCaptureViewActivity.java
+13
-0
app/src/main/java/com/mxdl/customview/view/RectCaptureView.java
...c/main/java/com/mxdl/customview/view/RectCaptureView.java
+238
-0
app/src/main/res/layout/activity_main.xml
app/src/main/res/layout/activity_main.xml
+7
-0
app/src/main/res/layout/activity_rect_capture_view.xml
app/src/main/res/layout/activity_rect_capture_view.xml
+9
-0
未找到文件。
.idea/codeStyles/Project.xml
0 → 100644
浏览文件 @
a9edaa04
<component
name=
"ProjectCodeStyleConfiguration"
>
<code_scheme
name=
"Project"
version=
"173"
>
<codeStyleSettings
language=
"XML"
>
<indentOptions>
<option
name=
"CONTINUATION_INDENT_SIZE"
value=
"4"
/>
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>
xmlns:android
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
^$
</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>
xmlns:.*
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
^$
</XML_NAMESPACE>
</AND>
</match>
<order>
BY_NAME
</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>
.*:id
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
http://schemas.android.com/apk/res/android
</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>
.*:name
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
http://schemas.android.com/apk/res/android
</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>
name
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
^$
</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>
style
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
^$
</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>
.*
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
^$
</XML_NAMESPACE>
</AND>
</match>
<order>
BY_NAME
</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>
.*
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
http://schemas.android.com/apk/res/android
</XML_NAMESPACE>
</AND>
</match>
<order>
ANDROID_ATTRIBUTE_ORDER
</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>
.*
</NAME>
<XML_ATTRIBUTE
/>
<XML_NAMESPACE>
.*
</XML_NAMESPACE>
</AND>
</match>
<order>
BY_NAME
</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
app/src/main/AndroidManifest.xml
浏览文件 @
a9edaa04
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"com.mxdl.customview"
>
package=
"com.mxdl.customview"
>
<application
android:name=
"com.mxdl.MyApplication"
...
...
@@ -10,25 +10,21 @@
android:roundIcon=
"@mipmap/ic_launcher_round"
android:supportsRtl=
"true"
android:theme=
"@style/AppTheme"
>
<activity
android:name=
".CricleCaptureViewActivity"
>
</activity>
<activity
android:name=
"com.mxdl.CaptureViewActivity1"
>
</activity>
<activity
android:name=
"com.mxdl.CaptureViewActivity"
>
</activity>
<activity
android:name=
".HorizontalScrollViewActivity"
>
</activity>
<activity
android:name=
".PinnedHeaderActivity"
>
</activity>
<activity
android:name=
".RectCaptureViewActivity"
></activity>
<activity
android:name=
".CricleCaptureViewActivity"
></activity>
<activity
android:name=
"com.mxdl.CaptureViewActivity1"
></activity>
<activity
android:name=
"com.mxdl.CaptureViewActivity"
></activity>
<activity
android:name=
".HorizontalScrollViewActivity"
></activity>
<activity
android:name=
".PinnedHeaderActivity"
></activity>
<activity
android:name=
".MainActivity"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
<activity
android:name=
".StickyLayoutActivity"
/>
<activity
android:name=
".HorizontalScrollViewExActivity"
/>
<activity
android:name=
".StickyLayoutActivity"
/>
<activity
android:name=
".HorizontalScrollViewExActivity"
/>
</application>
</manifest>
\ No newline at end of file
app/src/main/java/com/mxdl/customview/MainActivity.java
浏览文件 @
a9edaa04
...
...
@@ -25,6 +25,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private
Button
mBtnCaptrueView
;
private
Button
mBtnCaptrueView1
;
private
Button
mBtnCricleCapture
;
private
Button
mBtnRectCapture
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
...
...
@@ -38,6 +39,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
mBtnCaptrueView1
=
findViewById
(
R
.
id
.
btn_capture_view1
);
mBtnCricleCapture
=
findViewById
(
R
.
id
.
btn_cricle_capture
);
mBtnRectCapture
=
findViewById
(
R
.
id
.
btn_rect_capture
);
mBtnStickyLayout
.
setOnClickListener
(
this
);
mBtnHorizontalScrollViewEx
.
setOnClickListener
(
this
);
mBtnHorizontalScrollView
.
setOnClickListener
(
this
);
...
...
@@ -45,6 +48,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
mBtnCaptrueView
.
setOnClickListener
(
this
);
mBtnCaptrueView1
.
setOnClickListener
(
this
);
mBtnCricleCapture
.
setOnClickListener
(
this
);
mBtnRectCapture
.
setOnClickListener
(
this
);
}
@Override
...
...
@@ -71,6 +75,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
case
R
.
id
.
btn_cricle_capture
:
startActivity
(
new
Intent
(
this
,
CricleCaptureViewActivity
.
class
));
break
;
case
R
.
id
.
btn_rect_capture
:
startActivity
(
new
Intent
(
this
,
RectCaptureViewActivity
.
class
));
break
;
}
}
}
app/src/main/java/com/mxdl/customview/RectCaptureViewActivity.java
0 → 100644
浏览文件 @
a9edaa04
package
com.mxdl.customview
;
import
android.support.v7.app.AppCompatActivity
;
import
android.os.Bundle
;
public
class
RectCaptureViewActivity
extends
AppCompatActivity
{
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_rect_capture_view
);
}
}
app/src/main/java/com/mxdl/customview/view/RectCaptureView.java
0 → 100644
浏览文件 @
a9edaa04
package
com.mxdl.customview.view
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.graphics.Rect
;
import
android.graphics.RectF
;
import
android.graphics.Region
;
import
android.graphics.drawable.Drawable
;
import
android.os.Build
;
import
android.support.annotation.RequiresApi
;
import
android.util.AttributeSet
;
import
android.util.Log
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
com.mxdl.customview.R
;
/**
* Description: <RectCaptureView><br>
* Author: mxdl<br>
* Date: 2019/10/12<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public
class
RectCaptureView
extends
View
{
public
static
final
String
TAG
=
RectCaptureView
.
class
.
getSimpleName
();
private
int
mWidth
;
private
Rect
mScreenRect
=
new
Rect
();
private
Rect
mCaptureRect
=
new
Rect
();
private
Paint
mBorderPaint
=
new
Paint
();
private
Path
mCapturePath
=
new
Path
();
private
Paint
mAreaPaint
=
new
Paint
();
private
Drawable
mAnchorDrawable
;
private
int
mHalfAnchorWidth
;
private
int
mLastX
;
private
int
mLastY
;
private
int
mHitCorner
;
public
RectCaptureView
(
Context
context
)
{
super
(
context
);
initView
();
}
public
RectCaptureView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
initView
();
}
public
RectCaptureView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
initView
();
}
@RequiresApi
(
api
=
Build
.
VERSION_CODES
.
LOLLIPOP
)
public
RectCaptureView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
,
int
defStyleRes
)
{
super
(
context
,
attrs
,
defStyleAttr
,
defStyleRes
);
initView
();
}
public
void
initView
()
{
setLayerType
(
View
.
LAYER_TYPE_SOFTWARE
,
null
);
mWidth
=
(
int
)
(
getResources
().
getDisplayMetrics
().
density
*
216
+
0.5f
);
mBorderPaint
.
setStrokeWidth
(
getResources
().
getDisplayMetrics
().
density
*
2
);
mBorderPaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
mBorderPaint
.
setAntiAlias
(
true
);
mBorderPaint
.
setColor
(
Color
.
parseColor
(
"#1E88E5"
));
mAreaPaint
.
setStyle
(
Paint
.
Style
.
FILL_AND_STROKE
);
mAreaPaint
.
setColor
(
Color
.
parseColor
(
"#1E88E5"
));
mAreaPaint
.
setAlpha
(
20
);
mAnchorDrawable
=
getResources
().
getDrawable
(
R
.
mipmap
.
ic_edit_fence_dragger
);
mHalfAnchorWidth
=
mAnchorDrawable
.
getIntrinsicWidth
()
/
2
;
}
@Override
protected
void
onLayout
(
boolean
changed
,
int
left
,
int
top
,
int
right
,
int
bottom
)
{
super
.
onLayout
(
changed
,
left
,
top
,
right
,
bottom
);
Log
.
v
(
TAG
,
"onLayout"
);
mScreenRect
.
set
(
left
,
top
,
right
,
bottom
);
int
captureLeft
=
(
right
-
mWidth
)
/
2
;
int
captureTop
=
(
bottom
-
mWidth
)
/
2
;
int
captureRight
=
captureLeft
+
mWidth
;
int
captureBottom
=
captureTop
+
mWidth
;
mCaptureRect
.
set
(
captureLeft
,
captureTop
,
captureRight
,
captureBottom
);
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
super
.
onDraw
(
canvas
);
//Log.v(TAG,"onDraw left:"+mCaptureRect.left+";top:"+mCaptureRect.top+";right:"+mCaptureRect.right+";bottom:"+mCaptureRect.bottom);
canvas
.
save
();
//路径重新设置
mCapturePath
.
reset
();
//添加了一个当前的矩形区域
mCapturePath
.
addRect
(
new
RectF
(
mCaptureRect
),
Path
.
Direction
.
CW
);
//当前的画布与指定的路径相交
canvas
.
clipPath
(
mCapturePath
,
Region
.
Op
.
INTERSECT
);
//画矩形背景选区
canvas
.
drawRect
(
mScreenRect
,
mAreaPaint
);
//画矩形背景边框
canvas
.
drawPath
(
mCapturePath
,
mBorderPaint
);
canvas
.
restore
();
//画左上锚点
mAnchorDrawable
.
setBounds
(
mCaptureRect
.
left
-
mHalfAnchorWidth
,
mCaptureRect
.
top
-
mHalfAnchorWidth
,
mCaptureRect
.
left
+
mHalfAnchorWidth
,
mCaptureRect
.
top
+
mHalfAnchorWidth
);
mAnchorDrawable
.
draw
(
canvas
);
//画右上锚点
mAnchorDrawable
.
setBounds
(
mCaptureRect
.
right
-
mHalfAnchorWidth
,
mCaptureRect
.
top
-
mHalfAnchorWidth
,
mCaptureRect
.
right
+
mHalfAnchorWidth
,
mCaptureRect
.
top
+
mHalfAnchorWidth
);
mAnchorDrawable
.
draw
(
canvas
);
//画右下锚点
mAnchorDrawable
.
setBounds
(
mCaptureRect
.
right
-
mHalfAnchorWidth
,
mCaptureRect
.
bottom
-
mHalfAnchorWidth
,
mCaptureRect
.
right
+
mHalfAnchorWidth
,
mCaptureRect
.
bottom
+
mHalfAnchorWidth
);
mAnchorDrawable
.
draw
(
canvas
);
//画左下锚点
mAnchorDrawable
.
setBounds
(
mCaptureRect
.
left
-
mHalfAnchorWidth
,
mCaptureRect
.
bottom
-
mHalfAnchorWidth
,
mCaptureRect
.
left
+
mHalfAnchorWidth
,
mCaptureRect
.
bottom
+
mHalfAnchorWidth
);
mAnchorDrawable
.
draw
(
canvas
);
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
int
x
=
(
int
)
event
.
getX
();
int
y
=
(
int
)
event
.
getY
();
switch
(
event
.
getAction
())
{
case
MotionEvent
.
ACTION_DOWN
:
mHitCorner
=
getHitCorner
(
x
,
y
);
//Log.v(TAG, "ACTION_DOWN:mHitCorner" + mHitCorner);
//如果没有点击在锚点上,则直接返回false
if
(
mHitCorner
==
0
)
{
return
false
;
}
break
;
case
MotionEvent
.
ACTION_UP
:
mHitCorner
=
0
;
break
;
case
MotionEvent
.
ACTION_MOVE
:
if
(
mHitCorner
==
0
)
{
return
false
;
}
int
dx
=
x
-
mLastX
;
int
dy
=
y
-
mLastY
;
if
(
mHitCorner
==
7
)
{
mCaptureRect
.
left
+=
dx
;
mCaptureRect
.
top
+=
dy
;
//mCaptureRect.right -= dx;
//mCaptureRect.bottom -= dy;
}
else
if
(
mHitCorner
==
9
)
{
mCaptureRect
.
left
-=
dx
;
mCaptureRect
.
top
+=
dy
;
//mCaptureRect.right += dx;
//mCaptureRect.bottom -= dy;
}
else
if
(
mHitCorner
==
3
)
{
//mCaptureRect.left -= dx;
//mCaptureRect.top -= dy;
mCaptureRect
.
right
+=
dx
;
mCaptureRect
.
bottom
+=
dy
;
}
else
if
(
mHitCorner
==
1
)
{
mCaptureRect
.
left
+=
dx
;
//mCaptureRect.top -= dy;
//mCaptureRect.right -= dx;
mCaptureRect
.
bottom
+=
dy
;
}
//防止选取越界
int
screenWidth
=
mScreenRect
.
right
-
mScreenRect
.
left
;
int
screenHeight
=
mScreenRect
.
bottom
-
mScreenRect
.
top
;
int
maxWidth
=
screenWidth
-
mHalfAnchorWidth
*
2
;
if
(
mCaptureRect
.
left
<=
mHalfAnchorWidth
)
{
mCaptureRect
.
left
=
mHalfAnchorWidth
;
}
if
(
mCaptureRect
.
top
<=
mHalfAnchorWidth
)
{
mCaptureRect
.
top
=
mHalfAnchorWidth
;
}
if
(
mCaptureRect
.
right
>=
screenWidth
-
mHalfAnchorWidth
)
{
mCaptureRect
.
right
=
screenWidth
-
mHalfAnchorWidth
;
}
if
(
mCaptureRect
.
bottom
>=
screenHeight
-
mHalfAnchorWidth
)
{
mCaptureRect
.
bottom
=
screenHeight
-
mHalfAnchorWidth
;
}
if
(
mCaptureRect
.
left
>=
screenWidth
-
mHalfAnchorWidth
)
{
mCaptureRect
.
left
=
screenWidth
-
mHalfAnchorWidth
;
}
if
(
mCaptureRect
.
top
>=
screenHeight
-
mHalfAnchorWidth
)
{
mCaptureRect
.
top
=
screenHeight
-
mHalfAnchorWidth
;
}
if
(
mCaptureRect
.
right
<=
mHalfAnchorWidth
)
{
mCaptureRect
.
right
=
mHalfAnchorWidth
;
}
if
(
mCaptureRect
.
bottom
<=
mHalfAnchorWidth
)
{
mCaptureRect
.
bottom
=
mHalfAnchorWidth
;
}
boolean
square
=
true
;
if
(
Math
.
abs
(
mCaptureRect
.
right
-
mCaptureRect
.
left
)
!=
Math
.
abs
(
mCaptureRect
.
bottom
-
mCaptureRect
.
top
))
{
square
=
false
;
}
Log
.
v
(
TAG
,
"mHitCorner"
+
mHitCorner
+
";dx:"
+
dx
+
";dy:"
+
dy
+
";width:"
+
(
mCaptureRect
.
right
-
mCaptureRect
.
left
)
+
";height:"
+
(
mCaptureRect
.
bottom
-
mCaptureRect
.
top
)
+
";square:"
+
(
square
?
"ok"
:
"------------------"
));
break
;
}
mLastX
=
x
;
mLastY
=
y
;
invalidate
();
return
true
;
}
public
int
getHitCorner
(
float
x
,
float
y
)
{
int
result
=
0
;
if
(
y
>
mCaptureRect
.
top
-
mHalfAnchorWidth
*
2
&&
y
<
mCaptureRect
.
top
+
mHalfAnchorWidth
*
2
)
{
if
(
x
>
mCaptureRect
.
left
-
mHalfAnchorWidth
*
2
&&
x
<
mCaptureRect
.
left
+
mHalfAnchorWidth
*
2
)
{
result
=
7
;
}
else
if
(
x
>
mCaptureRect
.
right
-
mHalfAnchorWidth
*
2
&&
x
<
mCaptureRect
.
right
+
mHalfAnchorWidth
*
2
)
{
result
=
9
;
}
}
else
if
(
y
>
mCaptureRect
.
bottom
-
mHalfAnchorWidth
*
2
&&
y
<
mCaptureRect
.
bottom
+
mHalfAnchorWidth
*
2
)
{
if
(
x
>
mCaptureRect
.
left
-
mHalfAnchorWidth
*
2
&&
x
<
mCaptureRect
.
left
+
mHalfAnchorWidth
*
2
)
{
result
=
1
;
}
else
if
(
x
>
mCaptureRect
.
right
-
mHalfAnchorWidth
*
2
&&
x
<
mCaptureRect
.
right
+
mHalfAnchorWidth
*
2
)
{
result
=
3
;
}
}
return
result
;
}
}
app/src/main/res/layout/activity_main.xml
浏览文件 @
a9edaa04
...
...
@@ -56,5 +56,12 @@
android:text=
"CricleCaptureView"
android:textAllCaps=
"false"
/>
<Button
android:id=
"@+id/btn_rect_capture"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"RectCaptureView"
android:textAllCaps=
"false"
/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
app/src/main/res/layout/activity_rect_capture_view.xml
0 → 100644
浏览文件 @
a9edaa04
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<com.mxdl.customview.view.RectCaptureView
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
</RelativeLayout>
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录