【React-Native】用ScrollView封装可滑动翻页的菜单

react-native 开发一个如下图所示的可滑动翻页的菜单集合:

菜单可以滑动翻页,是不是特别像是轮播图呢?先配置菜单menu.js:
export const menus = [
{
    name: '用户管理', // 菜单名称
    icon: assets.service_user, // 菜单图标
    routerName: 'userManage', // 跳转页面name
  },
  {
    name: '企业信息',
    icon: assets.service_company,
    routerName: 'company'
  },
  {
    name: '产品信息',
    icon: assets.service_product,
    routerName: 'productInfo',
    companyType: '13',
  },
  {
    name: '财务中心',
    icon: assets.service_finance,
    routerName: 'financeCenter'
  },
  ...
  {
   	name: '更多',
    icon: assets.more,
    routerName: 'more'
  }
]

我们用 ScrollView 横向滚动来实现:

 <View>
	<ScrollView
	   horizontal={true}
	   pagingEnabled={true}
	   showsHorizontalScrollIndicator={false}
	   onScroll={onScroll}>
	   {menuList.map((item, index) => {
	     return (
			<Touchable
			  key={index}
			  onPress={() => {
			    _pressService(item, index);
			  }}>
			  <View style={styles.serviceItem}>
			    <Image source={item.icon} style={styles.serviceIcon} />
			    <Text style={styles.serviceName}>{item.name}</PFText>
			  </View>
			</Touchable>
	     );
	   })}
	 </ScrollView>
 </View>

这样呢我们的菜单全部拍成一排,并不能像图片那样分页处理,所以我们需要将我们的菜单数组做一点处理,首先我们将菜单数组按每页固定的数分布,比如按照图片中所示,按自己的需求分为每页10个,每页两行,多余的菜单滑动到下一页中,当然,如果你的菜单永远不会变,不会因为登录账号的不同让每个用户看到的菜单不相同的话,可以直接将你的菜单配置改成二维数组的格式:

const menuList = [
	[
		{
			name: '企业信息',
			icon: assets.service_company,
			routerName: 'company'
		},
		{
			name: '企业信息',
			icon: assets.service_company,
			routerName: 'company'
		}
		...
	],
	[
		{
			name: '企业信息',
			icon: assets.service_company,
			routerName: 'company'
		},
	]
]

return (
	<View>
		<ScrollView
		   horizontal={true}
		   pagingEnabled={true}
		   showsHorizontalScrollIndicator={false}
		   onScroll={onScroll}>
		   {menuList.map((item, index) => {
		     return (
				<View key={item.name}>
				  {
					item.map((_item, _index) => (
					  <Touchable
					     key={_index}
					     onPress={() => {
					       _pressService(_item, _index);
					     }}>
					     <View style={styles.serviceItem}>
					       <Image source={_item.uri} style={styles.serviceIcon} />
					       <Text style={styles.serviceName}>{_item.name}</PFText>
					     </View>
					   </Touchable>
					))
				  }
				</View>
		     );
		   })}
		 </ScrollView>
 	</View>
)

但是实际中我们的菜单一般都会涉及到权限,直接写成二位数修改删除一个菜单就需要全部修改整个二维数组,所以配置菜单我们只需要定义一个数组就可以了,思路就是先把我们的数组按每页几个来分我们的数组,一维数组个数作为渲染页数,二维数组的内容来渲染菜单,我们可以先处理我们的菜单数组,筛选我们有权限的菜单,再改造成二维数组,渲染到我们的组件中:

import React, { useState, useEffect } from 'react';
import {
  View,
  ScrollView,
  Text,
  Touchable,
} from 'react-native';
import menus from './menu.js';
import { chunk } from 'lodash';

const MenuView = props => {
  // 活跃的指示器页数
  const [activePage, setActivePage] = useState(0);
   // 菜单列表
  const [menuList, setMenuList] = useState(chunk(menus, 10));
  // 处理我们的数组
  useEffect(_ => {
	...
  } ,[])

  // 当一帧滚动结束的时候调用
  const onScroll = e => {
	let currPage = Math.floor(e.nativeEvent.contentOffset.x / ...);
    activePage !== currentPage && setActivePage(currentPage);
  }
  // 点击菜单跳转对应的路由页面
  const _pressService = item => props.navigation.push(item.routerName);

  // 渲染菜单页
  const _renderScrollItems = item => {
	return item.map((_item, _index) => {
	  return (
	    <Touchable
	      key={_index}
	      onPress={() => {
	        _pressService(_item, _index);
	      }}>
	      <View style={styles.serviceItem}>
	        <Image source={_item.uri} style={styles.serviceIcon} />
	        <Text style={styles.serviceName}>{_item.name}</PFText>
	      </View>
	    </Touchable>
	  );
	});
  }
   // 渲染指示器
  const _renderIndicator = () => {
    let indicatorArr = [];
    for (let i = 0; i < menuList.length; i++) {
      let backgroundColor = i === activePage ? '#ffffff' : '#5B55A0';
      indicatorArr.push(
        <View key={i} style={[styles.indicator, {backgroundColor}]} />,
      );
    }
    return indicatorArr;
  };
  
   return (
    <View style={styles.service}>
      <ScrollView
        horizontal={true}
        pagingEnabled={true}
        showsHorizontalScrollIndicator={false}
        onScroll={onScroll}>
        {menuList.map((item, index) => {
          return (
            <View key={index} style={styles.servicePage}>
              {_renderScrollItems(item)}
            </View>
          );
        })}
      </ScrollView>

      {/*指示器*/}
      <View style={styles.indicatorStyle}>{_renderIndicator()}</View>
    </View>
  );
}

当然这样也只是简单的分页滑动按钮,实际业务中菜单还可能支持用户使用习惯增加自定义的功能,比如拖拽排序等功能。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

small_Axe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值