首页 > 解决方案 > 如何在 WebView 组件中调整 YouTube 预览缩略图的尺寸,因为它过大且过大?

问题描述

如果您访问此网址:

https://www.youtube.com/embed/ZZ5LpwO-An4?rel=0&autoplay=0&showinfo=0&controls=0

然后在 Chrome 中将其切换到移动模式,它将如下所示: 优酷问题

尝试使用 WebView 加载 YouTube 时会出现同样的问题,如下所示:

<WebView style={{ flex: 1 }} source={{ uri: url }} />;

如何使用 WebView 组件正确缩放图像?

标签: react-native

解决方案


这是我找到的最干净的解决方案。56.25% 是 315/560(宽度/高度),这是固有比率。

            const html =
                '<html><body><meta name="viewport" content="device-width, initial-scale=1,maximum-scale=1.0, user-scalable=1.0">' +
                '<div style="display: flex; justify-content: center; align-items: center; height: 100%"><div style="position: relative; width: 100%; height: 0; padding-bottom: 56.25%;">' +
                `<iframe width="560" height="315" src="${url}" frameborder="0" style="position:absolute; width: 100%; height: 100%; left: 0; top: 0" allow="autoplay; encrypted-media" allowfullscreen></iframe>` +
                '</div></div>' +
                '</body></html>';

            return <WebView style={{ flex: 1 }} source={{ html }} />;

对于显示 YouTube 视频的完整解决方案,您可以执行以下操作:

import * as React from 'react';
import { AppState, WebView } from 'react-native';
import { Container, Header, Title, Content, Button, Right, Body, Left, Icon } from 'native-base';
import styles from '../services/Styles';

export default class extends React.Component {
    state = {
        appState: AppState.currentState,
    };
    componentDidMount() {
        AppState.addEventListener('change', this._handleStateChange);
    }
    componentWillUnmount() {
        AppState.removeEventListener('change', this._handleStateChange);
    }
    _handleStateChange = nextAppState =>
        this.setState({
            appState: nextAppState,
        });

    render() {
        const { params: { url, label, isYouTube } } = this.props.navigation.state;
        const { appState } = this.state;

        if (isYouTube) {
            // YouTube videos will play in the background on some devices if
            // we do not destroy the WebView when the app goes into the
            // background.
            // This is required to comply with YouTube policies and to
            // be accepted into the Google Play store.
            if (appState !== 'active') return null;

            // Create an intrinsic ratio for videos using this technique:
            // https://alistapart.com/article/creating-intrinsic-ratios-for-video
            const html =
                '<html><body><meta name="viewport" content="device-width, initial-scale=1,maximum-scale=1.0, user-scalable=1.0">' +
                '<div style="display: flex; justify-content: center; align-items: center; height: 100%"><div style="position: relative; width: 100%; height: 0; padding-bottom: 56.25%;">' +
                `<iframe width="560" height="315" src="${url}" frameborder="0" style="position:absolute; width: 100%; height: 100%; left: 0; top: 0" allow="autoplay; encrypted-media" allowfullscreen></iframe>` +
                '</div></div>' +
                '</body></html>';

            return <WebView style={{ flex: 1 }} source={{ html }} />;
        }

        return (
            <Container style={styles.container}>
                <Header>
                    <Left>
                        <Button transparent onPress={() => this.props.navigation.goBack()}>
                            <Icon name="arrow-back" />
                        </Button>
                    </Left>
                    <Body style={{ flex: 2 }}>
                        <Title>{label}</Title>
                    </Body>
                </Header>
                <Content contentContainerStyle={{ flex: 1 }}>
                    <WebView style={{ flex: 1 }} source={{ uri: url }} />
                </Content>
            </Container>
        );
    }
}

推荐阅读