Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: Image is coming partially black on Android when used in conjunction with ScrollView! #525

Closed
rohanstomar11 opened this issue Apr 9, 2024 · 3 comments

Comments

@rohanstomar11
Copy link

Image is coming partially black on Android when used in conjunction with ScrollView

Version: 0.72.4

Platform: Android

Expected behavior

When Image is generated of the ScrollView Component, The image should take the actual height of the scrollview, and generate the component as Image.

Actual behavior

Image is taking actual height of the scrollview but the image is partially coming black.

Steps to reproduce the behavior

I have attached a reproducible sample on this repo: https://github.com/rohanstomar11/view-shot.git.
Also, added the resultant image at the bottom.

Sample Code:

import React, {useRef} from 'react';
import type {PropsWithChildren} from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  TouchableOpacity,
  useColorScheme,
  View,
} from 'react-native';
import {captureRef} from 'react-native-view-shot';

import {
  Colors,
  DebugInstructions,
  Header,
  LearnMoreLinks,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
import Share from 'react-native-share';

type SectionProps = PropsWithChildren<{
  title: string;
}>;

function Section({children, title}: SectionProps): JSX.Element {
  const isDarkMode = useColorScheme() === 'dark';
  return (
    <View style={styles.sectionContainer}>
      <Text
        style={[
          styles.sectionTitle,
          {
            color: isDarkMode ? Colors.white : Colors.black,
          },
        ]}>
        {title}
      </Text>
      <Text
        style={[
          styles.sectionDescription,
          {
            color: isDarkMode ? Colors.light : Colors.dark,
          },
        ]}>
        {children}
      </Text>
    </View>
  );
}

function App(): JSX.Element {
  const isDarkMode = useColorScheme() === 'dark';

  const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
  };

  const viewShotRef = useRef();

  const captureScreenshot = () => {
    setTimeout(() => {
      captureRef(viewShotRef, {
        fileName: 'trial@platter',
        snapshotContentContainer: true,
        format: 'png',
      })
        .then((uri: any) => {
          Share.open({url: uri})
            .then(() => {})
            .catch(() => {});
        })
        .catch(() => {});
    }, 250);
  };

  return (
    <SafeAreaView style={backgroundStyle}>
      <StatusBar
        barStyle={isDarkMode ? 'light-content' : 'dark-content'}
        backgroundColor={backgroundStyle.backgroundColor}
      />
      <ScrollView
        contentInsetAdjustmentBehavior="automatic"
        style={backgroundStyle}
        ref={viewShotRef}>
        <Header />
        <View
          style={{
            backgroundColor: isDarkMode ? Colors.black : Colors.white,
          }}>
          <Section title="Step One">
            Edit <Text style={styles.highlight}>App.tsx</Text> to change this
            screen and then come back to see your edits.
          </Section>
          <Section title="See Your Changes">
            <ReloadInstructions />
          </Section>
          <Section title="Debug">
            <DebugInstructions />
          </Section>
          <Section title="Learn More">
            Read the docs to discover what to do next:
          </Section>
          <LearnMoreLinks />
          <TouchableOpacity onPress={captureScreenshot}>
            <Text>Take it</Text>
          </TouchableOpacity>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  sectionContainer: {
    marginTop: 32,
    paddingHorizontal: 24,
  },
  sectionTitle: {
    fontSize: 24,
    fontWeight: '600',
  },
  sectionDescription: {
    marginTop: 8,
    fontSize: 18,
    fontWeight: '400',
  },
  highlight: {
    fontWeight: '700',
  },
});

export default App;

Resultant Image
Screenshot_1712692019

@rohanstomar11
Copy link
Author

@gre Please help if possible.
Thank you.

@rrameshbtech
Copy link

@rohanstomar11
I was facing similar issue. When I was trying to capture the content of ScrollView, non screen area content was showing as blank even though I set snapshotContentContainer: true for captureRef function.

So I added <View collapsable="false"> inside <ScrollView> like below. It started capturing full content.

<ScrollView contentInsetAdjustmentBehavior="automatic">
  <View style={{ flex: 1}} collapsable={false} ref={viewRef} >
    // Content goes here
  </View>
</ScrollView>
const uri = await captureRef(viewRef, {
  fileName: `sample-file`,
  format: "jpg",
  quality: 0.8,
})

@rohanstomar11
Copy link
Author

@rohanstomar11 I was facing similar issue. When I was trying to capture the content of ScrollView, non screen area content was showing as blank even though I set snapshotContentContainer: true for captureRef function.

So I added <View collapsable="false"> inside <ScrollView> like below. It started capturing full content.

<ScrollView contentInsetAdjustmentBehavior="automatic">
  <View style={{ flex: 1}} collapsable={false} ref={viewRef} >
    // Content goes here
  </View>
</ScrollView>
const uri = await captureRef(viewRef, {
  fileName: `sample-file`,
  format: "jpg",
  quality: 0.8,
})

Thanks @rrameshbtech.
It worked for me.

Although How It worked for me was:
1.) I transferred the viewShotRef object from ScrollView to the child View Inside it
2.) I had to remove the snapshotContentContainer: true from the captureScreenshot function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants