如何在 React Native App 中显示超链接?

How does one Display a Hyperlink in React Native App?

如何在 React Native 应用程序中显示超链接?

例如

<a href="https://google.com>Google</a> 

像这样:

<Text style={{color: 'blue'}}
      onPress={() => Linking.openURL('http://google.com')}>
  Google
</Text>

使用与 React Native 捆绑在一起的 Linking 模块。

import { Linking } from 'react-native';

所选答案仅参考iOS。对于这两个平台,您可以使用以下组件:

import React, { Component, PropTypes } from 'react';
import {
  Linking,
  Text,
  StyleSheet
} from 'react-native';

export default class HyperLink extends Component {

  constructor(){
      super();
      this._goToURL = this._goToURL.bind(this);
  }

  static propTypes = {
    url: PropTypes.string.isRequired,
    title: PropTypes.string.isRequired,
  }

  render() {

    const { title} = this.props;

    return(
      <Text style={styles.title} onPress={this._goToURL}>
        >  {title}
      </Text>
    );
  }

  _goToURL() {
    const { url } = this.props;
    Linking.canOpenURL(url).then(supported => {
      if (supported) {
        Linking.openURL(this.props.url);
      } else {
        console.log('Don\'t know how to open URI: ' + this.props.url);
      }
    });
  }
}

const styles = StyleSheet.create({
  title: {
    color: '#acacac',
    fontWeight: 'bold'
  }
});

如果要做链接等类型的富文本,更全面的方案是使用React Native HTMLView.

对于 React Native,有用于在 App 中打开超链接的库。 https://www.npmjs.com/package/react-native-hyperlink

除此之外,我想您还需要检查 url,最好的方法是正则表达式。 https://www.npmjs.com/package/url-regex

为此,我强烈考虑将 Text 组件包装在 TouchableOpacity 中。当 TouchableOpacity 被触摸时,它会消失(变得不那么透明)。这会在用户触摸文本时立即提供反馈,并提供更好的用户体验。

您可以在 TouchableOpacity 上使用 onPress 属性 来实现 link:

<TouchableOpacity onPress={() => Linking.openURL('http://google.com')}>
  <Text style={{color: 'blue'}}>
    Google
  </Text>
</TouchableOpacity>

使用 React Native 超链接(原生 <A> 标签):

安装:

npm i react-native-a

进口:

import A from 'react-native-a'

用法:

  1. <A>Example.com</A>
  2. <A href="example.com">Example</A>
  3. <A href="https://example.com">Example</A>
  4. <A href="example.com" style={{fontWeight: 'bold'}}>Example</A>

React Native 文档建议使用 Linking:

Reference

这是一个非常基本的用例:

import { Linking } from 'react-native';

const url="https://google.com"

<Text onPress={() => Linking.openURL(url)}>
    {url}
</Text>

您可以使用函数式或 class 组件符号,由经销商选择。

只是想我会与现在发现这个问题的任何人分享我的 hacky 解决方案,其中 嵌入链接 在字符串中。它尝试 内联链接 通过使用输入的任何字符串动态呈现链接。

请随时根据您的需要进行调整。它正在为我们的目的而工作:

这是 https://google.com 的显示示例。

在 Gist 上查看:

https://gist.github.com/Friendly-Robot/b4fa8501238b1118caaa908b08eb49e2

import React from 'react';
import { Linking, Text } from 'react-native';

export default function renderHyperlinkedText(string, baseStyles = {}, linkStyles = {}, openLink) {
  if (typeof string !== 'string') return null;
  const httpRegex = /http/g;
  const wwwRegex = /www/g;
  const comRegex = /.com/g;
  const httpType = httpRegex.test(string);
  const wwwType = wwwRegex.test(string);
  const comIndices = getMatchedIndices(comRegex, string);
  if ((httpType || wwwType) && comIndices.length) {
    // Reset these regex indices because `comRegex` throws it off at its completion. 
    httpRegex.lastIndex = 0;
    wwwRegex.lastIndex = 0;
    const httpIndices = httpType ? 
      getMatchedIndices(httpRegex, string) : getMatchedIndices(wwwRegex, string);
    if (httpIndices.length === comIndices.length) {
      const result = [];
      let noLinkString = string.substring(0, httpIndices[0] || string.length);
      result.push(<Text key={noLinkString} style={baseStyles}>{ noLinkString }</Text>);
      for (let i = 0; i < httpIndices.length; i += 1) {
        const linkString = string.substring(httpIndices[i], comIndices[i] + 4);
        result.push(
          <Text
            key={linkString}
            style={[baseStyles, linkStyles]}
            onPress={openLink ? () => openLink(linkString) : () => Linking.openURL(linkString)}
          >
            { linkString }
          </Text>
        );
        noLinkString = string.substring(comIndices[i] + 4, httpIndices[i + 1] || string.length);
        if (noLinkString) {
          result.push(
            <Text key={noLinkString} style={baseStyles}>
              { noLinkString }
            </Text>
          );
        }
      }
      // Make sure the parent `<View>` container has a style of `flexWrap: 'wrap'`
      return result;
    }
  }
  return <Text style={baseStyles}>{ string }</Text>;
}

function getMatchedIndices(regex, text) {
  const result = [];
  let match;
  do {
    match = regex.exec(text);
    if (match) result.push(match.index);
  } while (match);
  return result;
}

从 React Native 导入链接模块

import { TouchableOpacity, Linking } from "react-native";

试一试:-

<TouchableOpacity onPress={() => Linking.openURL('http://Facebook.com')}>
     <Text> Facebook </Text>     
</TouchableOpacity>

要添加到上述响应中的另一个有用说明是添加一些 flexbox 样式。 这将使文本保持在一行上,并确保文本不会与屏幕重叠。

 <View style={{ display: "flex", flexDirection: "row", flex: 1, flexWrap: 'wrap', margin: 10 }}>
  <Text>Add your </Text>
  <TouchableOpacity>
    <Text style={{ color: 'blue' }} onpress={() => Linking.openURL('https://www.google.com')} >
         link
    </Text>
   </TouchableOpacity>
   <Text>here.
   </Text>
 </View>

您可以使用链接 属性 <文字样式={{颜色:'skyblue'}} onPress={() => Linking.openURL('http://yahoo.com')}> 雅虎

Linking.openURL('http://yahoo.com')}> https://google.com

以上代码将使您的文本看起来像超链接

我能够使用以下内容将可触摸的子字符串与周围的文本对齐。固定边距数字有点老套,但如果您不需要将其用于一种以上的字体大小,就足够了。否则,您可以将边距作为道具与 BaseText 组件一起传递。

import styled, { StyledComponent } from 'styled-components'
import { View, Linking, Text, TouchableOpacity } from 'react-native'

type StyledTextComponent = StyledComponent<typeof Text, any, {}, never>

export interface TouchableSubstringProps {
  prefix: string
  substring: string
  suffix: string
  BaseText: StyledTextComponent
  onPress: () => void
}

export const TouchableSubstring = ({
  prefix,
  substring,
  suffix,
  BaseText,
  onPress,
}: TouchableSubstringProps): JSX.Element => {
  const UnderlinedText = styled(BaseText)`
    text-decoration: underline;
    color: blue;
  `

  return (
    <TextContainer>
      <Text>
        <BaseText>{prefix}</BaseText>
        <TextAlignedTouchableOpacity onPress={onPress}>
          <UnderlinedText>{substring}</UnderlinedText>
        </TextAlignedTouchableOpacity>
        <BaseText>{suffix}</BaseText>
      </Text>
    </TextContainer>
  )
}

const TextContainer = styled(View)`
  display: flex;
  flex: 1;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 10px;
`

const TextAlignedTouchableOpacity = styled(TouchableOpacity)`
  margin-top: 1px;
  margin-bottom: -3px;
`

以下是实现超链接的方法,该超链接带有下划线并且具有 web-standard 单击时改变颜色的行为(如 CSS a:active)。

import { Linking, Pressable, Text } from 'react-native';

  <Pressable onPress={() => Linking.openURL('https://example.com')}>
    {({ pressed }) =>
      <Text style={{
        textDecorationLine: 'underline',
        color: pressed ? 'red' : 'blue'
      }}>I'm a hyperlink!</Text>
    }
  </Pressable>
  • 一些现有答案使用 TextLinkingTouchableOpacity,但 docs 声明 Pressable 更“future-proof" 而不是 TouchableOpacity,所以我们改用 Pressable
  • Text本身实际上有一个onPress()属性,所以TouchableOpacity对于简单的处理压力是不必要的。但是,仅使用 Text 似乎无法实现颜色样式更改。