版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android如何實現(xiàn)控件的縮放移動功能
這篇文章主要介紹了Android如何實現(xiàn)控件的縮放移動功能,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。需要的朋友點擊查看。1.簡介話不多說先來張效果圖
控件縮放移動.gif上面的gif中,依次進行了拖動——>觸摸右上角放大,縮小——>觸摸上方與右測邊緣——>雙指放大縮小。2使用步驟2.1布局。外層一個LinearLayout,里面一個自定義的控件DragScaleView,為了能夠更清楚的看到控件的變化過程,就給控件加了一個灰色帶虛線的邊框bg_dashgap。layout文件<?xml
version="1.0"
encoding="utf-8"?>
<LinearLayout
xmlns:android="/apk/res/android"
android:orientation="vertical"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80ce3d3a"
android:gravity="center_horizontal"
android:fitsSystemWindows="true">
<com.xxx.xxx.ui.DragScaleView
android:id="@+id/hair_dv"
android:src="@drawable/ic_sure"
android:background="@drawable/bg_dashgap"
android:adjustViewBounds="true"
android:layout_marginLeft="50dp"
android:layout_marginTop="10dp"
android:layout_width="100dp"
android:layout_height="120dp"
android:clickable="true"/>
</LinearLayout>在drawable文件夾下的bg_dashgap.xml<?xml
version="1.0"
encoding="utf-8"?>
<shape
xmlns:android="/apk/res/android"
>
<!--
圓角
-->
<corners
android:bottomLeftRadius="8dp"
android:bottomRightRadius="8dp"
android:radius="15dp"
android:topLeftRadius="8dp"
android:topRightRadius="8dp"
/>
<!--
描邊
-->
<stroke
android:dashGap="4dp"
android:dashWidth="4dp"
android:width="2dp"
android:color="@color/my_gery"
/>
</shape>2.2自定義的控件單指觸摸:當ACTION_DOWN時如果坐標為四個區(qū)域,則對View進行相應(yīng)的左上/右上/左下/右下拉伸;當ACTION_DOWN時如果坐標為四個區(qū)域,則分別對上/右/下/左四個方向進行拉伸;當ACTION_DOWN時如果坐標為9這個區(qū)域,則對View進行移動;
雙指觸摸:先計算出觸摸時雙指的距離,floatoriDist=distance(event);再得到雙指離開屏幕的距離,floatnewDist=distance(event);得到兩者之間的比例floatscale=newDist/oriDist;計算雙指間距離的方法/**
*
計算兩個手指間的距離
*
@param
event
觸摸事件
*
@return
放回兩個手指之間的距離
*/
private
float
distance(MotionEvent
event)
{
float
x
=
event.getX(0)
-
event.getX(1);
float
y
=
event.getY(0)
-
event.getY(1);
return
(float)
Math.sqrt(x
*
x
+
y
*
y);//兩點間距離公式
}自定義的控件onTouch(Viewv,MotionEventevent)的觸摸事件中代碼塊
image.png其他的關(guān)鍵地方,代碼中都有比較詳細的注釋了。思路就是觸摸監(jiān)聽判斷不同情況getDirection(v,(int)event.getX(),(int)event.getY())計算得到新的oriLeft,oriTop,oriRight,oriBottom重新繪制v.layout(oriLeft,oriTop,oriRight,oriBottom)3DragScaleView的完整代碼public
class
DragScaleView
extends
android.support.v7.widget.AppCompatImageView
implements
View.OnTouchListener
{
protected
int
screenWidth;
protected
int
screenHeight;
protected
int
lastX;
protected
int
lastY;
private
int
oriLeft;
private
int
oriRight;
private
int
oriTop;
private
int
oriBottom;
private
int
dragDirection;
private
static
final
int
TOP
=
0x15;
private
static
final
int
LEFT
=
0x16;
private
static
final
int
BOTTOM
=
0x17;
private
static
final
int
RIGHT
=
0x18;
private
static
final
int
LEFT_TOP
=
0x11;
private
static
final
int
RIGHT_TOP
=
0x12;
private
static
final
int
LEFT_BOTTOM
=
0x13;
private
static
final
int
RIGHT_BOTTOM
=
0x14;
private
static
final
int
TOUCH_TWO
=
0x21;
private
static
final
int
CENTER
=
0x19;
private
int
offset
=
0;
//可超出其父控件的偏移量
protected
Paint
paint
=
new
Paint();
private
static
final
int
touchDistance
=
80;
//觸摸邊界的有效距離
//
初始的兩個手指按下的觸摸點的距離
private
float
oriDis
=
1f;
/**
*
初始化獲取屏幕寬高
*/
protected
void
initScreenW_H()
{
screenHeight
=
getResources().getDisplayMetrics().heightPixels
-
40;
screenWidth
=
getResources().getDisplayMetrics().widthPixels;
}
public
DragScaleView(Context
context,
AttributeSet
attrs,
int
defStyle)
{
super(context,
attrs,
defStyle);
setOnTouchListener(this);
initScreenW_H();
}
public
DragScaleView(Context
context,
AttributeSet
attrs)
{
super(context,
attrs);
setOnTouchListener(this);
initScreenW_H();
}
public
DragScaleView(Context
context)
{
super(context);
setOnTouchListener(this);
initScreenW_H();
}
@Override
protected
void
onDraw(Canvas
canvas)
{
super.onDraw(canvas);
paint.setColor(Color.GRAY);
paint.setStrokeWidth(4.0f);
paint.setStyle(Paint.Style.STROKE);
}
@Override
public
boolean
onTouch(View
v,
MotionEvent
event)
{
setBackgroundResource(R.drawable.bg_dashgap);
int
action
=
event.getAction()&
MotionEvent.ACTION_MASK;
if
(action
==
MotionEvent.ACTION_DOWN)
{
oriLeft
=
v.getLeft();
oriRight
=
v.getRight();
oriTop
=
v.getTop();
oriBottom
=
v.getBottom();
lastY
=
(int)
event.getRawY();
lastX
=
(int)
event.getRawX();
dragDirection
=
getDirection(v,
(int)
event.getX(),
(int)
event.getY());
}
if
(action
==
MotionEvent.ACTION_POINTER_DOWN){
oriLeft
=
v.getLeft();
oriRight
=
v.getRight();
oriTop
=
v.getTop();
oriBottom
=
v.getBottom();
lastY
=
(int)
event.getRawY();
lastX
=
(int)
event.getRawX();
dragDirection
=
TOUCH_TWO;
oriDis
=
distance(event);
}
//
處理拖動事件
delDrag(v,
event,
action);
invalidate();
return
false;
}
/**
*
處理拖動事件
*
*
@param
v
*
@param
event
*
@param
action
*/
protected
void
delDrag(View
v,
MotionEvent
event,
int
action)
{
switch
(action)
{
case
MotionEvent.ACTION_MOVE:
int
dx
=
(int)
event.getRawX()
-
lastX;
int
dy
=
(int)
event.getRawY()
-
lastY;
switch
(dragDirection)
{
case
LEFT:
//
左邊緣
left(v,
dx);
break;
case
RIGHT:
//
右邊緣
right(v,
dx);
break;
case
BOTTOM:
//
下邊緣
bottom(v,
dy);
break;
case
TOP:
//
上邊緣
top(v,
dy);
break;
case
CENTER:
//
點擊中心-->>移動
center(v,
dx,
dy);
break;
case
LEFT_BOTTOM:
//
左下
left(v,
dx);
bottom(v,
dy);
break;
case
LEFT_TOP:
//
左上
left(v,
dx);
top(v,
dy);
break;
case
RIGHT_BOTTOM:
//
右下
right(v,
dx);
bottom(v,
dy);
break;
case
RIGHT_TOP:
//
右上
right(v,
dx);
top(v,
dy);
break;
case
TOUCH_TWO:
//雙指操控
float
newDist
=distance(event);
float
scale
=
newDist
/
oriDis;
//控制雙指縮放的敏感度
int
distX
=
(int)
(scale*(oriRight-oriLeft)-(oriRight-oriLeft))/50;
int
distY
=
(int)
(scale*(oriBottom-oriTop)-(oriBottom-oriTop))/50;
if
(newDist>10f){//當雙指的距離大于10時,開始相應(yīng)處理
left(v,
-distX);
top(v,
-distY);
right(v,
distX);
bottom(v,
distY);
}
break;
}
if
(dragDirection
!=
CENTER)
{
v.layout(oriLeft,
oriTop,
oriRight,
oriBottom);
}
lastX
=
(int)
event.getRawX();
lastY
=
(int)
event.getRawY();
break;
case
MotionEvent.ACTION_UP:
case
MotionEvent.ACTION_POINTER_UP:
dragDirection
=
0;
break;
}
}
/**
*
觸摸點為中心->>移動
*
*
@param
v
*
@param
dx
*
@param
dy
*/
private
void
center(View
v,
int
dx,
int
dy)
{
int
left
=
v.getLeft()
+
dx;
int
top
=
v.getTop()
+
dy;
int
right
=
v.getRight()
+
dx;
int
bottom
=
v.getBottom()
+
dy;
if
(left
<
-offset)
{
left
=
-offset;
right
=
left
+
v.getWidth();
}
if
(right
>
screenWidth
+
offset)
{
right
=
screenWidth
+
offset;
left
=
right
-
v.getWidth();
}
if
(top
<
-offset)
{
top
=
-offset;
bottom
=
top
+
v.getHeight();
}
if
(bottom
>
screenHeight
+
offset)
{
bottom
=
screenHeight
+
offset;
top
=
bottom
-
v.getHeight();
}
Log.d("raydrag",
left+"
"+top+"
"+right+"
"+bottom+"
"+dx);
v.layout(left,
top,
right,
bottom);
}
/**
*
觸摸點為上邊緣
*
*
@param
v
*
@param
dy
*/
private
void
top(View
v,
int
dy)
{
oriTop
+=
dy;
if
(oriTop
<
-offset)
{
//對view邊界的處理,如果子view達到父控件的邊界,offset代表允許超出父控件多少
oriTop
=
-offset;
}
if
(oriBottom
-
oriTop
-
2
*
offset
<
200)
{
oriTop
=
oriBottom
-
2
*
offset
-
200;
}
}
/**
*
觸摸點為下邊緣
*
*
@param
v
*
@param
dy
*/
private
void
bottom(View
v,
int
dy)
{
oriBottom
+=
dy;
if
(oriBottom
>
screenHeight
+
offset)
{
oriBottom
=
screenHeight
+
offset;
}
if
(oriBottom
-
oriTop
-
2
*
offset
<
200)
{
oriBottom
=
200
+
oriTop
+
2
*
offset;
}
}
/**
*
觸摸點為右邊緣
*
*
@param
v
*
@param
dx
*/
private
void
right(View
v,
int
dx)
{
oriRight
+=
dx;
if
(oriRight
>
screenWidth
+
offset)
{
oriRight
=
screenWidth
+
offset;
}
if
(oriRight
-
oriLeft
-
2
*
offset
<
200)
{
oriRight
=
oriLeft
+
2
*
offset
+
200;
}
}
/**
*
觸摸點為左邊緣
*
*
@param
v
*
@param
dx
*/
private
void
left(View
v,
int
dx)
{
oriLeft
+=
dx;
if
(oriLeft
<
-offset)
{
oriLeft
=
-offset;
}
if
(oriRight
-
oriLeft
-
2
*
offset
<
200)
{
oriLeft
=
oriRight
-
2
*
offset
-
200;
}
}
/**
*
獲取觸摸點flag
*
*
@param
v
*
@param
x
*
@param
y
*
@return
*/
protected
int
getDirection(View
v,
int
x,
int
y)
{
int
left
=
v.getLeft();
int
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 黑龍江省哈爾濱市2025-2026學年六年級上學期期中語文試題(含答案)(含解析)
- 2026年員工敬業(yè)度調(diào)研分析技巧
- 2026黑龍江哈爾濱啟航勞務(wù)派遣有限公司派遣到哈工大航天學院衛(wèi)星技術(shù)研究所招聘備考題庫及完整答案詳解1套
- 2026年農(nóng)村集體產(chǎn)權(quán)制度改革實務(wù)
- 機械設(shè)備液壓氣動系統(tǒng)檢修手冊
- 2026湖南長沙市長郡雨花外國語第二附屬小學春季合同制教師招聘備考題庫及答案詳解一套
- 2026年渠道經(jīng)銷商賦能管理培訓
- 2026年私人銀行財富規(guī)劃策略課程
- 職業(yè)共病管理的分級診療路徑優(yōu)化
- 2022年年春六年級下冊數(shù)學期末測試卷加答案下載
- dbj41河南省城市地下綜合管廊施工與驗收標準
- 2026屆新高考語文三輪沖刺復習:二元思辨作文審題構(gòu)思寫作
- 行業(yè)背景分析報告
- 2025中國農(nóng)業(yè)大學管理服務(wù)崗位(非事業(yè)編)招聘1人筆試備考試題附答案解析
- 2025福建省融資擔保有限責任公司招聘4人筆試試題附答案解析
- 工程管理費合同協(xié)議
- 協(xié)助審計協(xié)議書范本
- GB/T 13471-2025節(jié)能項目經(jīng)濟效益計算與評價方法
- 2025年小學一年級語文拼音測試試卷(含答案)
- 電力公司安全第一課課件
- 2025年征兵心理模擬測試試題及答案
評論
0/150
提交評論