吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

鴻蒙系統的手勢操控組件代碼現已開源

OpenHarmony技術社區 ? 來源:鴻蒙技術社區 ? 作者:朱偉ISRC ? 2021-06-24 18:16 ? 次閱讀

基于安卓平臺的手勢操控組件 PinchImageView-ohos,實現鴻蒙的功能化遷移和重構。代碼已經開源,歡迎各位開發者提出寶貴意見。

開源地址:

https://gitee.com/isrc_ohos/pinch-image-view-ohos

PinchImageView-ohos 是一個支持多點觸控的 ImageView 手勢操控組件,通過識別單指雙擊、雙指捏合、單指滑動等手勢指令,實現圖片的放大、縮小、滑動等效果。

該組件功能豐富且使用簡單,被廣泛應用于各類圖片預覽類應用。

01

組件效果展示

①雙指相向或相對捏合,實現圖片的縮放變化。

②單指雙擊實現圖片的放大縮小。

③單指雙擊后單指移動,實現圖片的放大后平移。

02

Sample 解析

Sample 部分主要負責整體顯示布局的搭建。首先為 PinchImageView-ohos 組件設置顯示圖片,然后將組件對象添加到顯示布局中。

下面將詳細介紹組件的使用方法:

步驟 1:創建整體的顯示布局。

步驟 2:導入相關類并實例化 PinchImageView-ohos 組件對象。

步驟 3:設置顯示圖片。

步驟 4:將 PinchImageView-ohos 組件對象添加到整體顯示布局中。

//步驟1 創建整體的顯示布局

DirectionalLayout directionalLayout = new DirectionalLayout(this);

//步驟2 導入相關類并實例化對象

PinchImageViewnew pinchImageView = new PinchImageViewnew(this);

//步驟3 設置顯示圖片

pinchImageView.setPixelMap(this, ResourceTable.Media_1111);

//步驟4 將pinchImageView添加到整體顯示布局中

directionalLayout.addComponent(pinchImageView);

setUIContent(directionalLayout);

03

Library 解析

Library 主要為 PinchImageView-ohos 組件實現手勢獲取功能和圖片操控功能。

開發者通過設置監聽器來捕捉各類手勢,根據不同的手勢執行不同的圖片操控方法,從而顯示不同的圖片操控效果,如放大、縮小、移動。

①手勢獲取方法

手勢獲取對實現 PinchImageView-ohos 組件的功能尤為重要,此處主要通過 onTouchEvent() 方法來捕捉對應的手勢。

主要用到的手勢包含:

PRIMARY_POINT_UP(最后一根手指從屏幕上抬起)

PRIMARY_POINT_DOWN(第一根手指觸摸屏幕)

OTHER_POINT_DOWN(當一根或多根手指已經觸摸屏幕時,另一個手指觸摸屏幕 )

OTHER_POINT_UP(一些手指從屏幕上抬起,而一些手指仍留在屏幕上 )

POINT_MOVE(手指在屏幕上移動)

通過監控各類手勢的操作順序和觸碰時間等條件,達到識別捏合、滑動、單擊、雙擊等復雜手勢的效果。

onTouchEvent() 函數首先通過 TouchEvent.getAction() 方法獲取當前的手勢,當手勢為:

(1)PRIMARY_POINT_UP

需要判斷圖片之前是否處于縮放模式(此時圖片處于縮放狀態)。如果是縮放模式,則觸發結束縮放動畫,后將手勢狀態置于自由模式。

//最后一個點抬起或者取消,結束所有模式if (action == TouchEvent.PRIMARY_POINT_UP || action == TouchEvent.CANCEL) {

//如果之前是縮放模式,還需要結束縮放動畫

if (mPinchMode == PINCH_MODE_SCALE) {

scaleEnd();//縮放結束

}

//手勢狀態置于自由模式

mPinchMode = PINCH_MODE_FREE;

}

(2)PRIMARY_POINT_DOWN

需要判斷圖片是否在縮放動畫中,若不在,圖片將切換到滾動模式(此時圖片處于可自由移動狀態),并保存觸發點的位置,用于(5)中的計算。

else if (action == TouchEvent.PRIMARY_POINT_DOWN) {

//在縮放動畫過程中不允許啟動滾動模式

if (?。╩ScaleAnimator != null && mScaleAnimator.isRunning())) {

//在動畫過程中不允許啟動滾動模式,停止所有動畫

cancelAllAnimator();

//切換到滾動模式

mPinchMode = PINCH_MODE_SCROLL;

//保存觸發點的位置用于(5)中的計算

mLastMovePoint.modify(event.getPointerPosition(0).getX(), event.getPointerPosition(0).getY());

}

}

(3)OTHER_POINT_DOWN

需要將圖片模式切換到縮放模式,并保存兩個觸發點的位置,用于(5)中的計算。

else if (action == TouchEvent.OTHER_POINT_DOWN) {

//在動畫過程中不允許啟動縮放模式,停止所有動畫

cancelAllAnimator();

//切換到縮放模式

mPinchMode = PINCH_MODE_SCALE;

//保存縮放的兩個觸發點的位置,用于(5)中的計算

saveScaleContext(event.getPointerPosition(0).getX(), event.getPointerPosition(0).getY(), event.getPointerPosition(1).getX(), event.getPointerPosition(1).getY());

}

(4)OTHER_POINT_UP

需要判斷手指抬起后圖片是否處于縮放模式。如果處于縮放模式下,判斷識別到的手指是否超過兩個。

在剩余手指超過兩個(縮放模式未結束)的情況下,第一個觸摸的手指抬起,那么讓第二個觸摸的手指和第三個觸摸的手指所在的點作為縮放控制點。

在剩余手指超過兩個(縮放模式未結束)的情況下,第二個觸摸的手指抬起,那么讓第一個觸摸的手指和第三個觸摸的手指所在的點作為縮放控制點。

如果處于縮放模式下,判斷識別到的手指只有一個。此時不能允許它切換到滾動模式,因為圖片可能沒有在初始的位置上。

手指抬起后圖片未處于縮放模式時(屏幕上僅剩余一個手指),開啟滾動模式,并記錄開始滾動的點。

else if (action == TouchEvent.OTHER_POINT_UP) {

//多個手指情況下抬起一個手指,此時需要是縮放模式才觸發

if (mPinchMode == PINCH_MODE_SCALE) {

//抬起的點如果大于2,那么縮放模式還有效,但是有可能初始點變了,重新測量初始點

if (event.getPointerCount() 》 2) {

//如果還沒結束縮放模式,但是第一個點抬起了,那么讓第二個點和第三個點作為縮放控制點

if (event.getAction() 》》 8 == 0) {

event.getPointerPosition(1).getX();

saveScaleContext(event.getPointerPosition(1).getX(), event.getPointerPosition(1).getY(), event.getPointerPosition(2).getX(), event.getPointerPosition(2).getY());

//如果還沒結束縮放模式,但是第二個點抬起了,那么讓第一個點和第三個點作為縮放控制點

} else if (event.getAction() 》》 8 == 1) {

saveScaleContext(event.getPointerPosition(0).getX(), event.getPointerPosition(0).getY(), event.getPointerPosition(2).getX(), event.getPointerPosition(2).getY());

}

}

//如果抬起的點等于2,那么此時只剩下一個點,也不允許進入單指模式,因為此時可能圖片沒有在正確的位置上

}

}

(5)POINT_MOVE

需要判斷當前圖片的模式。當為滾動模式時,執行 scrollBy() 方法來實現圖片的移動效果;當它為縮放模式時,計算兩個縮放點的距離和縮放點的中心,并執行 scale() 方法實現圖片的縮放效果。

scrollBy() 方法和 scale() 方法的具體邏輯在圖片操控方法中有詳細介紹,此處就不做過多贅述。

else if (action == TouchEvent.POINT_MOVE) {

if (?。╩ScaleAnimator != null && mScaleAnimator.isRunning())) {

//在滾動模式下移動

if (mPinchMode == PINCH_MODE_SCROLL) {

//每次移動產生一個差值累積到圖片位置上

scrollBy(event.getPointerPosition(0).getX() - mLastMovePoint.position[0], event.getPointerPosition(0).getY() - mLastMovePoint.position[1]);

//記錄新的移動點

mLastMovePoint.modify(event.getPointerPosition(0).getX(), event.getPointerPosition(0).getY());

//在縮放模式下移動

} else if (mPinchMode == PINCH_MODE_SCALE && event.getPointerCount() 》 1) {

//兩個縮放點間的距離

float distance = MathUtils.getDistance(event.getPointerPosition(0).getX(), event.getPointerPosition(0).getY(), event.getPointerPosition(1).getX(), event.getPointerPosition(1).getY());

//保存縮放點中心

float[] lineCenter = MathUtils.getCenterPoint(event.getPointerPosition(0).getX(), event.getPointerPosition(0).getY(), event.getPointerPosition(1).getX(), event.getPointerPosition(1).getY());

mLastMovePoint.modify(lineCenter[0], lineCenter[1]);

//處理縮放

scale(mScaleCenter, mScaleBase, distance, mLastMovePoint);

}

}

}

②圖片操控方法

1、圖片縮放

雙指捏合:顧名思義是表示兩根手指向相反方向移動的操作,該操作可實現圖片放大縮小的效果。雙指捏合完成圖片縮放的功能是由 scale() 方法實現的。

在 scale() 方法體中需要設置各種縮放參數:scaleBase 是縮放系數、scaleCenter 代表圖片縮放中點、distance 指兩指間距離、lineCenter 是兩指中點。

scaleBase 和 distance 相乘會得到縮放比例,圖片依舊縮放比例進行變化。

在縮放過程中,圖片縮放中點 scaleCenter 會跟隨兩指中點 lineCenter 移動,實現以兩指中點為中心對圖片進行放大縮小的效果,縮放效果如圖 4 所示。圖 4:圖片雙指縮放

private void scale(Point scaleCenter, float scaleBase, float distance, Point lineCenter) {

if (!isReady()) {

return;

}

//計算圖片從fit center狀態到目標狀態的縮放比例

float scale = scaleBase * distance;

Matrix matrix = MathUtils.matrixTake();

//按照圖片縮放中心縮放,并且讓縮放中心在縮放點中點上

matrix.postScale(scale, scale, scaleCenter.position[0], scaleCenter.position[1]);

//讓圖片的縮放中點跟隨手指縮放中點

matrix.postTranslate(lineCenter.position[0] - scaleCenter.position[0], lineCenter.position[1] - scaleCenter.position[1]);

//應用變換

mOuterMatrix.setMatrix(matrix);

MathUtils.matrixGiven(matrix);

dispatchOuterMatrixChanged();

//重繪

invalidate();

}

單指雙擊:表示用單根手指雙擊屏幕的操作,該操作可實現圖片放大縮小的效果,單指雙擊完成圖片縮放的功能是由 doubleTap() 方法實現的。

在 doubleTap() 方法體中我們初始化了一個縮放動畫的對象 mScaleAnimator(),它有兩個參數分別為 mOuterMatrix(開始矩陣)和 animEnd(結束矩陣)。

開始矩陣表示圖片原來的位置與大小;結束矩陣表示圖片縮放后的位置與大小,是根據放大比例和雙擊點位置確定的。

確定圖片的開始和結束矩陣后,啟動縮放動畫,便可以實現縮放效果,如圖 5 所示:

private void doubleTap(float x, float y) {

...

//開始計算縮放動畫的結果矩陣

Matrix animEnd = MathUtils.matrixTake(mOuterMatrix);

//計算還需縮放的倍數

animEnd.postScale(nextScale / currentScale, nextScale / currentScale, x, y);

//將放大點移動到控件中心

animEnd.postTranslate(displayWidth / 2f - x, displayHeight / 2f - y);

RectFloat testBound = MathUtils.rectFTake(0,0,mp.getImageInfo().size.width,mp.getImageInfo().size.height);

...

//清理當前可能正在執行的動畫

cancelAllAnimator();

//啟動矩陣動畫

mScaleAnimator = new ScaleAnimator(mOuterMatrix, animEnd);

mScaleAnimator.start();

...

}

2、圖片在縮放狀態下移動

單指滑動表示手指在屏幕上完成矢量平移,是圖片移動的唯一方式。該功能是通過 scrollBy() 方法實現的。

以實現圖片左右移動為例,在 scrollBy() 方法中,需要判斷縮放狀態下圖片位移的最大距離,有以下幾種不同的情況:

圖片移動后,左側邊緣超出控件的左側邊緣,圖片無法移動。

圖片移動后,右側邊緣超出控件的右側邊緣,圖片無法移動。

圖片移動后,兩側都未超出控件邊緣的情況下,將以手指觸碰點作為控制點,對圖片進行水平移動。

圖片上下平移的情況與左右平移類似,這里不做贅述,圖片移動效果如圖 6 所示:

圖 6:圖片移動的最大距離

public boolean scrollBy(float xDiff, float yDiff) {

...

if (bound.right - bound.left 《 displayWidth) {

xDiff = 0;

//如果圖片左邊在移動后超出控件左邊

} else if (bound.left + xDiff 》 0) {

//如果在移動之前是沒超出的,計算應該移動的距離

if (bound.left 《 0) {

xDiff = -bound.left;

//否則無法移動

} else {

xDiff = 0;

}

//如果圖片右邊在移動后超出控件右邊

} else if (bound.right + xDiff 《 displayWidth) {

//如果在移動之前是沒超出的,計算應該移動的距離

if (bound.right 》 displayWidth) {

xDiff = displayWidth - bound.right;

//否則無法移動

} else {

xDiff = 0;

}

}

...

}

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 操作系統
    +關注

    關注

    37

    文章

    6895

    瀏覽量

    123745
  • 鴻蒙系統
    +關注

    關注

    183

    文章

    2638

    瀏覽量

    66712
  • HarmonyOS
    +關注

    關注

    79

    文章

    1982

    瀏覽量

    30579

原文標題:鴻蒙手勢操控組件,代碼已開源!

文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    開源大師兄怎么刷鴻蒙系統的,那些傳感器配件還能調用嗎

    開源大師兄怎么刷鴻蒙系統的,那些傳感器配件還能調用嗎
    發表于 01-03 14:32

    鴻蒙原生頁面高性能解決方案上線OpenHarmony社區 助力打造高性能原生應用

    高性能鴻蒙原生應用。 Nodepool:優化頁面滑動流暢性Nodepool旨在解決應用頁面滑動卡頓問題。開發中,相似頁面因業務和代碼差異,組件復用性差,引發卡頓、丟幀,影響用戶體驗。Nodepool通過
    發表于 01-02 18:00

    開源鴻蒙榮獲開放原子“2024年度操作系統領域國內活躍開源項目”

    開源鴻蒙”或“OpenHarmony”)榮獲“2024年度操作系統領域國內活躍開源項目”。 活躍的開源項目是
    的頭像 發表于 12-28 15:39 ?480次閱讀

    開源鴻蒙操作系統5.0 Release版本發布

    開源鴻蒙操作系統5.0 Release版本。 該版本在系統完備度、分布式創新、開發者體驗以及系統穩定性等方面均實現了顯著提升,標志著
    的頭像 發表于 12-23 11:35 ?956次閱讀

    開源鴻蒙應用案例重磅發布

    開源賦能千行百業,有效推動產業創新升級。隨著開放原子開源基金會的開源鴻蒙(OpenHarmony)5.0 Release版本正式發布,項目生態逐步走向成熟,眾多
    的頭像 發表于 12-23 11:32 ?407次閱讀

    如何在開源鴻蒙OpenHarmony開啟SELinux模式?RK3566鴻蒙開發板演示

    本文介紹開源鴻蒙OpenHarmony系統下,開啟/關閉SELinux權限的方法,觸覺智能Purple Pi OH鴻蒙開發板演示,已適配全新OpenHarmony5.0 Release
    的頭像 發表于 11-18 19:03 ?423次閱讀
    如何在<b class='flag-5'>開源</b><b class='flag-5'>鴻蒙</b>OpenHarmony開啟SELinux模式?RK3566<b class='flag-5'>鴻蒙</b>開發板演示

    開源鴻蒙OpenHarmony系統更換開機Logo方法,RK3566鴻蒙開發板備戰第九屆華為ICT大賽

    本文適用開源鴻蒙OpenHarmony系統更換開機Logo,本次使用了觸覺智能的Purple Pi OH鴻蒙開源主板,搭載了瑞芯微RK356
    的頭像 發表于 09-26 09:18 ?837次閱讀
    <b class='flag-5'>開源</b><b class='flag-5'>鴻蒙</b>OpenHarmony<b class='flag-5'>系統</b>更換開機Logo方法,RK3566<b class='flag-5'>鴻蒙</b>開發板備戰第九屆華為ICT大賽

    鴻蒙ArkTS聲明式開發:跨平臺支持列表【綁定手勢方法】 手勢處理

    組件綁定不同類型的手勢事件,并設置事件的響應方法。
    的頭像 發表于 06-15 09:17 ?880次閱讀
    <b class='flag-5'>鴻蒙</b>ArkTS聲明式開發:跨平臺支持列表【綁定<b class='flag-5'>手勢</b>方法】 <b class='flag-5'>手勢</b>處理

    最新開源代碼證實!“鴻蒙原生版”微信正在積極開發中

    話不多說,直接看圖: 這是 MMKV 最新版本 v1.3.5 的發布說明。 MMKV 是微信團隊開源的鍵值對(Key-Value)存儲系統,也是微信客戶端自用的底層基礎組件 。 發布說明寫道
    發表于 05-08 17:08

    騰訊突然宣布,微信鴻蒙版要來了!

    今年初, 華為宣布HarmonyOS NEXT命名為“鴻蒙星河版” ,并計劃在二季度啟動開發者 Beta 計劃,四季度發布商用正式版。 消息一出,不少人為之振奮。 鴻蒙星河版因不再兼容安卓開源
    發表于 04-30 19:34

    開源鴻蒙】下載OpenHarmony 4.1 Release源代碼

    本文介紹了如何下載開源鴻蒙(OpenHarmony)操作系統 4.1 Release版本的源代碼,該方法同樣可以用于下載OpenHarmony最新開發版本(master分支)或者4.0
    的頭像 發表于 04-27 23:16 ?1056次閱讀
    【<b class='flag-5'>開源</b><b class='flag-5'>鴻蒙</b>】下載OpenHarmony 4.1 Release源<b class='flag-5'>代碼</b>

    打造開源鴻蒙生態,國產操作系統迎“轉折之戰”?| 深圳衛視獨家對話深開鴻王成錄

    作為正在崛起的國產操作系統,開源鴻蒙到底有哪些優勢?深圳衛視《大灣區會客廳》主持人何嘉琪獨家對話深開鴻CEO王成錄博士。探究為什么發展自主操作系統勢在必行?
    的頭像 發表于 04-20 08:32 ?562次閱讀
    打造<b class='flag-5'>開源</b><b class='flag-5'>鴻蒙</b>生態,國產操作<b class='flag-5'>系統</b>迎“轉折之戰”?| 深圳衛視獨家對話深開鴻王成錄

    鴻蒙系統三防平板怎么樣

    系統作為華為自主研發的操作系統,具有高度的兼容性和穩定性。用戶可以在設備上安裝各種應用程序,滿足工作、娛樂、學習等多種需求。同時,鴻蒙系統還提供了豐富的交互功能,如語音助手、
    發表于 04-12 14:26

    開源獲獎案例】隔空手勢識別測試系統

    ——來自迪文開發者論壇本期為大家推送迪文開發者論壇獲獎開源案例——隔空手勢識別測試系統。工程師采用7英寸COF智能屏,通過T5LOS核與PAJ7620U2手勢識別傳感器進行數據交互,不
    的頭像 發表于 03-16 08:12 ?665次閱讀
    【<b class='flag-5'>開源</b>獲獎案例】隔空<b class='flag-5'>手勢</b>識別測試<b class='flag-5'>系統</b>

    深圳力挺開源鴻蒙原生應用,深開鴻全力加速開源鴻蒙生態

    近日,深圳市工業和信息化局、深圳市政務服務和數據管理局聯合印發《深圳市支持開源鴻蒙原生應用發展2024年行動計劃》(以下簡稱《行動計劃》)。據悉,這是全國首個針對鴻蒙原生應用發展的政府行動計劃。深開
    的頭像 發表于 03-06 14:33 ?638次閱讀
    深圳力挺<b class='flag-5'>開源</b><b class='flag-5'>鴻蒙</b>原生應用,深開鴻全力加速<b class='flag-5'>開源</b><b class='flag-5'>鴻蒙</b>生態
    足球皇冠大全| 百家乐官网游戏唯一官网网站 | 网络百家乐公式打法| 临海市| 百家乐有什么打法| 波克棋牌斗地主| 百家乐官网的路子怎么| 新全讯网2| 易胜博百家乐官网娱乐城| 伟易博百家乐的玩法技巧和规则| 百家乐官网游戏怎样玩| 百家乐输钱的原因| 百家乐软件代理打| 百家乐官网赌场技巧大全| 百家乐手机壳| 至尊百家乐官网娱乐场| 大发888棋牌游戏| 百家乐官网单机版的| 大发888 m摩卡游戏| 澳门百家乐官网官网| 香港六合彩开奖结果| 长城百家乐游戏| 双桥区| 百家乐的路子怎么| 澳门百家乐官网现场游戏| 威尼斯人娱乐城澳门赌场| 找查百家乐官网玩法技巧| bet365怎么样| 24山运| 华安县| 万人迷百家乐的玩法技巧和规则 | 剑阁县| 澳门百家乐然后赢| 澳门赌百家乐官网能赢钱吗| 太阳城现金| 百家乐官网群到shozo网| 万博88真人娱乐城| 百家乐五种路单规| 百家乐官网龙虎扑克| 速博国际| 百家乐蔬菜配送公司|