FlatList not working inside BottomSheet on Android - react-native

I am using gorhom/react-native-bottom-sheet
The issue I am facing:
I have a FlatList inside a BottomSheet, I am able to scroll in FlaLlist on ios but it is not working on android.

After a lot of research, I was able to resolve the issue by using BottomSheetFlatList instead of FlatList from the same package.
import { BottomSheetFlatList } from "#gorhom/bottom-sheet";
<BottomSheetFlatList
ref={ref}
initialNumToRender={3}
keyExtractor={(item) => item?.id}
showsVerticalScrollIndicator={false}
maxToRenderPerBatch={3}
windowSize={7}
data={dat}
renderItem={renderItem}
/>
By doing so, it started working fine on android too.
But as I also wanted my Flatlist to auto-scroll using ref on a particular event.
After some research and because of the great documentation of #gorhom/bottom-sheet. I found out the solution in the troubleshooting section of the docs.
But as a developer, StackOverflow is our first go-to place for every issue. So, I decided to post the answer here.
ANSWER
Due to wrapping the content and handle with TapGestureHandler & PanGestureHandler, any gesture interaction would not function as expected.
To resolve this issue, please use ScrollView & FlatList from react-native-gesture-handler provide instead react-native.
import {
ScrollView,
FlatList
} from 'react-native-gesture-handler';
find the original answer here-
https://gorhom.github.io/react-native-bottom-sheet/troubleshooting

Using raw-bottom-sheet raw-bottom-sheet and set "dragFromTopOnly" as true, and any touch operation can be performed i will mention
example below:
<RBSheet
ref={refRBSheet}
dragFromTopOnly={true}
customStyles={{
wrapper: {
backgroundColor: "transparent"
},
draggableIcon: {
backgroundColor: "#000"
}
}}
>`

Related

React Native KeyboardAvoidingView is not working as expected

The screen is Wrapped inside KeyboardAvoidingView and ScrollView components. Some of the last inputs are partially hidden by the keyboard. If I set the behaviour prop to anything, but undefined a white element comes up after keyboard. All I would like to do is to make the screen scroll down like 20 more pixels... I feel like I have tried everything so far, even setting the keyboardVerticalOffset prop, but nothing seems to work. If that offset was transparent it would be perfect...
In the following code a View component is passed to children prop
import { FunctionComponent, ReactNode } from 'react';
import { KeyboardAvoidingView, ScrollView } from 'react-native';
interface WrapperProps {
children: ReactNode;
}
const KeyboardAvoidingWrapper: FunctionComponent<WrapperProps> = ({children}) => {
return (
<KeyboardAvoidingView behavior='height' keyboardVerticalOffset={100}>
<ScrollView>
{children}
</ScrollView>
</KeyboardAvoidingView>
);
};
Instead, You can use react-native-keyboard-aware-scroll-view.
I solved my issue with: react-native-avoid-softinput
INSTALLATION:
yarn add react-native-avoid-softinput
On iOS additionally run: npx pod-install
USAGE:
import React from "react";
import { AvoidSoftInputView } from "react-native-avoid-softinput";
const MyComponent = () => {
return (
<AvoidSoftInputView>
{/** Content that should be pushed above the keyboard */}
</AvoidSoftInputView>
);
};
TROUBLESHOOTING:
requireNativeComponent: "AvoidSoftInputView" was not found in the UIManager.
Solution: https://stackoverflow.com/a/65513391/14056591
Try again cd ios && pod install
If it doesn't help, try restarting the simulator, delete and rebuild the app. Restarting Xcode and metro bundler is also a good idea.
If this does not solve your issue, I came across another promising library, but I did not get to use it: react-native-keyboard-controller

Dark Mode not working React Navigation React Native

I Am working on this to implement Dark Mode in React Native using React Navigation. but it changes only the bottom bar navigator not the screens inside that. can you help me with this
Snack Code
https://snack.expo.io/#belgin/news-app
You're responsible for styling inside your own components. You're styling background as light, setting navigation theme to dark is not gonna magically change the colors you have defined.
For changing themes to work for your components, you need to use the useTheme hook to set colors in your own components instead of hardcoding them.
import * as React from 'react';
import { TouchableOpacity, Text } from 'react-native';
import { useTheme } from '#react-navigation/native';
function MyScreen() {
const { colors } = useTheme();
return (
<View style={{ flex: 1, backgroundColor: colors.background }}>
{/* screen content */}
</View>
);
}
https://reactnavigation.org/docs/themes/#using-the-current-theme-in-your-own-components
Other method is that, you can also create a state which can store your current view-mode (light/dark mode). This is very simple to implement using react-redux. You can refer this video to get better understanding of react and redux.
This is far more simpler implementation of redux.
Note - dependencies such as thunk, react-redux, etc etc are not installed in this video. You can identify which dependencies you're gonna need step-by-step by following error that came in your way. Eg. if createStore gives error try to import createStore as legacy_createstore like done in this question

Flatlist scroll position onScroll

I am building a header that animates/hides as the user scrolls down a Flatlist.
Is there any way to find out the scroll position of the Flatlist in pixels?
I'm using react native 0.59.8.
I've tried using onScroll hoping it passes a value to the callback - it doesn't.
I've also tried onScrollBeginDrag, onScrollEndDrag and onMomentumScrollEnd.. None of them provide information of the current scroll position.
onSroll={(info)=>{console.log(info)}
I would expect to get some information about the scroll, but none is passed.
use the code
<FlatList onScroll={this.handleScrollView} />
handleScrollView: function(event: Object) {
this.setState({ scrollPosition: event.nativeEvent.contentOffset.y });
}
its working
onScroll={(r) => console.log(r.nativeEvent.contentOffset.y)}
post your code here if you want to find bug
A Flatlist, as said in the docs, has all the props of a ScrollView, so as answered here,
Add a handler to your FlatList:
<FlatList onScroll={this.handleScroll} />
And then:
handleScroll: function(event) {
console.log(event.nativeEvent.contentOffset.y);
},

Code reusability in React Native, Ionic, Flutter and NativeScript(write once, use everywhere)

It is the first time that I write that kind of question here so please excuse me if my question is not okay.
I am learning some new cross platform frameworks. I am interesting in Ionic(version 4), Flutter, React Native and NativeScript. Precisely, I would like to understand the concept of code reusability for each framework. How do they apply reusability? In which matrix and what are the consequences?
Thanks.
In react-native you have create any component used any screen. for example I used InputText component for reusability.
InputField.js
import React, { Component } from "react";
import { TextInput, View, StyleSheet, Text,Image } from "react-native";
export class InputField extends Component {
render() {
const {
textentry,
keytype,
isvalid,
errormsg,
returnkey,
textplaceholder,
underlinecolor,
onchangetext
} = this.props;
return (
<View>
<TextInput
style={styles.input}
placeholder={textplaceholder}
keyboardType={keytype}
placeholderTextColor="#ffffff"
underlineColorAndroid={underlinecolor}
secureTextEntry={textentry}
ref={(input) => this.props.inputRef && this.props.inputRef(input)}
returnKeyType={returnkey}
blurOnSubmit={false}
onSubmitEditing={(event) => {
if (returnkey != 'done') {
this.props.onSubmitEditing(event)
}
}}
onChangeText={text => {
this.props.onText(text);
}}
/>
<View>
{!isvalid ? (
<Text style={styles.errormsg}>{errormsg}</Text>
) : null}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
input: {
width: 300,
color: "#ffffff",
justifyContent: "center",
alignItems: "center",
alignSelf: "center"
},
errormsg: {
color: "#ff0000",
marginLeft: 60
},
});
export default InputField;
Use this InputField component to screen
Myscreen.js
import React, { Component } from "react";
import {
View,
StyleSheet
} from "react-native";
import { InputField } from "../component/InputField";
render() {
return (
<View style={{flex:1}}>
<InputField
keytype="default"
textplaceholder="Enter First Name"
textentry={false}
returnkey="next"
isvalid={this.state.firstNameValid}
errormsg={this.state.errormsgtext}
underlinecolor={this.state.underLineColorFirstName}
onText={text => {
this.setState({ firstName: text });
}}
onSubmitEditing={event => {
this.inputs["phone"].focus();
}}
/>
</View>
)}}
About React Native, it works with something called Components. You may create a component for each thing you could imagine. The best of having components is that they are reusables. For example, I can create a button in a component and then export that same button to other apps or screens.
Talking about code sharing between Web and Mobile regarding NativeScript here are a few things to know:
Disclaimer: I am part of the NativeScript team
First it is only possible via Angular, there is not code sharing if you prefer to use pure JS or TypeScript
Second the portion of the code shared between the Web, iOS and Android is dependant on the functionality of your app. Meaning that if you rely heavily on platform specific functionality both for the UI and the code behind logic it is possible to not be able achieve full code shared, yet there are ways to overcome such scenarios and again be able to share common services.
Third the idea of code sharing with NativeScript is that if you have a specific code for a "platform" (Web, iOS and/or Android) you simply create additional file with a specific file name. For example if you have an Angular component named home.component.ts you should have one file containing its HTML for the Web part and one for the Mobile part so you simply create both home.component.html and home.component.tns.html. Similar approach is used for other non component files like css and angular services etc.
The technique that is used to achieve code sharing in NativeScript with Web is with the use of Angular schematics specifically for NativeScript.
The topic of exactly how code sharing is achieve is quite log so I would suggest you to read this blog post that introduces the code sharing between Web, iOS and Android with NativeSript. For a getting started steps I recommend the official documentation here.

React-native: How to control what keyboard pushes up

The structure of the app is fairly simple: A searchbar, a listview and react-native-tabs at the bottom. The problem: If I click on the searchbar on Android it pushes the whole app up, so I see the tabs directly over the keyboard. But on iOS the keyboard overlays the whole app, without pushing anything up. Is there any way to control that?
I'm happy to share code / screenshots if the question isn't clear.
Thanks
edit:
<View style={{flex:1, backgroundColor:'#f2f2f2'}}>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderSearchResults.bind(this)}
style={styles.listView}/>
<KeyboardAvoidingView
style={styles.addQuestionBar}
behavior={'position'}>
<Text>
Don't see your question?
</Text>
<TouchableOpacity>
<Text>
Add it
</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
</View>
Set android:windowSoftInputMode="adjustPan" in your manifest file, and it will work as you expect.
E.g.
<application
android:name=".MainApplication"
android:allowBackup="true"
...
<activity
android:name=".MainActivity"
android:label="#string/app_name"
...
android:windowSoftInputMode="adjustPan">
...
</activity>
...
</application>
For those using Expo
#J KW's answer is correct but if you're using Expo you will have to implement it differently.
Expo uses different configuration terms. In your app.json you have to set the configuration key
"softwareKeyboardLayoutMode":"pan" in your android object.
Your file might look something like:
{
"expo": {
"name": "App",
...
"android":{"softwareKeyboardLayoutMode": "pan"},
...
}
}
Note: If you are receiving a "should NOT have additional property" error, it's likely because you don't have the updated Expo SDK (v.038). Please update your Expo version.
Documentation: https://docs.expo.io/workflow/configuration/
There is new Component called KeyboardAvoidingView from React Native not documented yet but i already use it in my project and its very useful
Code Example:
'use strict'
import { ... , KeyboardAvoidingView } from 'react-native'
class Test extends Component {
constructor () {
super()
this.state = {
behavior: 'position'
// there is three ways to adjust (position , height , padding )
}
}
render(){
return (
<View>
<KeyboardAvoidingView behavior={this.state.behavior}>
<TextInput
style={style.PhoneNumberInput}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
</KeyboardAvoidingView>
</View>
)
}
}
module.exports = Test
and for more details you can check KeyboardAvoidingViewExample
EDIT:
Sorry i just got the wrong idea from the question i think what you are trying to do is stop the android keyboard from pushing the application up here is component that allow you to choose between (Pan, Resize, Nothing) in android
react-native-android-keyboard-adjust
Use android:windowSoftInputMode="adjustResize".
KeyboardAvoidingView and other keyboard-related components don't work quite well if you have "adjustPan" set for your android:windowSoftInputMode in AndroidManifest.xml.
Instead, you should use "adjustResize" and have a wonderful life.
I had "adjustPan" and tried using KeyboardAvoidingView and KeyboardAwareScrollView... nothing worked.
Now, with "adjustResize", i'm not using any keyboard-related component and my android app works. (I might have to use KeyboardAvoiding view on iOS, but it will work out of the box.)
#binkie's answer worked for my expo (Version 44.0.0) app with a slight change.
In app.json,
"android":{"softwareKeyboardLayoutMode": "pan"}
In the screen, margin bottom value equal to height of the bottom tab like so
<ScrollView mb="70px">...</ScrollView>
****1) modify the AndroidMainfest.xml in
android/src/main/AndroidMainfest.xml
u can solve the issue by changing the
$ android:windowSoftInputMode="adjustResize";
to
$ android:windowSoftInputMode="adjustPan";
the problem will be resolvede****