美文网首页
尽可能地复用代码:StyleSheet

尽可能地复用代码:StyleSheet

作者: 沐风雨木 | 来源:发表于2018-02-27 21:02 被阅读28次

    我们需要“尽可能地复用代码”。
    对于一个小组件来说,我们有大量的跨平台的逻辑是重合的:都是显示文本的按钮,都有 active,hover 状态,他们之间唯一的差别就在于视觉样式上的轻微的差别。所以最好的方式是使用同一个组件,然后在必要的地方,用控制语句来区别。
    示例代码:

    class Segment extends React.Component {
      props: {
        value: string;
        isSelected: boolean;
        selectionColor: string;
        onPress: () => void;
      };
    
    render() {
        var selectedButtonStyle;
        if (this.props.isSelected) {
          selectedButtonStyle = { borderColor: this.props.selectionColor };
        }
        var deselectedLabelStyle;
        if (!this.props.isSelected && Platform.OS === 'android') {
          deselectedLabelStyle = styles.deselectedLabel;
        }
        var title = this.props.value && this.props.value.toUpperCase();
    
        var accessibilityTraits = ['button'];
        if (this.props.isSelected) {
          accessibilityTraits.push('selected');
        }
    
        return (
          <TouchableOpacity
            accessibilityTraits={accessibilityTraits}
            activeOpacity={0.8}
            onPress={this.props.onPress}
            style={[styles.button, selectedButtonStyle]}>
            <Text style={[styles.label, deselectedLabelStyle]}>
              {title}
            </Text>
          </TouchableOpacity>
        );
      }
    }
    

    在这里,我们使用 React Native 的 Platform module,根据代码在不同的平台上运行,应用不同的样式。在这两个平台上,tab 按钮先使用同样的样式,然后分化

    var styles = F8StyleSheet.create({
      container: {
        flexDirection: 'row',
        backgroundColor: 'transparent',
        ios: {
          paddingBottom: 6,
          justifyContent: 'center',
          alignItems: 'center',
        },
        android: {
          paddingLeft: 60,
        },
      },
      button: {
        borderColor: 'transparent',
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'transparent',
        ios: {
          height: HEIGHT,
          paddingHorizontal: 20,
          borderRadius: HEIGHT / 2,
          borderWidth: 1,
        },
        android: {
          paddingBottom: 6,
          paddingHorizontal: 10,
          borderBottomWidth: 3,
          marginRight: 10,
        },
      },
      label: {
        letterSpacing: 1,
        fontSize: 12,
        color: 'white',
      },
      deselectedLabel: {
        color: 'rgba(255, 255, 255, 0.7)',
      },
    });
    

    这里,我们使用一个改造后的 React Native StyleSheet API,可根据平台进行一下选择转换:

    export function create(styles: Object): {[name: string]: number} {
      const platformStyles = {};
      Object.keys(styles).forEach((name) => {
        let {ios, android, ...style} = {...styles[name]};
        if (ios && Platform.OS === 'ios') {
          style = {...style, ...ios};
        }
        if (android && Platform.OS === 'android') {
          style = {...style, ...android};
        }
        platformStyles[name] = style;
      });
      return StyleSheet.create(platformStyles);
    }
    

    现在,我们可以在 app 中复用这个组件了,并且,UI 样式是对 iOS 和 Android 适配的。
    ----------------------我是分割线-------------------------

    分离复杂的差异

    当在两个平台实现一个不仅在 UI 上分化,同时也几乎没有共同业务逻辑的组件时,我们需要采用不同的方式。下面的例子是 app 中的顶级导航菜单:

    image.png
    我们可以看到, iOS 版本使用固定的底部导航,而 Android 则使用侧滑菜单。他们之间在动画,样式,甚至菜单内容本身都存在巨大的差异。比如在 Android 上,有类似 logout 这样的菜单选项。
    正确的做法,我们应该使用 React Native 内置的 特定平台下的扩展。这个特性允许我们创建两个不同的组件,其中一个叫 FBTabsView.ios.js,另外一个叫 FBTabsView.android.js。React Native 会根据运行的平台自动找到并加载他们。
    const FBTabsView= require('./FBTabsView');
    

    相关文章

      网友评论

          本文标题:尽可能地复用代码:StyleSheet

          本文链接:https://www.haomeiwen.com/subject/mbhwoxtx.html