applist拨号盘样式合并 1798/1 1798/head
authorluozheng <1732036298@qq.com>
Tue, 27 May 2025 08:45:20 +0000 (16:45 +0800)
committerluozheng <1732036298@qq.com>
Tue, 27 May 2025 08:45:20 +0000 (16:45 +0800)
code/sdk/application/wearable/fd230/nativeapp/nativeui/applist/include/ApplistAdapter.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/applist/include/ApplistModel.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/applist/include/ApplistView.h
code/sdk/application/wearable/fd230/nativeapp/nativeui/applist/src/ApplistAdapter.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/applist/src/ApplistModel.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/applist/src/ApplistPresenter.cpp
code/sdk/application/wearable/fd230/nativeapp/nativeui/applist/src/ApplistView.cpp

index 3be80b8..b66b151 100644 (file)
@@ -19,6 +19,7 @@
 #include "wearable_log.h"
 #include "AppItemView.h"
 #include "ApplistModel.h"
+#include "components/root_view.h"
 
 namespace OHOS {
 class ApplistAdapter : public AbstractAdapter {
@@ -51,6 +52,8 @@ private:
     UIView::OnClickListener *itemClickListener_;
 };
 
+/* -------------------------------------------------------------------------- */
+/* ---------------------------------- 弧形列表 ---------------------------------- */
 class ArcScaleListItemAdapter : public AbstractAdapter 
 {
 public:
@@ -70,5 +73,17 @@ private:
     List<AppItem> nodeList_;
     UIView::OnClickListener * itemClickListener_;
 };
+/* -------------------------------------------------------------------------- */
+/* ----------------------------------- 拨号盘 ---------------------------------- */
+class CircleListAdapter
+{
+public:
+    CircleListAdapter(){}
+    ~CircleListAdapter(){}
+    static void native_app_position_init(UIImageView ** CircleListAPP,int CircleListAPPNum,int startangle);
+    static void native_app_position_update(UIImageView ** CircleListAPP,int CircleListAPPNum,UIImageView *CircleListSelectImage_,int startangle,bool isDirectRotate);
+    static int angleIncrement;
+};
+
 }
 #endif
\ No newline at end of file
index 8127fce..d9e8f68 100644 (file)
@@ -46,12 +46,21 @@ public:
     AppListStyle GetCurrentStyle(void);
     void SetInitFlag(bool flag);
 
+    /* -------------------------------------------------------------------------- */
     /* ---------------------------------- 弧形列表 ---------------------------------- */
     void SetArcListStartIndex(uint16_t index);
     uint16_t GetArcListStartIndex(void);
     void GetArcListHeadItemY(int y);
     int GetArcListHeadItemY(void);
     /* -------------------------------------------------------------------------- */
+    /* ----------------------------------- 拨号盘 ---------------------------------- */
+    void SetCircleListStartAngle(int angle);
+    int GetCircleListStartAngle(void);
+    void SetCurselectImageIndex(int index);
+    int GetCurselectImageIndex(void);
+    void SetPreselectImageIndex(int index);
+    int GetPreselectImageIndex(void);
+    /* -------------------------------------------------------------------------- */
 
 private:
     ApplistModel();
@@ -73,6 +82,11 @@ private:
     uint16_t arcListstartIndex = 0; // 圆弧列表起始位置
     int arcListheadItemY = 0;       // 圆弧列表头部位置
     /* -------------------------------------------------------------------------- */
+    /* ----------------------------------- 拨号盘 ---------------------------------- */
+    int circleListStartAngle{0};
+    int curselectImageIndex{0};
+    int preselectImageIndex{0};
+    /* -------------------------------------------------------------------------- */
 };
 }
 
index 6908ae7..8cd8194 100644 (file)
@@ -25,6 +25,7 @@
 #include "drag_event.h"
 #include "UiConfig.h"
 #include "components/ui_transform_list.h"
+#include "components/ui_picker.h"
 
 namespace OHOS {
 class AppListOnDragListener : public UIView::OnDragListener {
@@ -159,6 +160,18 @@ private:
     UITransformList * ArcScaleList_{nullptr};
     ArcScaleListItemAdapter * ArcScaleListAdapter_{nullptr};
     UIView::OnDragListener * ArcScaleListDragListener_{nullptr};
+
+    //for circleList style
+    void CircleListStyleOnStart(void);
+    void CircleListStyleOnSetUpView(void);
+    void CircleListStyleOnStop(void);
+    UIViewGroup * CircleListGroup_{nullptr};
+    UIImageView * CircleListAPP[12]{nullptr};
+    UIImageView * PointImage{nullptr};
+    UIImageView * CircleListSelectImage{nullptr};
+    UIPicker * CircleListPicker{nullptr};
+    UIScrollView * CircleListScrollView{nullptr};
+    int CircleListAPPNum{0};
 };
 }
 #endif // APPLIST_VIEW_H
\ No newline at end of file
index 14f1afd..39c67f3 100644 (file)
@@ -56,6 +56,7 @@ void ApplistAdapter::AddListItem(const AppItem &item)
 {
     listData_.push_back(item);
 }
+/* -------------------------------------------------------------------------- */
 /* ---------------------------------- 弧形列表 ---------------------------------- */
 ArcScaleListItemAdapter::ArcScaleListItemAdapter(){}
 
@@ -106,4 +107,392 @@ UIView * ArcScaleListItemAdapter::GetView(UIView* inView, int16_t index)
     }
     return item;
 }
+/* -------------------------------------------------------------------------- */
+/* ----------------------------------- 拨号盘 ---------------------------------- */
+#define NATIVE_APP_NUM_MAX 50
+static  const uint8_t NATIVE_APP_ANGEL_INTERVAL = 360 / 12;
+static const int CIRCLE_WATCH_R = 233;                  //圆形手表半径
+static const double PI_OVER_180 = M_PI / 180.0;         // 180度对应的弧度
+static const int native_big_app_size = 90;              //大图标
+static const int native_small_app_size = 72;            //小图标
+static int native_app_position_update_startflag = 0;    //native_app_position_update函数开始更新的标志位
+int CircleListAdapter::angleIncrement = 10;
+
+// 根据起始角度、旋转方向以及相关索引更新CircleListAPP和选中图片信息(顺时针且直接旋转情况)
+static void updateCircleListAndSelectImageForDirectClockwise(UIImageView** CircleListAPP,
+                                                             UIImageView* CircleListSelectImage_,
+                                                             int startangle,
+                                                             int& curselectImageIndex,
+                                                             int& preselectImageIndex,
+                                                             int nativeAppNum)
+{
+    int nextstartangle = startangle + (30 - CircleListAdapter::angleIncrement);
+    if (nextstartangle % 30 == 0) {
+        int tempIndex = (nextstartangle / 30);
+        // 计算 index 和 appIndex
+        int index = tempIndex % nativeAppNum + 11;
+        int appIndex = index;
+        if (nextstartangle >= 360) {
+            appIndex = index % nativeAppNum;
+        }
+
+        // 计算 circleIndex
+        int circleIndex = (12 - tempIndex) % 12;
+        if (circleIndex < 0) {
+            circleIndex += 12;
+        }
+
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "circleIndex:%d,appIndex:%d name:%s", circleIndex, appIndex, ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle大于0的顺时针%d:circleIndex:%d,appIndex:%d name:%s",nextstartangle, circleIndex, appIndex,ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        CircleListAPP[circleIndex]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        CircleListAPP[circleIndex]->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[appIndex].id);
+
+        // 选中图片计算
+        if (nextstartangle <= 180) {
+            if (preselectImageIndex == 0 && curselectImageIndex == 12) {
+                preselectImageIndex = 1;
+                curselectImageIndex = 0;
+            } else {
+                preselectImageIndex = curselectImageIndex;
+                curselectImageIndex = (curselectImageIndex - 1) % nativeAppNum;
+            }
+        } else {
+            if (preselectImageIndex == 1 && curselectImageIndex == 0) {
+                preselectImageIndex = 0;
+                curselectImageIndex = 12;
+            } else {
+                preselectImageIndex = curselectImageIndex;
+                curselectImageIndex = (curselectImageIndex + 1) % nativeAppNum;
+            }
+        }
+
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "nextstartangle:%d,startangle大于0的顺时针:[%d,%d] name:%s", nextstartangle,curselectImageIndex, preselectImageIndex,ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].iconLarge);
+        CircleListSelectImage_->SetSrc(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].iconLarge);
+        CircleListSelectImage_->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].id);
+        ApplistModel::GetInstance().SetCurselectImageIndex(curselectImageIndex);
+        ApplistModel::GetInstance().SetPreselectImageIndex(preselectImageIndex);
+    }
+}
+
+// 根据起始角度、旋转方向以及相关索引更新CircleListAPP(顺时针且非直接旋转情况)
+static void updateCircleListForClockwiseNotDirect(UIImageView** CircleListAPP,
+                                                  UIImageView* CircleListSelectImage_,
+                                                  int startangle,
+                                                  int& curselectImageIndex,
+                                                  int& preselectImageIndex,
+                                                  int nativeAppNum)
+{
+    if(startangle % 30 == 0) 
+    {
+        int prevStartAngle = startangle + 30;
+        int tempIndex =  prevStartAngle / 30;
+        int appIndex = (12 - tempIndex) % nativeAppNum;
+        if(startangle >= 360)
+        {
+            if (appIndex <= 0) 
+            {
+                appIndex = (- appIndex + 11) % nativeAppNum;
+            }
+        }
+
+        // 计算 circleIndex
+        int circleIndex = (12 - tempIndex) % 12;
+        if (circleIndex < 0) {
+            circleIndex += 12;
+        }
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "circleIndex:%d,appIndex:%d name:%s", circleIndex, appIndex, ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle大于0的逆时针%d:circleIndex:%d,appIndex:%d name:%s",startangle,circleIndex, appIndex,ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        CircleListAPP[circleIndex]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        CircleListAPP[circleIndex]->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[appIndex].id);
+    }
+    
+    if(startangle % 30 == 0) 
+    {
+        // 选中图片计算
+        if(startangle <= 180)
+        {
+            if(preselectImageIndex == 0 && curselectImageIndex == 12)
+            {
+                preselectImageIndex = 1;
+                curselectImageIndex = 0;
+            }
+            else
+            {
+                curselectImageIndex = preselectImageIndex;
+                preselectImageIndex = curselectImageIndex + 1 % nativeAppNum;
+            }
+        }
+        else
+        {
+            if(preselectImageIndex == 12 && curselectImageIndex == 13)
+            {
+                preselectImageIndex = 0;
+                curselectImageIndex = 12;
+            }
+            else
+            {
+                curselectImageIndex = (curselectImageIndex - 1 + nativeAppNum) % nativeAppNum;
+                preselectImageIndex = (preselectImageIndex - 1 + nativeAppNum) % nativeAppNum;
+            }
+        }
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle:%d,startangle大于0的逆时针:[%d,%d] name:%s", startangle,curselectImageIndex, preselectImageIndex,ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].iconLarge);
+        CircleListSelectImage_->SetSrc(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].iconLarge);
+        CircleListSelectImage_->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].id);
+        ApplistModel::GetInstance().SetCurselectImageIndex(curselectImageIndex);
+        ApplistModel::GetInstance().SetPreselectImageIndex(preselectImageIndex);
+    }
+}
+
+// 根据起始角度、旋转方向以及相关索引更新CircleListAPP和选中图片信息(逆时针且非直接旋转情况)
+static void updateCircleListAndSelectImageForCounterclockwiseNotDirect(UIImageView** CircleListAPP,
+                                                                       UIImageView* CircleListSelectImage_,
+                                                                       int startangle,
+                                                                       int& curselectImageIndex,
+                                                                       int& preselectImageIndex,
+                                                                       int nativeAppNum)
+{
+
+    int absnextStartAngle = abs(startangle - (30 - CircleListAdapter::angleIncrement));
+    if (absnextStartAngle % 30 == 0) {
+        int index = (absnextStartAngle / 30) % nativeAppNum + 11;
+        int appIndex = index;
+        if (absnextStartAngle >= 360) {
+            appIndex = index % nativeAppNum;
+        }
+        int circleIndex = ((absnextStartAngle - 30) / 30 ) % 12;
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "circleIndex:%d,appIndex:%d name:%s", circleIndex, appIndex, ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle小于0的逆时针:circleIndex:%d,appIndex:%d", circleIndex, appIndex);
+        CircleListAPP[circleIndex]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        CircleListAPP[circleIndex]->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[appIndex].id);
+        
+        preselectImageIndex = curselectImageIndex;
+        curselectImageIndex = (curselectImageIndex + 1) % nativeAppNum;
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "absnextStartAngle:%d,startangle小于0的逆时针:[%d,%d]", absnextStartAngle,curselectImageIndex, preselectImageIndex);
+        CircleListSelectImage_->SetSrc(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].iconLarge);
+        CircleListSelectImage_->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].id);
+        ApplistModel::GetInstance().SetCurselectImageIndex(curselectImageIndex);
+        ApplistModel::GetInstance().SetPreselectImageIndex(preselectImageIndex);
+    }
+}
+
+// 根据起始角度、旋转方向以及相关索引更新CircleListAPP和选中图片信息(逆时针且直接旋转情况)
+static void updateCircleListAndSelectImageForCounterclockwiseDirect(UIImageView** CircleListAPP,
+                                                                    UIImageView* CircleListSelectImage_,
+                                                                    int startangle,
+                                                                    int& curselectImageIndex,
+                                                                    int& preselectImageIndex,
+                                                                    int nativeAppNum)
+{
+    int absStartAngle = abs(startangle);
+    if (absStartAngle % 30 == 0) {
+        int appIndex = (absStartAngle / 30) % nativeAppNum ;
+        int circleIndex = (absStartAngle / 30) % 12;
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "circleIndex:%d,appIndex:%d name:%s", circleIndex, appIndex, ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle小于0的顺时针:circleIndex:%d,appIndex:%d", circleIndex, appIndex);
+        CircleListAPP[circleIndex]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+        CircleListAPP[circleIndex]->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[appIndex].id);
+
+        curselectImageIndex = preselectImageIndex;
+        preselectImageIndex = (preselectImageIndex - 1 + nativeAppNum) % nativeAppNum;
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "absStartAngle:%d,startangle小于0的顺时针:[%d,%d]", absStartAngle,curselectImageIndex, preselectImageIndex);
+        CircleListSelectImage_->SetSrc(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].iconLarge);
+        CircleListSelectImage_->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].id);
+        ApplistModel::GetInstance().SetCurselectImageIndex(curselectImageIndex);
+        ApplistModel::GetInstance().SetPreselectImageIndex(preselectImageIndex);
+    }
+}
+
+// 根据起始角度为0的情况更新CircleListAPP和选中图片信息
+static void updateCircleListAndSelectImageWhenStartangleZero(UIImageView** CircleListAPP,
+                                                             UIImageView* CircleListSelectImage_,
+                                                             int& curselectImageIndex,
+                                                             int& preselectImageIndex,
+                                                             bool isDirectRotate)
+{
+    int index = 0;
+    int appIndex = 0;
+    int circleIndex = 0;
+    if (!isDirectRotate) {
+        index = 0;
+        appIndex = 11;
+        circleIndex = 11;
+    } else {
+        index = 0;
+        appIndex = 0;
+        circleIndex = 0;
+    }
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "circleIndex:%d,appIndex:%d name:%s", circleIndex, appIndex, ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+    CircleListAPP[circleIndex]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+
+    curselectImageIndex = preselectImageIndex;
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle等于0:[%d,%d]", curselectImageIndex, preselectImageIndex);
+    CircleListSelectImage_->SetSrc(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].iconLarge);
+    CircleListSelectImage_->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[curselectImageIndex].id);
+    ApplistModel::GetInstance().SetCurselectImageIndex(curselectImageIndex);
+    ApplistModel::GetInstance().SetPreselectImageIndex(preselectImageIndex);
+}
+//更改图片位置和大小的函数
+static void updateImagePositionAndSize(UIImageView** CircleListAPP, int CircleListAPPNum, int startangle, int curscale)
+{
+    double curangle = startangle;// 当前角度
+    int xPos = 0;
+    int yPos = 0;
+    int size = 81;
+    int margin = 100 - size;//边距
+    int R = CIRCLE_WATCH_R - size / 2 - margin;
+
+    //更改图片位置和大小
+    for(int i = 0; i < CircleListAPPNum; i++)
+    {
+        xPos = ((CIRCLE_WATCH_R - cos(curangle*PI_OVER_180) * R) - size / 2);
+        yPos = ((CIRCLE_WATCH_R - sin(curangle*PI_OVER_180) * R) - size / 2);
+        CircleListAPP[i]->SetPosition(xPos, yPos, size,size);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "xPos:%d,yPos:%d",xPos,yPos);
+        curangle += NATIVE_APP_ANGEL_INTERVAL ; //每个NATIVE_APP位置变化NATIVE_APP_ANGEL_INTERVAL度
+    }
+}
+
+void CircleListAdapter::native_app_position_init(UIImageView ** CircleListAPP,int CircleListAPPNum,int startangle)
+{
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle:%d",startangle);
+    double curangle = startangle;// 当前角度
+    int xPos = 0;
+    int yPos = 0;
+    int size = 81;
+    int margin = 100 - size;//边距
+    int R = CIRCLE_WATCH_R - size / 2 - margin;
+
+    if(startangle % 30 == 0)
+    {
+        int index = 0;
+        int appIndex = 0;
+        int circleIndex = 0;
+
+        int nativeAppNum = ApplistModel::GetInstance().GetAppListNum();
+        int native_app_image_start_index = 0;
+
+        if(startangle > 0 )
+        {
+            int numToChange = startangle / 30;
+            int cnt = 0;
+            for (int i = numToChange - 1; i >= 0; i--)
+            {
+                if(cnt >= 12) //优化算法,只取最后12次图片路径设置,减少重复计算
+                {
+                    break;
+                }
+                // 计算 index 和 appIndex
+                index = i % nativeAppNum + 12;
+                appIndex = index;
+                if (startangle >= 360) {
+                    appIndex = index % nativeAppNum;
+                }
+
+                // 计算 circleIndex
+                circleIndex = (11 - i) % 12;
+                if (circleIndex < 0) {
+                    circleIndex += 12;
+                }
+                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "circleIndex:%d,appIndex:%d name:%s", circleIndex, appIndex, ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+                CircleListAPP[circleIndex]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+                CircleListAPP[circleIndex]->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[appIndex].id);
+                cnt++;
+            }
+
+        }
+        else if(startangle < 0)
+        {
+            int numToChange = abs(startangle) / 30;
+            int cnt = 0;
+            for (int i = numToChange - 1; i >= 0; i--)
+            {
+                if(cnt >= 12) //优化算法,只取最后12次图片路径设置,减少重复计算
+                {
+                    break;
+                }
+                index = i % nativeAppNum + 12;
+                appIndex = index;
+                if (abs(startangle) >= 360)
+                {
+                    appIndex = index % nativeAppNum;
+                }
+                circleIndex = i % 12;
+                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "circleIndex:%d,appIndex:%d name:%s", circleIndex, appIndex, ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+                CircleListAPP[circleIndex]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[appIndex].iconSmall);
+                CircleListAPP[circleIndex]->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[appIndex].id);
+                cnt++;
+            }
+        }
+        else 
+        {
+            for(int i = 0;i < CircleListAPPNum;i++)
+            {
+                CircleListAPP[i]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[i].iconSmall);
+                CircleListAPP[i]->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[i].id);
+            }
+        }
+    }
+
+    //更改图片位置和大小
+    for(int i = 0; i < CircleListAPPNum; i++)
+    {
+        xPos = ((CIRCLE_WATCH_R - cos(curangle*PI_OVER_180) * R) - size / 2);
+        yPos = ((CIRCLE_WATCH_R - sin(curangle*PI_OVER_180) * R) - size / 2);
+        CircleListAPP[i]->SetPosition(xPos, yPos, size,size);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "xPos:%d,yPos:%d",xPos,yPos);
+        curangle += NATIVE_APP_ANGEL_INTERVAL ; //每个NATIVE_APP位置变化NATIVE_APP_ANGEL_INTERVAL度
+    }
+}
+
+void CircleListAdapter::native_app_position_update(UIImageView ** CircleListAPP,int CircleListAPPNum,UIImageView *CircleListSelectImage_,int startangle,bool isDirectRotate)
+{
+    // 打印起始角度
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle:%d",startangle);
+    double curangle = startangle;// 当前角度
+    int curscale = 0;
+    int nativeAppNum = ApplistModel::GetInstance().GetAppListNum();
+
+    int curselectImageIndex = ApplistModel::GetInstance().GetCurselectImageIndex();     //当前选中图片索引
+    int preselectImageIndex = ApplistModel::GetInstance().GetPreselectImageIndex();     //上一次选中图片索引
+
+    if (startangle % 30 == 0) {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startangle:%d,[curselectImageIndex,preselectImageIndex]:[%d,%d]", startangle, curselectImageIndex, preselectImageIndex);
+        native_app_position_update_startflag = 0; //表示可以下次更新了
+        ApplistModel::GetInstance().SetCircleListStartAngle(startangle);
+    }
+
+    if (startangle > 0) 
+    {
+        //顺时针
+        if (isDirectRotate) 
+        {
+            updateCircleListAndSelectImageForDirectClockwise(CircleListAPP,CircleListSelectImage_,startangle,curselectImageIndex,preselectImageIndex,nativeAppNum);
+        }
+        else//逆时针处理
+        {
+            updateCircleListForClockwiseNotDirect(CircleListAPP,CircleListSelectImage_,startangle,curselectImageIndex,preselectImageIndex,nativeAppNum);
+        }
+    }
+    else if(startangle < 0)
+    {
+        if (!isDirectRotate) //逆时针
+        { 
+            updateCircleListAndSelectImageForCounterclockwiseNotDirect(CircleListAPP,CircleListSelectImage_,startangle,curselectImageIndex,preselectImageIndex,nativeAppNum);
+        } 
+        else 
+        {
+            updateCircleListAndSelectImageForCounterclockwiseDirect(CircleListAPP,CircleListSelectImage_,startangle,curselectImageIndex,preselectImageIndex,nativeAppNum);
+        }
+    }
+    else 
+    {
+        updateCircleListAndSelectImageWhenStartangleZero(CircleListAPP,CircleListSelectImage_,curselectImageIndex,preselectImageIndex,isDirectRotate);
+    }
+
+    updateImagePositionAndSize(CircleListAPP, CircleListAPPNum, startangle, curscale);
+    RootView::GetInstance()->Invalidate();
+    return;
+}
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
 } // namespace OHOS
index d6d2bc0..c570478 100644 (file)
@@ -144,29 +144,6 @@ namespace OHOS {
         return headItemY;
     }
 
-    //设置弧形列表的起始位置
-    void ApplistModel::SetArcListStartIndex(uint16_t index)
-    {
-        arcListstartIndex = index;
-    }
-
-    //获取弧形列表的起始位置
-    uint16_t ApplistModel::GetArcListStartIndex(void)
-    {
-        return arcListstartIndex;
-    }
-
-    //设置弧形列表的头部位置
-    void ApplistModel::GetArcListHeadItemY(int y)
-    {
-        arcListheadItemY = y;
-    }
-    //获取弧形列表的头部位置
-    int ApplistModel::GetArcListHeadItemY(void)
-    {
-        return arcListheadItemY;
-    }
-
     void ApplistModel::ApplistUpdate(void)
     {
         ResolvingJSAppItems();
@@ -201,4 +178,69 @@ namespace OHOS {
         }
         #endif
     }
+
+    /* -------------------------------------------------------------------------- */
+    /* ---------------------------------- 弧形列表 ---------------------------------- */
+    //设置弧形列表的起始位置
+    void ApplistModel::SetArcListStartIndex(uint16_t index)
+    {
+        arcListstartIndex = index;
+    }
+
+    //获取弧形列表的起始位置
+    uint16_t ApplistModel::GetArcListStartIndex(void)
+    {
+        return arcListstartIndex;
+    }
+
+    //设置弧形列表的头部位置
+    void ApplistModel::GetArcListHeadItemY(int y)
+    {
+        arcListheadItemY = y;
+    }
+    //获取弧形列表的头部位置
+    int ApplistModel::GetArcListHeadItemY(void)
+    {
+        return arcListheadItemY;
+    }
+    /* -------------------------------------------------------------------------- */
+    /* ----------------------------------- 拨号盘 ---------------------------------- */
+    // 设置拨号盘的起始角度
+    void ApplistModel::SetCircleListStartAngle(int angle)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"SetCircleListStartAngle:%d\r\n",angle);
+        circleListStartAngle = angle;
+    }
+    
+    // 获取拨号盘的起始角度
+    int ApplistModel::GetCircleListStartAngle(void)
+    {
+        return circleListStartAngle;
+    }
+
+    // 设置当前选中的图片索引
+    void ApplistModel::SetCurselectImageIndex(int index)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"SetCurselectImageIndex:%d\r\n",index);
+        curselectImageIndex = index;
+    }
+    
+    // 获取当前选中的图片索引
+    int ApplistModel::GetCurselectImageIndex(void)
+    {
+        return curselectImageIndex;
+    }
+    
+    // 设置上一次选中的图片索引
+    void ApplistModel::SetPreselectImageIndex(int index)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"SetPreselectImageIndex:%d\r\n",index);
+        preselectImageIndex = index;
+    }
+    
+    // 获取上一次选中的图片索引
+    int ApplistModel::GetPreselectImageIndex(void)
+    {
+        return preselectImageIndex;
+    }
 }
index 1e2e9ae..673315a 100644 (file)
@@ -108,7 +108,7 @@ REGIST_SLICE(VIEW_APPLIST, ApplistView, ApplistPresenter);
             waterfallView->SetDraggable(false);
             waterfallView->Scale(1.0f, itemView->GetViewIndex());
             type = TransitionType::TRANSITION_WATERFALL;
-        } else if (AppListStyle::ARC_SCALE_LIST_STYLE == style) {
+        } else if (style == AppListStyle::ARC_SCALE_LIST_STYLE) {
             ArcScaleListItemView *itemView = dynamic_cast<ArcScaleListItemView *>(&view);
             if (nullptr == itemView)
             {
@@ -117,6 +117,16 @@ REGIST_SLICE(VIEW_APPLIST, ApplistView, ApplistPresenter);
             }
             viewId = itemView->GetViewId();
             uid = (char *)itemView->GetAppUid();
+        } else if(style == AppListStyle::CIRCLE_LIST_STYLE) {
+            UIImageView *itemView = dynamic_cast<UIImageView *>(&view);
+            viewId = (AppViewId)itemView->GetViewIndex();
+            if(viewId == VIEW_INVALID)
+            {
+                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "VIEW_INVALID -> %d", viewId);
+                return false;
+            }
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "viewId = %d", viewId);
+            type = TransitionType::TRANSITION_INVALID;
         } else {
             AppItemView *itemView = dynamic_cast<AppItemView *>(&view);
             if (itemView == nullptr) {
index fe03ab5..6fc004c 100644 (file)
 #include "AppItemView.h"
 #include "common/image_cache_manager.h"
 #include "hal_tick.h"
+#include "main/include/ModelListenerSample.h"
 
 namespace OHOS {
 static constexpr int16 NUM_2 = 2;
 static constexpr int16 MAX_SCROLL_DIS = 1000;
 
+class  AppCircleListOnDragListener;
+static AppCircleListOnDragListener *AppCircleListOnDragListener_ = nullptr;
+
 ApplistView::ApplistView()
 {
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApplistView::ApplistView ");
@@ -54,6 +58,7 @@ ApplistView::~ApplistView()
     }
     enterAnimator_ = nullptr;
     /* -------------------------------------------------------------------------- */
+    /* ---------------------------------- 弧形列表 ---------------------------------- */
     if(nullptr != ArcScaleListAdapter_)
     {
         delete ArcScaleListAdapter_;
@@ -75,6 +80,33 @@ ApplistView::~ApplistView()
         ArcScaleListDragListener_ = nullptr;
     }
     /* -------------------------------------------------------------------------- */
+    /* ----------------------------------- 拨号盘 ---------------------------------- */
+    if(CircleListGroup_ != nullptr)
+    {
+        CircleListGroup_->RemoveAll();
+        delete PointImage;
+        PointImage = nullptr;
+        delete CircleListSelectImage;
+        CircleListSelectImage = nullptr;
+        delete CircleListPicker;
+        CircleListPicker = nullptr;
+        delete CircleListScrollView;
+        CircleListScrollView = nullptr;
+        for(int i = 0;i < CircleListAPPNum;i++)
+        {
+            if(nullptr != CircleListAPP[i])
+            {
+                delete CircleListAPP[i];
+                CircleListAPP[i] = nullptr;
+            }
+        }
+        delete AppCircleListOnDragListener_;
+        AppCircleListOnDragListener_ = nullptr;
+
+        delete CircleListGroup_;
+        CircleListGroup_ = nullptr;
+    }
+    /* -------------------------------------------------------------------------- */
 }
 
 void ApplistView::OnStart()
@@ -90,8 +122,7 @@ void ApplistView::OnStart()
     } else if(style == AppListStyle::ARC_SCALE_LIST_STYLE) {
         ArcScaleListStyleOnStart();
     } else if(style == AppListStyle::CIRCLE_LIST_STYLE) {
-        // CircleListStyleOnStart();
-        ListStyleOnStart();// 暂时未合并拨号盘样式,使用列表样式代替
+        CircleListStyleOnStart();
     } else {
         ListStyleOnStart();
     }
@@ -170,7 +201,7 @@ void ApplistView::WaterfallStyleOnStart()
     waterfallList_->SetDraggable(false); // ensure that it can't be dragged during animation to avoid error display
     AddViewToRootContainer(waterfallList_);
 }
-
+/* -------------------------------------------------------------------------- */
 /* ---------------------------------- 弧形列表 ---------------------------------- */
 #define ARC_SCALE_LIST_SCALE_FACTOR (400)
 #define ARC_SCALE_LIST_X (25)
@@ -333,6 +364,449 @@ void ApplistView::ArcScaleListStyleOnStop(void)
     presenter_->SetArcListStartIndex(arclistHeadIndex);    //设置头部Index
 }
 /* -------------------------------------------------------------------------- */
+/* ----------------------------------- 拨号盘 ---------------------------------- */
+#include <vibrator_service.h>
+
+#include "cmath"
+#include "vector"
+
+// 圆形表的圆心坐标和半径
+static const int CIRCLE_CENTER_X = 233;
+static const int CIRCLE_CENTER_Y = 233;
+static const int CIRCLE_RADIUS = 233;
+static Point curpoint;
+static Point prepoint;
+
+// 将触摸点坐标转换为相对于圆心的坐标
+static Point convertToRelativeCoordinates(const Point& point)
+{
+    Point relativePoint;
+    relativePoint.x = point.x - CIRCLE_CENTER_X;
+    relativePoint.y = point.y - CIRCLE_CENTER_Y;
+    return relativePoint;
+}
+// 使用 atan2 函数计算点与水平正方向的夹角(弧度制)
+static double calculateAngle(const Point& point)
+{
+    double angle = std::atan2(point.y, point.x);
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "x:%d,y:%d",point.x,point.y);
+    return angle;
+}
+//获取是否是正向旋转
+static void isDirectRotate(const DragEvent& event,bool &isDirectRotate)
+{
+    // 计算当前点与水平正方向的夹角(弧度制)
+    double angle_cur = calculateAngle(curpoint);
+    // 计算上一次点与水平正方向的夹角(弧度制)
+    double angle_pre = calculateAngle(prepoint);
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "angle_cur:%lf,angle_pre:%lf",angle_cur,angle_pre);
+
+    // 判断滑动方向,通过比较角度差值
+    bool isDirectRotateTemp = isDirectRotate;
+    double angleDiff = angle_cur - angle_pre;
+    if (angleDiff >= 0)
+    {
+        isDirectRotate = true;
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "顺时针滑动");
+    }
+    else
+    {
+        isDirectRotate = false;
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "逆时针滑动");
+    }
+    if((angle_cur < 0 && angle_pre > 0) || (angle_cur > 0 && angle_pre < 0))
+    {
+        isDirectRotate = isDirectRotateTemp;
+        if(isDirectRotateTemp)
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "逆时针滑动->顺时针滑动");
+        else
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "顺时针滑动->逆时针滑动");
+    }
+}
+
+class AppCircleListOnDragListener : public UIView::OnDragListener,
+                                    public UIPicker::SelectedListener,
+                                    public UIView::OnRotateListener,
+                                    public ::OHOS::ModelListenerSample
+                                    
+{
+public:
+    AppCircleListOnDragListener(UIImageView ** CircleListAPP_,int CircleListAPPNum_,UIImageView *CircleListSelectImage_)
+    {
+        CircleListAPP = CircleListAPP_;
+        CircleListAPPNum = CircleListAPPNum_;
+        CircleListSelectImage = CircleListSelectImage_;
+        angle = ApplistModel::GetInstance().GetCircleListStartAngle();
+    }
+    ~AppCircleListOnDragListener(){}
+    bool OnDragStart(UIView& view, const DragEvent& event) override
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AppCircleListOnDragListener::OnDragStart");
+        if(!isEncoderEvent) //如果此时编码器未旋转
+        {
+            isDragEvent = true;
+            prepoint = convertToRelativeCoordinates(event.GetStartPoint());
+            preX = event.GetStartPoint().x;
+            preY = event.GetStartPoint().y;
+            dragstartTimeStamp = event.GetTimeStamp();
+        }
+        return true;
+    }
+
+    bool OnDrag(UIView& view, const DragEvent& event) override
+    {
+        if(isDragEvent)
+        {
+            int curX = event.GetCurrentPos().x;
+            int curY = event.GetCurrentPos().y;
+            int deltaX = abs(curX - preX);
+            int deltaY = abs(curY - preY);
+            if (deltaX < 8 && deltaY < 8)
+            {
+                return false;
+            }
+            curpoint = convertToRelativeCoordinates(event.GetCurrentPos());
+            /* -------------------------------------------------------------------------- */
+            isDirectRotate(event,isDirectRotateFlag);
+            angle += (isDirectRotateFlag ? CircleListAdapter::angleIncrement : - CircleListAdapter::angleIncrement);
+            CircleListAdapter::CircleListAdapter::native_app_position_update(CircleListAPP,CircleListAPPNum,CircleListSelectImage,angle,isDirectRotateFlag);
+            /* -------------------------------------------------------------------------- */
+            prepoint = curpoint;
+            preX = curX;
+            preY = curY;
+            /* -------------------------------------------------------------------------- */
+        }
+        return true;
+    }
+
+    bool OnDragEnd(UIView& view, const DragEvent& event) override
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AppCircleListOnDragListener::OnDragEnd");
+        if(isDragEvent)
+        {
+            dragendTimeStamp =  event.GetTimeStamp();
+            dragDuration = dragendTimeStamp - dragstartTimeStamp;
+            // OnDragEndFlag = (dragDuration >= 25 ? 1 : 0);//点击应用的时候容易产生滑动,小于25ms的屏蔽
+            OnDragEndFlag = 1;
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "dragDuration:%d,dragstartTimeStamp:%d,dragendTimeStamp:%d",dragDuration,dragstartTimeStamp,dragendTimeStamp);
+            int deltaX = abs(event.GetLastPoint().x - event.GetStartPoint().x);
+            int deltaY = abs(event.GetLastPoint().y - event.GetStartPoint().y);
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "拖动时间:%d 毫秒,deltaX:%d,deltaY:%d",dragDuration,deltaX,deltaY);
+        }
+        return true;
+    }
+
+
+    void ResetState() 
+    {  
+        OnDragEndFlag = 0;  
+        isInitialized = false;  
+        inertiaDragAngle = 0;
+        isDragEvent = false;  
+        if (isEncoderEvent) 
+        {  
+            CircleListAdapter::angleIncrement = 10;//还原为drag的角度
+            isEncoderEvent = false;  
+            ui_api_vibrate_once_func();  
+        }
+    }
+
+    void Notify() override
+    {
+        if (!OnDragEndFlag) {  
+            return; // Early return if there's no drag end  
+        }  
+        static int targetAngle = 0;// 目标角度:就是等下惯性要滑多少角度
+        static int timeIndex = 0;
+
+        if(!isInitialized) {
+            isInitialized = true;
+
+            // Define target angles based on drag duration  
+            std::vector<int> targetAngles = {0, 30, 60, 90, 150,180,210,240,270,300};
+            // 根据滑动时间确定对应的目标角度索引
+            uint32_t minDragDuration = 0;  // 假设的最短滑动时间,单位:毫秒,可调整
+            uint32_t maxDragDuration = 1400; // 假设的最长滑动时间,单位:毫秒,可调整
+
+            if (dragDuration < minDragDuration) {
+                // dragDuration = minDragDuration;  // 时间过短,按最短时间处理,避免索引越界等问题
+            } else if (dragDuration > maxDragDuration) {
+                dragDuration = maxDragDuration;  // 时间过长,按最长时间处理
+            }
+            uint32_t durationRange = maxDragDuration - minDragDuration;
+
+
+            // Calculate the target angle index 
+            timeIndex = (dragDuration) / (durationRange / targetAngles.size());
+            timeIndex = std::min(timeIndex, static_cast<int>(targetAngles.size() - 1));  // 防止越界
+            targetAngle = targetAngles[timeIndex];  
+        }
+
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "拖动时间:%d 毫秒,当前角度:%d,目标角度:%d,时间索引:%d", dragDuration, angle, targetAngle, timeIndex);
+        // 根据旋转方向确定角度增量的正负以及计算角度增量大小
+        int angleIncrementSign = isDirectRotateFlag ? 1 : -1;
+
+        if(targetAngle != 0) {
+            if(inertiaDragAngle != targetAngle) {
+                angle += (angleIncrementSign * CircleListAdapter::angleIncrement);
+                inertiaDragAngle += abs(angleIncrementSign * CircleListAdapter::angleIncrement);
+            } else if(inertiaDragAngle == targetAngle && angle % 30 != 0) {
+                angle += (angleIncrementSign * CircleListAdapter::angleIncrement); //还要再次补充角度
+            } else if(inertiaDragAngle == targetAngle && angle % 30 == 0) {
+                // Reset state when target angle is reached  
+                ResetState();
+                return;
+            }
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "inertiaDragAngle:%d,angle:%d",inertiaDragAngle,angle);
+            // 调用视图更新函数,实时更新界面显示
+            CircleListAdapter::native_app_position_update(CircleListAPP, CircleListAPPNum, CircleListSelectImage, angle, isDirectRotateFlag);
+        } else {
+            if(angle % 30 == 0) {
+                ResetState();
+            } else {
+                angle += (isDirectRotateFlag? CircleListAdapter::angleIncrement : -CircleListAdapter::angleIncrement);
+                CircleListAdapter::native_app_position_update(CircleListAPP,CircleListAPPNum,CircleListSelectImage,angle,isDirectRotateFlag);
+            }
+        }
+        return;
+    }
+
+    bool OnRotateStart(UIView& view, const RotateEvent& event)
+    {
+        if(!isDragEvent) //如果此时未拖拽
+        {
+            isEncoderEvent = true;
+            CircleListAdapter::angleIncrement = 15;
+            preRotateAngle = angle;
+        }
+        return false;
+    }
+
+    bool OnRotate(UIView& view, const RotateEvent& event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AppCircleListOnDragListener::OnRotate %d",event.GetRotate());
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnRotate回调次数%d",++RotateReportedCount);
+        if(isEncoderEvent)
+        {
+            ++RotateReportedCount;
+            if(RotateReportedCount > 4) 
+            {
+                if(event.GetRotate() > 0)
+                {
+                    isDirectRotateFlag = true;
+                    angle += CircleListAdapter::angleIncrement;
+                    CircleListAdapter::native_app_position_update(CircleListAPP,CircleListAPPNum,CircleListSelectImage,angle,isDirectRotateFlag);
+                }
+                else
+                {
+                    isDirectRotateFlag = false;
+                    angle -= CircleListAdapter::angleIncrement;
+                    CircleListAdapter::native_app_position_update(CircleListAPP,CircleListAPPNum,CircleListSelectImage,angle,isDirectRotateFlag);
+                }
+            }
+        }
+        return false;
+    }
+    bool OnRotateEnd(UIView& view, const RotateEvent& event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AppCircleListOnDragListener::OnRotateEnd %d",event.GetRotate());
+        if(isEncoderEvent)
+        {
+            if(angle % 30 == 0) 
+            { 
+                CircleListAdapter::angleIncrement = 10; //还原为drag的角度
+                OnDragEndFlag = 0;   //不需要补偿角度
+                isEncoderEvent = false;
+                if(preRotateAngle != angle) 
+                {
+                    ui_api_vibrate_once_func();
+                }
+            } 
+            else 
+            {
+                OnDragEndFlag = 1;
+            }
+            RotateReportedCount = 0;
+            rotateangle = 0;
+            dragDuration = 0;
+        }
+        return false;
+    }
+
+    private:
+        UIImageView **CircleListAPP{nullptr};           //图片组件数组
+        UIImageView *CircleListSelectImage{nullptr};    //中间选中图片的图片组件
+        int CircleListAPPNum{0};                        //图片组件数量
+        int angle = 0;                                  //要旋转角度
+        int rotateangle{0};                             //旋转累计角度
+        uint8_t OnDragEndFlag{0};                       //是否拖拽结束的标志
+        bool isDirectRotateFlag{false};                 //是否是正向旋转的标志
+        int preX{0}; 
+        int preY{0};
+
+        bool isEncoderEvent{false};                     //是否为编码器事件                
+        bool isDragEvent{false};                        //是否为拖拽事件
+        int RotateReportedCount{0};
+
+        uint32_t dragstartTimeStamp{0}; //开始拖拽时的时间戳
+        uint32_t dragendTimeStamp{0};   //拖拽结束时的时间戳
+        uint32_t dragDuration{0};       //拖拽时间
+        int inertiaDragAngle{0};        //惯性拖拽角度
+        bool isInitialized {false};
+        int preRotateAngle{0};
+};
+
+void ApplistView::CircleListStyleOnStart(void)
+{
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApplistView::CircleListStyleOnStart start!! [%d]", __LINE__);
+    if(nullptr == CircleListGroup_)
+    {
+        CircleListGroup_ = new UIViewGroup();
+        if(nullptr == CircleListGroup_)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApplistView::CircleListGroup_ failed!! [%d]", __LINE__);
+            return;
+        }
+        CircleListGroup_->SetPosition(0, 0);
+        CircleListGroup_->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);
+        CircleListGroup_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
+        CircleListGroup_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);
+        CircleListGroup_->SetTouchable(true);
+        CircleListGroup_->SetDraggable(true);
+        AddViewToRootContainer(CircleListGroup_);
+        /* -------------------------------------------------------------------------- */
+        if (CircleListPicker == nullptr)
+        {
+            CircleListPicker = new UIPicker();
+            if (CircleListPicker == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CircleListPicker new fail!");
+                return;
+            }
+            CircleListPicker->SetPosition(213, 213, 40, 40);
+            CircleListPicker->SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff);
+            CircleListPicker->SetStyle(STYLE_BACKGROUND_OPA, 0x00);
+            CircleListPicker->SetStyle(STYLE_BORDER_RADIUS, 150);
+            CircleListPicker->SetItemHeight(30);
+            CircleListPicker->SetLoopState(true);
+            CircleListPicker->SetRotateFactor(1.0);
+            CircleListPicker->RequestFocus();
+            CircleListPicker->SetLoopState(true);
+            CircleListPicker->SetTextColor(Color::GetColorFromRGBA(0x00, 0x00, 0x00, 0xff), Color::GetColorFromRGBA(0xff, 0x00, 0x00, 0xff));
+            CircleListPicker->SetSelected(1);
+            int start = 1;
+            int end = 3;
+            CircleListPicker->SetValues(start,end);
+        }
+        /* -------------------------------------------------------------------------- */
+        if(CircleListScrollView == nullptr)
+        {
+            CircleListScrollView = new UIScrollView();
+            if(nullptr == CircleListScrollView)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApplistView::CircleListScrollView failed!! [%d]", __LINE__);
+                return;
+            }
+            CircleListScrollView->SetPosition(213, 213, 40, 40);
+            CircleListScrollView->SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff);
+            CircleListScrollView->SetStyle(STYLE_BACKGROUND_OPA, 0x00);
+            CircleListScrollView->SetStyle(STYLE_BORDER_RADIUS, 150);
+            CircleListScrollView->SetRotateFactor(30.0);
+            CircleListScrollView->RequestFocus();
+            CircleListGroup_->Add(CircleListScrollView);
+        }
+        /* -------------------------------------------------------------------------- */
+        CircleListAPPNum = sizeof(CircleListAPP) / sizeof(CircleListAPP[0]);//图片显示数量
+        /* -------------------------------------------------------------------------- */
+        for(int i = 0;i < CircleListAPPNum ;i++)
+        {
+            if(nullptr == CircleListAPP[i])
+            {
+                CircleListAPP[i] = new UIImageView();
+                if(nullptr == CircleListAPP[i]) 
+                {
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApplistView::CircleListStyleOnStart failed!! [%d]", __LINE__);
+                    return;
+                }
+                CircleListAPP[i]->SetAutoEnable(false);
+                CircleListAPP[i]->SetResizeMode(UIImageView::SCALE_DOWN);
+                CircleListAPP[i]->SetSrc(ApplistModel::GetInstance().GetApplistItems()[i].iconSmall);
+                CircleListAPP[i]->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[i].id);
+                CircleListAPP[i]->SetTouchable(true);
+                CircleListAPP[i]->SetOnClickListener(presenter_);
+            }
+            CircleListGroup_->Add(CircleListAPP[i]); // Add the UIImageView to the UIViewGroup (CircleListGroup_)
+        }
+        /* -------------------------------------------------------------------------- */
+        uint16_t presliceId = NativeAbility::GetInstance().GetPreSliceId();
+        if (presliceId == VIEW_MAIN || presliceId == VIEW_THEME_STYLE) //如果是从主页进入的,那么 startangle = 0
+        {
+            ApplistModel::GetInstance().SetCircleListStartAngle(0);
+            ApplistModel::GetInstance().SetCurselectImageIndex(6);
+            ApplistModel::GetInstance().SetPreselectImageIndex(6);
+        }
+        CircleListAdapter::native_app_position_init(CircleListAPP,CircleListAPPNum,ApplistModel::GetInstance().GetCircleListStartAngle());
+        /* -------------------------------------------------------------------------- */
+        if(nullptr == PointImage)
+        {
+            PointImage = new UIImageView();
+            if(nullptr == PointImage)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApplistView::PointImage failed!! [%d]", __LINE__);
+                return;
+            }
+            PointImage->SetPosition(330, 233, 10, 10);
+            PointImage->SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff);
+            PointImage->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+            PointImage->SetStyle(STYLE_BORDER_RADIUS, 200);
+            CircleListGroup_->Add(PointImage);
+        }
+        /* -------------------------------------------------------------------------- */
+        if(CircleListSelectImage == nullptr)
+        {
+            CircleListSelectImage = new UIImageView();
+            if(nullptr == CircleListSelectImage)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApplistView::CircleListSelectImage failed!! [%d]", __LINE__);
+                return;
+            }
+            CircleListSelectImage->SetPosition(153, 153,160,160);
+            CircleListSelectImage->SetAutoEnable(false);
+            CircleListSelectImage->SetResizeMode(UIImageView::SCALE_DOWN);
+            CircleListSelectImage->SetSrc(ApplistModel::GetInstance().GetApplistItems()[ApplistModel::GetInstance().GetCurselectImageIndex()].iconLarge);
+            CircleListSelectImage->SetViewIndex(ApplistModel::GetInstance().GetApplistItems()[ApplistModel::GetInstance().GetCurselectImageIndex()].id);
+            CircleListSelectImage->SetTouchable(true);
+            CircleListSelectImage->SetOnClickListener(presenter_);
+            CircleListGroup_->Add(CircleListSelectImage);
+        }
+        /* -------------------------------------------------------------------------- */
+        if(nullptr == AppCircleListOnDragListener_)
+        {
+            AppCircleListOnDragListener_ = new AppCircleListOnDragListener(CircleListAPP,CircleListAPPNum,CircleListSelectImage);
+            if (nullptr == AppCircleListOnDragListener_)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ApplistView::AppCircleListOnDragListener_ failed!! [%d]", __LINE__);
+                return;
+            }
+        }
+        CircleListGroup_->SetOnDragListener(static_cast<UIView::OnDragListener*>(AppCircleListOnDragListener_));
+        CircleListScrollView->SetOnRotateListener(static_cast<UIView::OnRotateListener *>(AppCircleListOnDragListener_));
+        /* -------------------------------------------------------------------------- */
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApplistView::CircleListStyleOnStart success!! [%d]", __LINE__);
+    }
+    return;
+}
+void ApplistView::CircleListStyleOnSetUpView(void)
+{
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApplistView::CircleListStyleOnSetUpView [%d]", __LINE__);
+    return;
+}
+void ApplistView::CircleListStyleOnStop(void)
+{
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ApplistView::CircleListStyleOnStop [%d]", __LINE__);
+    return;
+}
+/* -------------------------------------------------------------------------- */
 
 void ApplistView::ListStyleOnStart()
 {
@@ -393,6 +867,8 @@ void ApplistView::OnStop()
         WaterfallStyleOnStop();
     } else if (style == AppListStyle::ARC_SCALE_LIST_STYLE) {
         ArcScaleListStyleOnStop();
+    } else if (style == AppListStyle::CIRCLE_LIST_STYLE) {
+        CircleListStyleOnStop();
     } else {
         ListStyleOnStop();
     }
@@ -486,6 +962,8 @@ void ApplistView::AddAppItemToList(const AppItem &item)
         waterfallItemList_.PushBack(itemView);
     } else if(style == AppListStyle::ARC_SCALE_LIST_STYLE) {
         ArcScaleListAdapter_->AddListItem(item);
+    } else if(style == AppListStyle::CIRCLE_LIST_STYLE) {
+        //拨号盘
     } else {
         listAdapter_->AddListItem(item);
     }
@@ -502,6 +980,8 @@ void ApplistView::ClearAppItemToList()
         WaterfallStyleOnStop();
     } else if(style == AppListStyle::ARC_SCALE_LIST_STYLE) {
         ArcScaleListStyleOnStop();
+    } else if(style == AppListStyle::CIRCLE_LIST_STYLE) {
+        CircleListStyleOnStop();
     } else {
         listAdapter_->ClearItem();
     }
@@ -519,6 +999,8 @@ void ApplistView::RefreshAppList(void)
         waterfallList_->LayoutChildren(true);
     }  else if (style == AppListStyle::ARC_SCALE_LIST_STYLE) {
         ArcScaleListStyleOnSetUpView();
+    } else if (style == AppListStyle::CIRCLE_LIST_STYLE) {
+        // 拨号盘
     } else {
         uint16_t startIndex = 0;
         int16_t headY = 0;