<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: wei chang</title>
    <description>The latest articles on DEV Community by wei chang (@youlanjihua).</description>
    <link>https://dev.to/youlanjihua</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2893797%2F203f9a98-7b10-43c7-bce4-75d96a8da145.png</url>
      <title>DEV Community: wei chang</title>
      <link>https://dev.to/youlanjihua</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/youlanjihua"/>
    <language>en</language>
    <item>
      <title>Create the most user-friendly loading animations and prompt pop-ups in HarmonyOS</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Mon, 30 Jun 2025 07:50:56 +0000</pubDate>
      <link>https://dev.to/youlanjihua/create-the-most-user-friendly-loading-animations-and-prompt-pop-ups-in-harmonyos-1b01</link>
      <guid>https://dev.to/youlanjihua/create-the-most-user-friendly-loading-animations-and-prompt-pop-ups-in-harmonyos-1b01</guid>
      <description>&lt;p&gt;Since I started working on HarmonyOS development, Youlan Jun has been constantly seeking an elegant way to create pop-up Windows. I don't want to add components or initialize every page. I just want the loading animation or prompt pop-up window that pops up with just one sentence when I need it, simple and straightforward yet elegant.&lt;/p&gt;

&lt;p&gt;Today, I'm going to officially share with you all this extremely simple and user-friendly tool. I named it yloadinghud. I can't wait to show you how good it is now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpsrjuk26yyf8afxatic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpsrjuk26yyf8afxatic.png" alt="Image description" width="624" height="1344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No matter on which page or anywhere, when you need to load animations or text prompts, you can handle it with just one line of code. It's so elegant.&lt;/p&gt;

&lt;p&gt;yloadinghud has also been uploaded to the ohpm repository. This article is not convenient to post the address. You can search for yloadinghud to view it.&lt;/p&gt;

&lt;p&gt;The following introduces how to install and use this tool:&lt;/p&gt;

&lt;p&gt;First, execute the command to install yloadinghud:&lt;/p&gt;

&lt;p&gt;ohpm install yloadinghud&lt;br&gt;&lt;br&gt;
After the installation is completed, make a very simple configuration. Introduce the project in the EntryAbility.ets file:&lt;/p&gt;

&lt;p&gt;import { yloadinghud } from 'yloadinghud/Index&lt;br&gt;&lt;br&gt;
Then add the following code in the onWindowStageCreate method:&lt;/p&gt;

&lt;p&gt;yloadinghud.gloabalWindowStage = windowStage&lt;br&gt;&lt;br&gt;
Now you can use it freely throughout the entire project when you need to load animations:&lt;/p&gt;

&lt;p&gt;yloadinghud.showLoading()&lt;br&gt;&lt;br&gt;
When the loading is completed and it is necessary to make the animation disappear:&lt;/p&gt;

&lt;p&gt;yloadinghud.dismiss()&lt;br&gt;&lt;br&gt;
Except for the loading animation, all other prompt types have been designed to disappear automatically after 2.5 seconds. So you just need to play and don't worry about anything else.&lt;/p&gt;

&lt;p&gt;For example, display a pop-up window with successful loading:&lt;/p&gt;

&lt;p&gt;yloadinghud.showSuccess()&lt;br&gt;&lt;br&gt;
Pop-up window with failed loading:&lt;/p&gt;

&lt;p&gt;yloadinghud.showError()&lt;br&gt;&lt;br&gt;
There are also ordinary text pop-ups without icon displays:&lt;/p&gt;

&lt;p&gt;yloadinghud.showContent('请输入不少于8位的包含大小写字母和特殊字符串的密码')    &lt;/p&gt;

&lt;p&gt;yloadinghud is the first third-party library project contributed by Youlan Jun, hoping to bring convenience to a large number of HarmonyOS developers. Welcome everyone to use it and also welcome everyone to offer valuable suggestions to make it more perfect.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Practical Case of HarmonyOS NEXT Cangjie Development Language: Movie App</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Mon, 30 Jun 2025 01:32:53 +0000</pubDate>
      <link>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-movie-app-1543</link>
      <guid>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-movie-app-1543</guid>
      <description>&lt;p&gt;Hello everyone, this weekend. Today, I'm still going to share with you a case that was previously implemented using ArkTS. It's a movie App. Today, I'm implementing it again using the UI of Cangjie. Let's take a look at the similarities and differences between Cangjie and ArkTs.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpejh4r0izhd7xkj7cs0t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpejh4r0izhd7xkj7cs0t.png" alt=" " width="800" height="1726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before starting to write the code, let's still analyze the structure of the page first. This page as a whole is a List that scrolls up and down, so the list container is used to implement it. The elements inside the List container can be divided into three parts. The top part is the carousel, followed by a classified list that can be swiped left and right, and the bottom part is the video influence, which is a grid layout.&lt;br&gt;
Now we can start writing the code. First, let's take a look at the carousel at the top. Cangjie language provides a Swiper component, which can conveniently implement many functional effects of the carousel. Here is a demonstration of its basic usage for everyone:&lt;/p&gt;

&lt;p&gt;var controller: SwiperController = SwiperController()&lt;br&gt;
Swiper(this.controller){&lt;br&gt;
ForEach(this.imglist, itemGeneratorFunc: {img:CJResource,index:Int64 =&amp;gt;&lt;br&gt;
Image(img)&lt;br&gt;
.width(300)&lt;br&gt;
.height(300)&lt;/p&gt;

&lt;p&gt;})"&lt;br&gt;
}&lt;br&gt;
Swiper has many rich functional parameters that can be set. Here are some commonly used parameters for you:&lt;br&gt;
cachedCount: The number of preloaded child components&lt;br&gt;
autoPlay: Whether to play automatically&lt;br&gt;
loop: Whether to display in a loop&lt;br&gt;
curve: The animated curve of the carousel&lt;br&gt;
duration: The duration of the switched animation&lt;/p&gt;

&lt;p&gt;The next two parts both have titles, so we will use the header of ListItemGroup to implement them. This part of the knowledge point has been frequently used by us recently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Builder func itemHead(text:String) {
    Row{
        Text(text)
        .fontColor(Color.WHITE)
        .fontSize(13)
    }
    .width(100.percent)
    .height(35)
    .alignItems(VerticalAlign.Center)
    .padding(top:3,left:10)
}
ListItemGroup(ListItemGroupParams(header:{=&amp;gt;bind(this.itemHead,this)(‘分类’)})){
}   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next comes the content part of the classification list. First, we need to define an array. The array writing method of Cangjie is slightly different from that of ArkTS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@State var types:ArrayList&amp;lt;String&amp;gt; = ArrayList&amp;lt;String&amp;gt;(['全部的','动作','喜剧片','爱情','乡村','都市','战争'])    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in the page, add classification components in a loop. The Foreach writing method of Cangjie is also different from that of ArkTS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scroll{
    Row{
        ForEach(types, itemGeneratorFunc: {str:String,index:Int64 =&amp;gt;
            if(index == currentType){
                    Text(str)
                    .fontSize(15)
                    .fontColor(Color.WHITE)
                    .padding(top:8,bottom:8,left:22,right:22)
                    .borderRadius(15)
                    .backgroundColor(0x6152FF)
            }else {
                    Text(str)
                    .fontSize(15)
                    .fontColor(Color.WHITE)
                    .padding(top:8,bottom:8,left:22,right:22)
                    .borderRadius(15)
                    .backgroundColor(Color(6, 4, 31, alpha: 1.0))
            }
                })
    }
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bottom part of the movie list is similar to the above. Just post the code directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ListItemGroup(ListItemGroupParams(header:{=&amp;gt;bind(this.itemHead,this)('最受欢迎')})){
    ListItem{
        Scroll{
            Row(10){
                ForEach(ArrayList&amp;lt;String&amp;gt;(['1','1','2']), itemGeneratorFunc: {str:String,index:Int64 =&amp;gt;
                            Image(@r(app.media.fm))
                        .width(124)
                        .height(180)
                        .borderRadius(10)
                        .objectFit(ImageFit.Fill)
                            })
            }
        }
    }
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above is today's content sharing. Thank you for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Practical Case of HarmonyOS NEXT Cangjie Development Language: Food Delivery App</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Mon, 30 Jun 2025 01:29:57 +0000</pubDate>
      <link>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-food-delivery-app-30pg</link>
      <guid>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-food-delivery-app-30pg</guid>
      <description>&lt;p&gt;Hello everyone, this weekend! Today, I’m going to share with you the practical application of the Cangjie language food delivery App.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x776lua16lnu63aahwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x776lua16lnu63aahwq.png" alt="Image description" width="800" height="1726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can first analyze the layout structure of the page. It is composed of the navigation bar and the List container. Youlan Jun still hasn’t found the system component of the Cangjie language navigation bar. It still needs to be customized. This navigation bar has three parts of content and can be aligned at both ends. It should be noted that if the middle part is needed in the middle of the page, the content width at both ends should be the same. The layout structure code of the navigation bar and the page is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Column{
    Row{
        Text('幽蓝外卖')
        .fontColor(Color.BLACK)
        .fontSize(17)
        Row(6){
            Image(@r(app.media.wm_m1))
            .width(16)
            .height(16)
            Text('黄埔江岸')
            .fontColor(0x1EC28A)
            .fontSize(13)
        }
        Row{
            Image(@r(app.media.wm_m2))
            .width(21)
            .height(21)
        }
        .width(65)
        .justifyContent(FlexAlign.End)
    }
    .padding(left:12,right:12)
    .width(100.percent)
    .height(60)
    .alignItems(VerticalAlign.Center)
    .justifyContent(FlexAlign.SpaceBetween)

    List{
    }
    .width(100.percent)
    .layoutWeight(1)
    .padding(left:12,right:12)
}
.width(100.percent)
.height(100.percent)
.backgroundColor(Color(247, 247, 247, alpha: 1.0))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next comes the search box. Cangjie provides a search box component. With just simple Settings, the effect of this case can be achieved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ListItem{
    Search(value: "", placeholder: "吃点什么")
    .width(100.percent)
    .height(38)
    .backgroundColor(0xDDDDDD)
    .placeholderColor(0x000000)
    .borderRadius(19)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s take a look at the category and discover good dishes modules. They have the same style of title, so we use the header of ListItemGroup to implement them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Builder func itemHead(text:String) {
    Row{
        Text(text)
        .fontColor(Color.BLACK)
        .fontSize(13)
    }
    .width(100.percent)
    .height(35)
    .alignItems(VerticalAlign.Center)
    .padding(top:3,left:10)
}
ListItemGroup(ListItemGroupParams(header:{=&amp;gt;bind(this.itemHead,this)('看看品类')})){
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s take a look at the category section. Its content has two horizontally scrollable lists. Here, we need to use “Scroll”. Let’s take the list of dishes as an example to implement a simple scrolling list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scroll{
    Row(14){
        ForEach(ArrayList&amp;lt;Int64&amp;gt;([1,1,1,1]), itemGeneratorFunc: {num:Int64,index:Int64 =&amp;gt;
                    Column{
            Image(@r(app.media.wm_mlt))
            .width(168)
            .height(168)
            Column(4){
                Text('幽蓝麻辣烫')
                .fontSize(14)
                .fontColor(Color.BLACK)
                Text('月售 1006')
                .fontSize(13)
                .fontColor(Color.GRAY)
            }
            .width(100.percent)
            .alignItems(HorizontalAlign.Start)
            .padding(left:10)
            .margin(bottom:10)
            Row{
                Text('¥ 18.88')
                .fontColor(Color.RED)
                .fontSize(14)
                Image(@r(app.media.wm_qq))
                .width(16)
                .height(16)
            }
            .padding(left:10,right:10)
            .width(100.percent)
            .justifyContent(FlexAlign.SpaceBetween)
            .margin(bottom:10)
        }
        .height(260)
        .width(162)
        .backgroundColor(Color.WHITE)
        .justifyContent(FlexAlign.SpaceBetween)
                    })
    }
    .height(260)
}
 .scrollable(ScrollDirection.Horizontal)
.scrollBar(BarState.Off)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using the Scroll component, it is important to set the scrolling direction; otherwise, the list may not scroll.&lt;br&gt;
The above is the content sharing about the food delivery App.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Practical Case of HarmonyOS NEXT Cangjie Development Language: A Small but Beautiful Travel App</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Sun, 29 Jun 2025 06:38:26 +0000</pubDate>
      <link>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-a-small-but-beautiful-travel-app-252</link>
      <guid>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-a-small-but-beautiful-travel-app-252</guid>
      <description>&lt;p&gt;Hello everyone, weekend! This article shares the home page of a small but beautiful travel app. The effect picture is as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuey3jdjnc11pqg5drfv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuey3jdjnc11pqg5drfv.png" alt=" " width="800" height="1726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we start writing the code, let’s first sort out the structure of the entire page. It is a scrolling List as a whole, so we need to use the List component. Moreover, this page does not have a Navigation bar. However, to better use component navigation, we still need to use the navigation component and hide the header content, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pathStack: NavPathStack = new NavPathStack();

Navigation(this.pathStack){
}
.width('100%')
.height('100%')
.hideTitleBar(true)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, within the List container, it is further divided into several different sections, namely the personal information section, the function list section, and the recommendation section. Each section has a different layout. We can first set the overall style of the List component, which has a background color and left and right spacing. Additionally, the top and bottom spacing of the elements within the List can be achieved using the space parameter, eliminating the hassle of setting margin each time. The specific code is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List(space:20){
}
.padding(left:14,right:14,top:62)
.width(100.percent)
.height(100.percent)
.backgroundColor(0xF6F9FF)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The personal information section in the first row of the list is relatively simple. It is laid out horizontally and aligned at both ends. The specific code is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Row{
    Column(4){
        Text('llona')
        .fontSize(17)
        .fontColor(0x42436A)
        Text('Summer time, let's book a flight for vacation')
        .fontColor(0x8D91A2)
        .fontSize(14)
    }
    .constraintSize( maxWidth: 60.percent)
    .alignItems(HorizontalAlign.Start)
    Image(@r(app.media.lx_icon))
    .width(55)
    .height(55)
}
.width(100.percent)
.justifyContent(FlexAlign.SpaceBetween)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second line has the same alignment at both ends, and the content is simpler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Row{
    Row{
        Image(@r(app.media.lx_cup))
        .height(21)
        .width(21)
        .margin(left:14)
        Text('1130 pts')
        .fontColor(0X42436A)
        .fontSize(15)
        .margin(left:14)
    }
    .width(168)
    .height(49)
    .backgroundColor(Color.WHITE)
    .alignItems(VerticalAlign.Center)
    .borderRadius(4)
    Row{
        Image(@r(app.media.lx_wallet))
        .height(21)
        .width(21)
        .margin(left:14)
        Text('$ 4600')
        .fontColor(0X42436A)
        .fontSize(15)
        .margin(left:14)
    }
    .width(168)
    .height(49)
    .backgroundColor(Color.WHITE)
    .alignItems(VerticalAlign.Center)
    .borderRadius(4)
}
.width(100.percent)
.justifyContent(FlexAlign.SpaceBetween)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function List part is a bit difficult. We need to nest the Grid list, that is, Grid, in the list container. This is a grid with 2 rows and 4 columns. Please pay attention to the setting of the grid property and the use of foreach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Grid {
    ForEach(lxList, itemGeneratorFunc: {item:LXItem,tag:Int64 =&amp;gt;
                GridItem{
                    Column{
                    Image(item.getImg())
                    .width(52)
                    .height(52)
                    Text(item.getTitle())
                    .fontColor(0x6e6e6e)
                    .fontSize(15)
                    }
                    .height(80)
                }
            })
}
.width(100.percent)
.columnsTemplate('1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(12)
.rowsGap(12)
.height(200)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last Column has a title. We have seen it many times. There are various implementation methods for this alignment of three elements. Today, we will simply and practically implement Row and Column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ListItemGroup(ListItemGroupParams(header:{=&amp;gt;bind(this.itemHead,this)('Recommend')})){
    ListItem{
        Row(15){
            Image(@r(app.media.lx_f1))
            .width(142)
            .height(185)

            Column{
                Image(@r(app.media.lx_f2))
                .width(100.percent)
                .height(83)
                Image(@r(app.media.lx_f3))
                .width(100.percent)
                .height(83)

            }
            .height(185)
            .layoutWeight(1)
            .justifyContent(FlexAlign.SpaceBetween)

        }
        .width(100.percent)
        .height(185)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main contents of the travel app are these. Thank you for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>HarmonyOS NEXT Cangjie Development Language Practical Case: Fitness App</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Sun, 29 Jun 2025 06:36:35 +0000</pubDate>
      <link>https://dev.to/youlanjihua/harmonyos-next-cangjie-development-language-practical-case-fitness-app-6dg</link>
      <guid>https://dev.to/youlanjihua/harmonyos-next-cangjie-development-language-practical-case-fitness-app-6dg</guid>
      <description>&lt;p&gt;Hello everyone, today I’m sharing the homepage of a fitness app:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8iyzhgkh16anij0kmml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8iyzhgkh16anij0kmml.png" alt="Image description" width="800" height="1726"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This page seems slightly more complex than the previous cases, mainly in the top part, where there are overlapping backgrounds and offset parts. Overlapping layouts can be implemented using the Stack container, and offsets beyond the container’s scope can be achieved using negative spacing. The specific implementation code for the top part is as follows:

Column{
    Text('February')
    .fontColor(Color.WHITE)
    .fontSize(14)

    Row{
        Row{
            Image(@r(app.media.goal))
            .width(37)
            .height(37)
            Text('MY GOAL')
            .fontColor(Color.WHITE)
            .fontSize(30)
            .fontWeight(FontWeight.Bolder)
            .margin(left:6)
        }

        Image(@r(app.media.cm_add))
        .width(28)
        .height(28)

    }
    .margin(top:20)
    .width(100.percent)
    .justifyContent(FlexAlign.SpaceBetween)
    .alignItems(VerticalAlign.Center)
}
.alignItems(HorizontalAlign.Start)
.padding(left:12,right:12,top:60)
.width(100.percent)
.height(220)
.linearGradient( direction: GradientDirection.Bottom, colors:[(Color(103, 76, 222, alpha: 1.0),0.0),(Color(129, 28, 219, alpha: 1.0),1.0)], repeating: false)
.borderRadius(bottomLeft: 20.vp, bottomRight: 20.vp)
Row{
    Column(5){
        Row(6){
            Text('weight')
            .fontColor(Color.GRAY)
            .fontSize(11)
            Image(@r(app.media.cm_down))
            .width(15)
            .height(15)
        }
        .justifyContent(FlexAlign.Center)
        .alignItems(VerticalAlign.Center)
        .width(80)
        .height(20)
        .borderRadius(10)
        .border(width: 1.vp, color: Color(216, 216, 216, alpha: 1.0), radius:10.vp,style: BorderStyle.Solid)
        Row(8){
            Image(@r(app.media.cm_js))
            .width(28)
            .height(28)
            Column(5){
                  Progress(value: 50.0, total: 100.0, `type`: ProgressType.Linear)
                    .width(100.percent)
                    .color(0x9570FF)
                Row{
                    Text('250 lb')
                    .fontColor(Color.GRAY)
                    .fontSize(10)
                    Text('250 lb')
                    .fontColor(Color.GRAY)
                    .fontSize(10)
                }
                .width(100.percent)
                .alignItems(VerticalAlign.Center)
                .justifyContent(FlexAlign.SpaceBetween)
            }
            .layoutWeight(1)
        }
        .width(100.percent)
    }
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Start)
    .padding(10)
    .width(100.percent)
    .height(80)
    .borderRadius(10)
    .backgroundColor(Color.WHITE)
}
.width(100.percent)
.height(80)
.margin(top:-50)
.padding(left:12,right:12)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The remaining part is a scrolling List with a title, so it is implemented using the List container. Regarding the use of the list title, everyone should be more familiar with it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Builder func itemHead(text:String) {
    Row{
        Text(text)
        .fontColor(Color.GRAY)
        .fontSize(13)
    }
    .width(100.percent)
    .height(35)
    .alignItems(VerticalAlign.Center)
    .padding(top:3,left:10)
}
ListItemGroup(ListItemGroupParams(header:{=&amp;gt;bind(this.itemHead,this)('THIS WEEK')})){
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should be noted that the first row of the list is a list that can be scrolled horizontally. Here, I choose to use the Scroll container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scroll{
    Row(12){
        Stack(Alignment.Bottom){
            Image(@r(app.media.cm_s1))
            .width(124)
            .height(155)
            Column(3){
                Text('WALKING LUNGES')
                .fontColor(Color.WHITE)
                .fontSize(13)
                .fontWeight(FontWeight.Bold)
                Text('Today')
                .fontSize(10)
                .fontColor(Color.WHITE)
                .backgroundColor(0x3EC7E6)
                .height(16)
                .width(68)
                .borderRadius(8)
                .textAlign(TextAlign.Center)
            }
            .alignItems(HorizontalAlign.Start)
            .margin(bottom:8)
        }
        Stack(Alignment.Bottom){
            Image(@r(app.media.cm_s2))
            .width(124)
            .height(155)
            Column(3){
                Text('WALKING LUNGES')
                .fontColor(Color.WHITE)
                .fontSize(13)
                .fontWeight(FontWeight.Bold)
                Text('Today')
                .fontSize(10)
                .fontColor(Color.WHITE)
                .backgroundColor(0x3EC7E6)
                .height(16)
                .width(68)
                .borderRadius(8)
                .textAlign(TextAlign.Center)
            }
            .alignItems(HorizontalAlign.Start)
            .margin(bottom:8)
        }
        Stack(Alignment.Bottom){
            Image(@r(app.media.cm_s3))
            .width(124)
            .height(155)
            Column(3){
                Text('WALKING LUNGES')
                .fontColor(Color.WHITE)
                .fontSize(13)
                .fontWeight(FontWeight.Bold)
                Text('Today')
                .fontSize(10)
                .fontColor(Color.WHITE)
                .backgroundColor(0x3EC7E6)
                .height(16)
                .width(68)
                .borderRadius(8)
                .textAlign(TextAlign.Center)
            }
            .alignItems(HorizontalAlign.Start)
            .margin(bottom:8)
        }
    }
    .padding(left:12,right:12)
}
.height(155)
.width(100.percent)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last part is relatively simple and similar to the code above, so it won’t be elaborated on further.&lt;br&gt;
That’s all for today’s content. Thank you for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Practical Case of HarmonyOS NEXT Cangjie Development Language: Dynamic Square</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Sat, 28 Jun 2025 11:35:45 +0000</pubDate>
      <link>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-dynamic-square-9k1</link>
      <guid>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-dynamic-square-9k1</guid>
      <description>&lt;p&gt;Hello everyone, today I'm going to share the development of a dynamic square page using the Cangjie language, which is also quite similar to a Moments page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6ra8ekg92ctok8snxx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6ra8ekg92ctok8snxx2.png" alt="Image description" width="800" height="1726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The entire page is divided into two parts, namely the navigation bar and the status list. The navigation bar is relatively simple. We can first write down the specific code of the navigation bar and the basic structure of the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Column{
    Row(10){
        Text('推荐')
        .fontColor(Color.BLACK)
        .fontSize(17)
        .fontWeight(FontWeight.Bold)
        Text('关注')
        .fontColor(Color.GRAY)
        .fontSize(16)
    }
    .width(100.percent)
    .height(60)
    .justifyContent(FlexAlign.Center)

    List(space:10){

    }
    .width(100.percent)
    .layoutWeight(1)
    .backgroundColor(Color(247, 247, 247))
}
.width(100.percent)
.height(100.percent) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, the navigation bar and the list container fill up the entire page. The next task is to develop the status list.&lt;/p&gt;

&lt;p&gt;The content here is also divided into several parts: personal information, status content, and image list. The overall layout is vertical. It should be noted that the profile picture and name of the personal information section are arranged horizontally, which is relatively simple. There is also the list of pictures. The solution I use is Grid, which can quickly adapt to different numbers of pictures.&lt;/p&gt;

&lt;p&gt;Without further ado, let's take a look at how the code is implemented. For the status list, we first need to define the data structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class RowItem{
    private let name: String;
    private let time: String;
    private let cover: CJResource;
    private let content: String;
    private let images : ArrayList&amp;lt;CJResource&amp;gt;;

    public RowItem(name:String, time:String,cover:CJResource,content:String,images:ArrayList&amp;lt;CJResource&amp;gt;){
        this.name = name
        this.content = content
        this.time = time
        this.images = images
        this.cover = cover
    }
    public func getName():String{
        return this.name
    }
    public func getContent():String{
        return this.content
    }
    public func getTime():String{
        return this.time
    }
    public func getCover():CJResource{
        return this.cover
    }
     public func getImages():ArrayList&amp;lt;CJResource&amp;gt;{
        return this.images
    }
}   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don't involve network requests today. We directly define the array locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@State var rowList:ArrayList&amp;lt;RowItem&amp;gt; = ArrayList&amp;lt;RowItem&amp;gt;(
    RowItem('Tom','7小时前',@r(app.media.icon1),'美丽的风景',ArrayList&amp;lt;CJResource&amp;gt;([@r(app.media.fj1),@r(app.media.fj2),@r(app.media.fj3)])),
    RowItem('PLANK','10小时前',@r(app.media.icon2),'晨跑，空气很清新，顺便用个早餐',ArrayList&amp;lt;CJResource&amp;gt;([@r(app.media.cp1)]))
)    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, loop through the List container to implement the list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List(space:10){
    ForEach(rowList, itemGeneratorFunc: {item: RowItem, index: Int64 =&amp;gt;
                ListItem{
                Column(10){
                    Row(6){
                        Image(item.getCover())
                        .width(40)
                        .height(40)
                        .borderRadius(20)
                        Column(4){
                            Text(item.getName())
                            .fontColor(Color.BLACK)
                            .fontSize(15)
                            Text(item.getTime())
                            .fontColor(Color.GRAY)
                            .fontSize(15)
                        }
                        .alignItems(HorizontalAlign.Start)
                    }
                    Text('美丽的风景')
                    .fontSize(18)
                    .fontColor(Color.BLACK)
                    .margin(top:3)
                    Grid {
                        ForEach(item.getImages(), itemGeneratorFunc: {img:CJResource,tag:Int64 =&amp;gt;
                                    GridItem{
                                    Image(img)
                                    .width(112)
                                    .height(112)
                                    .borderRadius(8)
                                    .onClick({e =&amp;gt;
                                        imglist = item.getImages()
                                        dialogController.open()
                                        })
                                }
                                })
            }
            .width(100.percent)
            .columnsTemplate('1fr 1fr 1fr')
            .columnsGap(12)
            .rowsGap(12)
            .backgroundColor(0xFFFFFF)
                }
                .padding(12)
                .alignItems(HorizontalAlign.Start)
                .backgroundColor(Color.WHITE)

            }
            })
}
.width(100.percent)
.layoutWeight(1)
.backgroundColor(Color(247, 247, 247))  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all for today's content. Thank you for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Practical Case of HarmonyOS NEXT Cangjie Development Language: Image Previewer</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Sat, 28 Jun 2025 11:32:54 +0000</pubDate>
      <link>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-image-previewer-kii</link>
      <guid>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-image-previewer-kii</guid>
      <description>&lt;p&gt;The previous text shared how to implement a dynamic square using the Cangjie language. There are many pictures in the dynamic square. This article will explain how to implement a picture magnification previewer using the Cangjie language:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fdo5mh1arrtc8oj8976.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fdo5mh1arrtc8oj8976.png" alt=" " width="800" height="1726"&gt;&lt;/a&gt;&lt;br&gt;
Seeing this effect, the first implementation solution that came to my mind was the pop-up window. The pop-up and disappearance effects of the pop-up window saved us a lot of work. Here, the CustomDialogController is used.&lt;/p&gt;

&lt;p&gt;First, we implement the pop-up content component. The image preview may have different numbers of images, so we need to do a good job of adaptation and also achieve the page-turning effect. Therefore, using the swiper container is the most suitable. The specific code is as follows. Please pay attention to the definition of the received parameters and the writing method of the pop-up click close code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package ohos_app_cangjie_entry
import ohos.base.*
import ohos.component.*
import ohos.state_manage.*
import ohos.state_macro_manage.*
import cj_res_entry.app
import std.collection.ArrayList
@CustomDialog
public  class imgdialog {
    var controller: Option&amp;lt;CustomDialogController&amp;gt; = Option.None
    @Prop var imgList:ArrayList&amp;lt;CJResource&amp;gt;
    func build() {
        Swiper(){
            ForEach(imgList, itemGeneratorFunc: {img:CJResource,index:Int64 =&amp;gt;
                        Image(img)
                        .width(100.percent)
                        .height(100.percent)
                        .objectFit(ImageFit.Contain)
                        })
        }
        .width(100.percent)
        .height(100.percent)
        .backgroundColor(Color(0, 0, 0, alpha: 0.6))
        .onClick({e =&amp;gt;
            controller.getOrThrow().close()
                })
    }
}   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, everyone still needs to pay attention to the writing method of loop rendering Foreach in Cangjie language. It is slightly different from ArkTS, and the main difference is the addition of the itemGeneratorFunc structure. In addition, in the click event of the Swiper component, I wrote controller.getorthrow ().close() to close the pop-up window. The function of the getOrThrow() method, as you can guess from its name, is to retrieve the value or throw an exception. This can avoid many errors during code execution.&lt;br&gt;
The next step is to initialize a pop-up object. By default, the pop-up component cannot fill the entire screen. At this point, it is only necessary to set the customStyle value to true. The function of the autoCancel parameter is to support automatic pop-up messages. The specific code is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@State var imglist:ArrayList&amp;lt;CJResource&amp;gt; = ArrayList&amp;lt;CJResource&amp;gt;()
var dialogController: CustomDialogController = CustomDialogController(CustomDialogControllerOptions(
    builder: imgdialog(imgList:imglist),
    customStyle:true,
    autoCancel:true
))    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the configuration parameters of the pop-up window, setting customStyle to true can make the pop-up window display in full screen. Finally, a pop-up window will open when you click on the picture:&lt;/p&gt;

&lt;p&gt;imglist = item.getImages()&lt;br&gt;
dialogController.open()&lt;br&gt;&lt;br&gt;
Today's content sharing is over. Thank you all for reading&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Practical Case of HarmonyOS NEXT Cangjie Development Language: Simple Music Playback Page</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Fri, 27 Jun 2025 03:07:02 +0000</pubDate>
      <link>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-simple-music-playback-page-49l</link>
      <guid>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-simple-music-playback-page-49l</guid>
      <description>&lt;p&gt;By chance, I came across a very beautiful design drawing of a music player and couldn’t help but want to practice with the Cangjie language. When a beautiful design drawing meets an elegant development language, it’s simply a perfect match., let me show you the beautiful renderings：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzyhay0s0uxqvvr8zz26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzyhay0s0uxqvvr8zz26.png" alt=" " width="800" height="1726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As is customary, before starting to write the code, let's first make a simple analysis of the overall structure of the page. Firstly, this page has a Navigation bar, but it should be noted that the title of the navigation bar is in the middle. In the system's navigation component, it is impossible to center the title, so we need to customize the navigation bar. When defining the navigation bar, I chose to use the Stack layout to place the titles in an independent space, thereby achieving complete centering and not being affected by other components.&lt;br&gt;
Apart from the navigation bar, the other parts are arranged vertically, from top to bottom: the song cover, song information, playback progress bar, audio control bar, and the lyrics control bar at the very bottom.&lt;br&gt;
The overall structure code of the page is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Column{
   //导航栏
    Stack {
        Text('Now Playing')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor(Color.BLACK)
        Row{
            Image(@r(app.media.cm_back))
            .width(35)
            .height(35)
            .onClick({evet =&amp;gt; Router.back()})
        }.width(100.percent).justifyContent(FlexAlign.Start).padding(left:5)
    }
    .padding(left:10,right:10)
    .width(100.percent)
    .height(60)
    .backgroundColor(Color.WHITE)

    Column{
//中间内容
     }
    //歌词
    Row{
            Row(10){
                Image(@r(app.media.cm_music))
                .width(35)
                .height(35)
                Text('Lyrics')
                .fontColor(Color.BLACK)
                .fontWeight(FontWeight.Bold)
                .fontSize(16)
            }
             Image(@r(app.media.cm_up))
                .width(45)
                .height(45)
        }
        .padding(left:10,right:10)
        .width(100.percent)
        .alignItems(VerticalAlign.Center)
        .justifyContent(FlexAlign.SpaceBetween)
}
.justifyContent(FlexAlign.SpaceBetween)
.width(100.percent)
.height(100.percent)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code shows the basic structure of the page and the specific code of the top and bottom parts. Now we only have the middle content part left.&lt;br&gt;
The song cover and the like button can be regarded as a whole, and they partially overlap. This can be achieved by setting the margin to a negative number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Column{
    Image(@r(app.media.cm_cover))
    .width(65.percent)
    .objectFit(ImageFit.Contain)
    Image(@r(app.media.cm_like))
    .width(60)
    .height(60)
    .margin(top:-15)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The song title section is a simple vertical layout of two Text components, with different fonts and colors set. The code is relatively simple and will not be listed or elaborated here. The progress bar is a component we haven't used before. The progress bar provided by Cangjie is rich in functions, offers multiple modes, and is very convenient to use. The demonstration code is as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Progress(value: 50.0, total: 100.0, `type`: ProgressType.Linear)
.width(100.percent)
.color(0x9570FF)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The control button section is also relatively simple. They are one of the few horizontal layouts on this page. Just select "SpaceAround" for alignment. The specific code is as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Row{
    Text('00:36')
    .fontColor(0x9570FF)
    .fontSize(13)
    Image(@r(app.media.skip_previous))
    .width(33)
    .height(33)
    Image(@r(app.media.cm_play))
    .width(80)
    .height(80)
    Image(@r(app.media.skip_next))
    .width(33)
    .height(33)
    Text('03:36')
    .fontColor(Color.GRAY)
    .fontSize(13)
}
.alignItems(VerticalAlign.Center)
.width(100.percent)
.justifyContent(FlexAlign.SpaceAround)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The music playback page is completed here. Thank you for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A case of implementing a drawing board with the Cangjie development language in HarmonyOS NEXT</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Fri, 27 Jun 2025 03:03:19 +0000</pubDate>
      <link>https://dev.to/youlanjihua/a-case-of-implementing-a-drawing-board-with-the-cangjie-development-language-in-harmonyos-next-4498</link>
      <guid>https://dev.to/youlanjihua/a-case-of-implementing-a-drawing-board-with-the-cangjie-development-language-in-harmonyos-next-4498</guid>
      <description>&lt;p&gt;Good morning, everyone. Today, I'd like to share a case of a drawing board implemented with the language developed by Cangjie.&lt;/p&gt;

&lt;p&gt;Recently, there have been many classmates saying that I wrote ArkTS to impersonate Cangjie. To prove my innocence, I took a screenshot for everyone to see. It is indeed a Cangjie file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhlkdwut92cwngp4ie9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhlkdwut92cwngp4ie9n.png" alt="Image description" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cangjie provided the Canvas component Canvas. All our drawing work needs to be carried out on the Canvas, so first add a large enough canvas component on the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Canvas(this.context)
.backgroundColor(0xffff00)
.width(100.percent)
.height(100.percent) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at the code above, you might ask what this.context is. Youlan Jun compares it to a paintbrush. When using the paintbrush to paint on the canvas, context can draw graphics, text, pictures and other contents. The style of the brush can be modified, such as thickness, color, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var settings: RenderingContextSettings = RenderingContextSettings(antialias: true)
var context: CanvasRenderingContext2D = CanvasRenderingContext2D(this.settings)
var path2Db: Path2D = Path2D()


protected open func onPageShow(){
  context.lineWidth(5)
  context.strokeStyle(0x0000ff)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we do today is to let the paintbrush follow the trajectory we have touched to draw curves.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlqha9f0ag8qj52980ct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlqha9f0ag8qj52980ct.png" alt="Image description" width="800" height="1726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fulfill this requirement, first of all, we need to know the trajectory coordinates of the drawing country so that we can draw accurately on the canvas.&lt;/p&gt;

&lt;p&gt;To make the drawing more accurate, I used the Bezier curve three times. Thus, I needed to record at least two points and then pass the midpoint of this point into the coordinates of the Bezier curve as well.&lt;/p&gt;

&lt;p&gt;Touch sliding events can use onTouch. There are several types of onTouch events, such as Down, Move, etc. In Cangjie, I used an unconventional way to determine the type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.onTouch({e:TouchEvent =&amp;gt;
    var pointX = e.touches[0].x;
    var pointY = e.touches[0].y;
    if(e.eventType.toString() == 'Move'){
            let curX = (pointX + this.pointX1)/Float64(2)
            let curY = (pointY + this.pointY1)/Float64(2)
            this.path2Db.bezierCurveTo(this.pointX1,this.pointY1,this.pointX2,this.pointY2,curX,curY)
            this.pointX1 = pointX
            this.pointY1 = pointY
            this.pointX2 = curX
            this.pointY2 = curY
            this.context.stroke(this.path2Db)
    }else if(e.eventType.toString() == 'Down'){
         this.path2Db.moveTo(e.touches[0].x, e.touches[0].y);
            this.pointX1 = pointX
            this.pointY1 = pointY
            this.pointX2 = pointX
            this.pointY2 = pointY
        }
    })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After achieving the drawing of curves, the clearRect method can be used to clear the canvas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Button('清空').onClick({e =&amp;gt;  
    this.context.clearRect(0, 0, 3000, 3000)
  }) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Such a simple drawing board effect has been achieved. Thank you for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Practical Case of HarmonyOS NEXT Cangjie Development Language: Bank App</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Thu, 26 Jun 2025 01:06:45 +0000</pubDate>
      <link>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-bank-app-n5n</link>
      <guid>https://dev.to/youlanjihua/practical-case-of-harmonyos-next-cangjie-development-language-bank-app-n5n</guid>
      <description>&lt;p&gt;The development of the Cangjie language mall project is basically completed. Today, I’d like to share a new project with you all, a bank app. Although it’s called a new project, you might find it somewhat familiar. This project was written about in the ArkTS tutorial. Today, let’s write the Cangjie language again to see what the differences are from ArkTS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1h7c1udws8bhg0unq9uw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1h7c1udws8bhg0unq9uw.png" alt="Image description" width="800" height="1726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First of all, we can see that the page content fills the screen, so the immersive mode needs to be set. The specific code is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;windowStage.getMainWindow().setWindowLayoutFullScreen(true)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next comes the page content section. This is a scrollable List layout, so the List container can be used. Then, the list container can be further divided into several modules:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgky1en18c0c8ignt1qm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgky1en18c0c8ignt1qm2.png" alt="Image description" width="578" height="1076"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With a clear idea in mind, we can then tackle each part one by one. The asset section at the top has a background image, so we can look at the image and content sections separately. Each part becomes very simple. The specific code is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stack(){
            Image(@r(app.media.nav_img))
              .width(100.percent)
            Row(){
              Column(6){
                Row(){
                  Text('总资产')
                    .fontSize(13)
                    .fontColor(Color.BLACK)
                  Image(@r(app.media.eyes))
                    .width(14)
                    .height(10)
                    .margin(left:5)
                }
                Text('****')
                  .fontSize(30)
                  .fontColor(Color.BLACK)
                  .fontWeight(FontWeight.Bold)
                Text('今日收益 +13.3')
                  .fontSize(12)
                  .fontColor(Color.GRAY)
              }
              .alignItems(HorizontalAlign.Start)
              .margin(left:26)
              Row(){
                Image(@r(app.media.shield))
                  .width(16)
                  .height(16)
                Text('开启保障')
                  .fontColor(Color.WHITE)
                  .fontSize(13)
                  .margin(left:6)
              }
              .width(102)
              .height(30)
              .justifyContent(FlexAlign.Center)
              .backgroundColor(Color(0, 0, 0, alpha: 0.1))
              .borderRadius(topLeft:15.vp,bottomLeft:15.vp)
            }
            .width(100.percent)
            .justifyContent(FlexAlign.SpaceBetween)
          }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next comes the list of function buttons. What needs to be noted in this part is that it has some overlap with the asset content above. My implementation method is to set the margin to be negative to offset it towards the top, and then its fillets are only the top two corners. Therefore, attention should also be paid to the setting of some fillets. The reference code is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Row(){
}
.width(100.percent)
.backgroundColor(Color.WHITE)
.borderRadius(topLeft:20.vp,topRight:20.vp)
.margin(top:-40)
.padding(left:12,right:12)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In fact, you can see that most of the code is quite similar to ArkTS. Now, let’s go directly to the popular recommendations section at the very bottom. This part has a title. The best way to implement it is to use headers. As mentioned before, the header writing method of Cangjie is a bit different. Let’s take a look at the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Builder func itemHead(title:String,subTitle:String){
  Row(5){
    Text(title)
      .fontColor(Color.BLACK)
      .fontSize(18)
      .fontWeight(FontWeight.Bold)
          Text(subTitle)
      .fontColor(13)
      .fontColor(0x999999)
  }
  .height(60)
  .width(100.percent)
  .padding(left:12,bottom:13)
  .alignItems(VerticalAlign.Bottom)
}
ListItemGroup(ListItemGroupParams(header:{=&amp;gt;bind(this.itemHead,this)('热门推荐','每天告诉大家值得买的')})){
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above is the relevant content of the bank App case. Thank you for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Summary and Sharing of Data Types in the Cangjie development Language for HarmonyOS Next</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Wed, 25 Jun 2025 04:41:22 +0000</pubDate>
      <link>https://dev.to/youlanjihua/summary-and-sharing-of-data-types-in-the-cangjie-development-language-for-harmonyos-next-2e2m</link>
      <guid>https://dev.to/youlanjihua/summary-and-sharing-of-data-types-in-the-cangjie-development-language-for-harmonyos-next-2e2m</guid>
      <description>&lt;p&gt;Hello everyone. Today, let’s summarize the data types in Cangjie.&lt;br&gt;
Digital&lt;br&gt;
The number types in Cangjie are complex and diverse. Firstly, they are divided into integer and floating-point types, namely Int and Float types. Int types include several types such as Int, Int8, Int32, and Int64. Float types also have several types such as Float16, Float32, and Float64. The following introduces the differences between them to everyone.&lt;br&gt;
In fact, whether it is Int8, Int32 or Int64, they all belong to integer types; the only difference lies in their lengths.&lt;br&gt;
For example, Int8 is the shortest, occupying only one byte;&lt;br&gt;
Int16 occupies 2 bytes and is equivalent to short;&lt;br&gt;
Int32 occupies 4 bytes and it is equivalent to Int.&lt;br&gt;
Int64 occupies 8 bytes and is equivalent to long&lt;br&gt;
String&lt;br&gt;
The String type of Cangjie is similar to that of other languages, all being string. So far, I haven’t found anything to pay attention to.&lt;br&gt;
Array&lt;br&gt;
There are many types of arrays in Cangjie. The most basic one is the Array type. Array is used to define a relatively fixed array. It does not have addition or deletion operations, but only simple sorting, truncation, and query operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arrayList1 = Array&amp;lt;Int64&amp;gt;([1, 2, 3, 4, 5, 6])
//截取
arrayList1.slice(0, 1)
//倒序
arrayList1.reverse()
//查询
arrayList1.indexOf(1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next comes the ArrayList type, which adds operations such as adding, inserting and deleting on the basis of Array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arrayList2 = ArrayList&amp;lt;Int64&amp;gt;([1, 2, 3, 4, 5, 6])
//在头部添加
arrayList2.prepend(0)
//在尾部添加
arrayList2.append(7)
//在指定位置添加
arrayList2.insert(2, 0)
//删除元素
arrayList2.remove(1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, there is the ObservedArrayList type, and correspondingly, there is also the ObservedArray type. They are typically used for state management. When the content of the array changes, they trigger the UI to update.&lt;br&gt;
HashMap&lt;br&gt;
A HashMap is an unordered sequence used to store key-value types. The type of each key-value pair is fixed, and the keys cannot be repeated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let map = HashMap&amp;lt;String, String&amp;gt;([('姓名','幽蓝'),('职业','码农')])
//修改
map['姓名'] = '123'
//删除
map.remove('职业')
//取值
map.get('姓名')
//清空
map.clear()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all for today’s content. Thank you for reading.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using a database in the Cangjie development language</title>
      <dc:creator>wei chang</dc:creator>
      <pubDate>Tue, 24 Jun 2025 02:42:22 +0000</pubDate>
      <link>https://dev.to/youlanjihua/using-a-database-in-the-cangjie-development-language-32pl</link>
      <guid>https://dev.to/youlanjihua/using-a-database-in-the-cangjie-development-language-32pl</guid>
      <description>&lt;p&gt;Today, I tried out CodeGenie, which I saw at the developer conference. It was really great. AI is influencing all walks of life. These days, You LAN Jun has a deep understanding of this. As an employee, one must maintain a state of continuous learning; otherwise, there is a possibility of being replaced.&lt;br&gt;
Today, I’d like to share with you all how to use a database in the Cangjie development language.&lt;br&gt;
Here we are talking about relational databases. First, we still need to introduce the corresponding module. The module of a relational database in the Cangjie language is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ohos.relational_store.*  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The operation process of the database that follows might be quite familiar to many friends. It is in sequence: obtaining the database, creating tables, and then performing operations such as adding, deleting, modifying, and querying. This is the sequence of steps in any development language. However, the writing method of Cangjie might be somewhat different.&lt;br&gt;
The method by which Cangjie acquires data is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getRdbStore(context, config)  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its two parameters are the application context and the configuration information of the database respectively. The main problem is that it is rather troublesome to write the application context. First, in the main_ability.cj file, define the global context parameters and assign values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var globalAbilityContext: Option&amp;lt;AbilityContext&amp;gt; = Option&amp;lt;AbilityContext&amp;gt;.None

globalAbilityContext = Option&amp;lt;AbilityContext&amp;gt;.Some(this.context)  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The positions of these two lines of code are as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flh1j62wg0w8irfp1uf2v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flh1j62wg0w8irfp1uf2v.png" alt="Image description" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now back to the database page. Here, another method is written:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func getContext(): AbilityContext {
     match(globalAbilityContext) {
         case Some(context) =&amp;gt; context
         case _ =&amp;gt; throw Exception("can not get globalAbilityContext.")
     }
 }  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database can be obtained now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var rdbStore: RdbStore = getRdbStore(getStageContext(getContext()), StoreConfig("RdbTest.db", SecurityLevel.S1)) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After obtaining the database, we can try to create a table. We have been writing the mall application, so I will create a product table. The fields will only write the id, product and price:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rdbStore.executeSql("CREATE TABLE IF NOT EXISTS GOODSLIST(ID int NOT NULL, NAME varchar(255) NOT NULL, PRICE int,  PRIMARY KEY (Id))")   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now try to insert data into the table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var values = HashMap&amp;lt;String, ValueType&amp;gt;()
values.put("ID", ValueType.integer(1))
values.put("NAME", ValueType.string("T恤"))
values.put("PRICE", ValueType.integer(79))

rdbStore.insert("GOODSLIST", values) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify the successful insertion, the query operation is carried out next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let resultSet = rdbStore.querySql("SELECT * FROM GOODSLIST") 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The writing method of the query is relatively simple. resultSet is the result set obtained from the query. Now, I will demonstrate to you how to extract data from this result set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(resultSet.goToNextRow()){
  let id = resultSet.getLong(resultSet.getColumnIndex("ID"));
  let name = resultSet.getString(resultSet.getColumnIndex("NAME"));
  let price = resultSet.getLong(resultSet.getColumnIndex("PRICE"));
  AppLog.info('id:' + id.toString()  + ',商品:' + name.toString() + ',价格:' +  price.toString())
}   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“goToNextRow” means pointing to the next line of the result set. It returns a bool value, and a return of true indicates that there is a value. If you want to print all the obtained data, you can use while:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while (resultSet.goToNextRow()) {
  let id = resultSet.getLong(resultSet.getColumnIndex("ID"));
  let name = resultSet.getString(resultSet.getColumnIndex("NAME"));
  let price = resultSet.getLong(resultSet.getColumnIndex("PRICE"));
  AppLog.info('id:' + id.toString()  + '  ,商品:' + name.toString() + '  ,价格:' +  price.toString())
}    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a look at the execution result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo7j757k51zayzvjdys5i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo7j757k51zayzvjdys5i.png" alt="Image description" width="588" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far, we have basically covered the database of Cangjie. Because both modification and deletion can be operated by creating data. For example, to delete a piece of data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rdbStore.executeSql("DELETE FROM GOODSLIST WHERE ID = ?", [ValueType.integer(3)]) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In summary, if the operation has a return value, such as a query, the querySql method can be used. For operations without a return value, the executeSql method can be used.&lt;br&gt;
That’s all for today’s content. Thank you for reading.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
