鸿蒙期末大作业——甜点店铺APP(二)跳转页面的改进

一、跳转页面的继续改进

        上一期我们实现了登录页面的渲染,这一期我们进行登录完成后跳转页面的进一步加工

        当页面信息较多时,为了让用户能够聚焦于当前显示的内容,需要对页面内容进行分类,提高页面空间利用率。利用Tabs导航组件可以在一个页面内快速实现视图内容的切换,一方面提升查找信息的效率,另一方面精简用户单次获取到的信息量。

         Tabs组件的页面组成包含两个部分,分别是TabContent和TabBar。TabContent是内容页,TabBar是导航页签栏。TabBar可以调用自定义构造函数,自定义导航栏。

在view目录下新建三个文件HomePage、ChiocePage和MinePage,分别用来表示首页、精选和我的等三个页面。

二、实验过程(文字描述)

我们登录成功后跳转到MainPage页面,该页面需要包含三个栏目——首页、精选以及我的,页面信息较多,需要将其分类,在该页面内实现试图内容的快速切换。所以在这里我使用了Tabs导航组件进行完善,它是一个可以容纳多个选项卡的容器组件。每个选项卡通常包含一个面板和一个标签,用户可以通过点击标签来切换面板。一方面提升查找信息的效率,另一方面精简用户单次获取到的信息量。

  1. 首先我们创建新的文件夹view,在里面创建三个新的ets文件——HomePage.ets、ChoicePage.ets、MinePage.ets等三个文件。将我们需要用到的图片提前保存在meida目录下,接着分别在不同文件进行下一步不同页面的渲染。
  2. 在MainPage.ets中,我们首先引入Tabs组件,设置它在页面的位置——利用BarPosition.End并且设置vertical(false)属性会使导航页签栏在页面底部显示。利用animationDuration属性设置滑动动画时长。不设置时,点击切换页签无动画,滑动切换有动画;设置时,点击切换和滑动切换都有动画。
  3. 然后构造自定义函数TabBuilder,在TabContent对应tabBar属性中传入自定义函数组件,并传递相应的参数。首先,定义一个items数组,里面有三个参数—标题、未选中的图片以及选中状态的图片。给自定义构造函数TabBuilder传入三个参数:标题title、选中状态的图片iconSelected以及未选中的图片iconNormal。通过ForEach循环遍历对底部导航栏每一个组件的进行加载和渲染,在tabBar属性中传入对应的三个参数。
  4. 最后定义一个状态变量currentIndex,用来记录当前索引下标。给Tabs底部导航页签栏添加触发事件,当我点击导航页签栏的其他栏目,index值发生变化时,将点击的页面下标index赋值给currentIndex。再将该变量传入到自定义构造函数TabBuilder中和.tabBar属性中。然后在自定义构造函数TabBuilder中增加判断条件,运用三目运算,如果传入的索引值和当前索引相等,则加载选中状态的图片,否则加载未被选中状态的图片。

三、代码实现

MainPage.ets

import HomePage from '../view/HomePage'
import ChoicePage from '../view/ChoicePage'
import MinePage from '../view/MinePage'
@Entry
@Component
struct MainPage {
  @State message: string = '首页'
  private controller:TabsController = new TabsController()//Tabs组件的控制器,用于控制Tabs组件进行页签切换
  private items:Array<{title:string,iconSelected:Resource,iconNormal:Resource}> =[
    {title:'首页',iconSelected:$r('app.media.home_selected'),iconNormal:$r('app.media.home_normal')},
    {title:'精选',iconSelected:$r('app.media.choice_selected'),iconNormal:$r('app.media.choice_normal')},
    {title:'我的',iconSelected:$r('app.media.mine_selected'),iconNormal:$r('app.media.mine_normal')},
  ]
  @State currentIndex:number = 0;  //当前索引下标 0

  //@Builder 装饰器 自定义构建函数
  @Builder TabBuilder(title,iconSelected,iconNormal,index){
    Column(){
      Image(this.currentIndex==index?iconSelected:iconNormal)
        .width(25)
        .height(25)
      Text(title)
        .fontColor(this.currentIndex==index?Color.Green:Color.Grey)
        .fontSize(14)
        .fontWeight(FontWeight.Bold)
    }
    .width('100%')
  }

  build() {
    Row() {
      //BarPosition.Start 左侧或顶部 vertical(true) true页签位于左侧;false页签位于顶部
      //BarPosition.End 右侧或底部 vertical(true) true页签位于右侧;false页签位于底部
      Tabs({barPosition:BarPosition.End}){
        ForEach(this.items,(item:{title:string,iconSelected:Resource,iconNormal:Resource},index:number)=>{
          TabContent(){
            //页签的内容
            Column(){
              //加载不同的组件
              if(index===0){  //三个等号代表全等
                HomePage()
              }else if(index===1){
                ChoicePage()
              }else{
                MinePage()
              }
            }

          }.tabBar(this.TabBuilder(item.title,item.iconSelected,item.iconNormal,index))//导航页签栏,调用自定义构造函数,自定义导航栏
        })

      }
      .vertical(false)
      .animationDuration(300)//设置动画效果
      .onChange((index:number)=>{
        this.currentIndex = index
      })

    }
      .width('100%')
  }

}

HomePage.ets

@Entry
@Component
 
struct Main{
  @State message:string = '首页'
 
  build(){
    Row(){
      Column(){
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

Choice.ets

@Entry
@Component
 
struct Main{
  @State message:string = '精选'
 
  build(){
    Row(){
      Column(){
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

 Mine.ets

@Entry
@Component
 
struct Main{
  @State message:string = '我的'
 
  build(){
    Row(){
      Column(){
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

四、效果展示

这里忘了将文本修改成“我的”了,/(ㄒoㄒ)/~~

五、遇到的问题 

1.在MainPage页面包含三个栏目,页面信息较多,需要将页面内容分类,如何在一个页面内快速实现试图内容的切换?

解决方案:使用Tabs导航组件,它是一个可以容纳多个选项卡的容器组件。每个选项卡通常包含一个面板和一个标签,用户可以通过点击标签来切换面板。一方面提升查找信息的效率,另一方面精简用户单次获取到的信息量。

2.在导航栏点击不同栏目时,如何使页面加载不同的效果以及多元化的组件?若都写在首页会使页面过于庞大,如何改进?

解决方法:每个页面放在单独的模块,创建三个页面:分别为首页面、精选 页面以及我的页面。创建新的文件夹view,在里面创建新的ets文件—HomePage.ets、ChoicePage.ets、MinePage.ets等三个文件。分别在不同文件再进行下一步的渲染。

3.底部导航栏怎么加载不同的图片效果?

解决方案:构建自定义构造函数TabBuilder,在TabContent对应tabBar属性中传入自定义函数组件,并传递相应的参数。首先,定义一个items数组,里面有三个参数—标题、未选中的图片以及选中状态的图片。给自定义构造函数TabBuilder传入三个参数:标题title、选中状态的图片iconSelected以及未选中的图片iconNormal。通过ForEach循环遍历对底部导航栏每一个组件的进行加载和渲染,在tabBar属性中传入对应的三个参数。

4.当我们点击底部导航栏的每个栏目时,如何使每个栏目由未选中的状态变为选中的状态?

解决方案:定义一个状态变量currentIndex,用来记录当前索引下标。给Tabs组件添加触发事件,当值发生变化时,将当前索引值赋值给currentIndex。再将该变量传入到自定义构造函数TabBuilder中和.tabBar属性中。然后在自定义构造函数TabBuilder中增加判断条件,运用三目运算,如果传入的索引值和当前索引相等,则加载选中状态的图片,否则加载未被选中状态的图片。

在JavaWeb中,实现网站用户登录功能通常涉及到以下几个关键步骤: 1. **前端页面设计**:创建登录界面,包括用户名输入框(username)、密码输入框(password),以及登录按钮。可以使用HTML、CSS和JavaScript进行前端开发。 2. **后端服务器处理**:后端使用Java和Servlet或Spring MVC框架接收用户的登录请求。通常会涉及以下步骤: - 用户名和密码的验证:检查输入的用户名和密码是否匹配数据库中的记录。你可以使用JDBC连接数据库查询用户信息,也可以使用ORM框架如Hibernate或MyBatis。 - 使用Session或Cookie管理用户状态:如果验证通过,为用户创建一个Session,存储用户标识(通常是登录凭据的哈希值)或其他重要信息,这样后续请求可以识别用户。 3. **安全性考虑**:确保密码安全,一般会采用哈希+盐的方式加密存储,登录时对比哈希值。同时,防止SQL注入和XSS攻击。 4. **错误处理和反馈**:对输入错误或验证失败的情况,返回合适的错误消息给前端,并可能显示错误提示。 5. **登录/登出功能**:除了登录,还需要提供登出功能,清除Session或Cookie,结束用户会话。 6. **登录日志记录**:为了审计和安全,应该记录用户的登录尝试和结果。 相关问题: 1. 如何在JavaWeb中防止跨站脚本攻击(XSS)? 2. 什么是Session和Cookie的区别,它们在用户登录中的作用是什么? 3. 如何在Java中使用Spring Security来增强登录系统的安全性?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值