Подтвердить что ты не робот

React Native <ScrollView> стойкая полоса прокрутки

После просмотра React Native Documentation я, похоже, не мог понять, как сделать <ScrollView> постоянную полосу прокрутки, t исчезают. Как я могу это достичь?

4b9b3361

Ответ 1

IOS

Базовый собственный компонент iOS, UIScrollView (технически, RCTEnhancedScrollView), не поддерживает отображение индикаторов прокрутки. По этой причине оболочка React Native вокруг нее тоже не будет.

Есть хак, чтобы заставить это работать с нативным компонентом (см. этот ответ для одного подхода). Чтобы сделать это в React Native, вам нужно реализовать этот хак на нативной стороне, а затем либо создать собственный Native Module, либо разветкить React Native и изменить их компонент ScrollView.

Тем не менее, рекомендации по интерфейсу iOS Scroll View препятствуют этому, поэтому вы можете оставить поведение индикаторов в покое.

Android

Несколько подходов:

  • установить <item name="android:overScrollMode">always</item>,
  • установить android:fadeScrollbars="false" в XML или
  • установить ScrollView.setScrollbarFadingEnabled(false) в Java (например, в вашем собственном коде собственного моста)

Это также не рекомендуется как нестандартный интерфейс, если у вас нет веских причин для этого.

Ответ 2

Если вы посмотрите на конец, вы можете увидеть метод flashScrollIndicators(), решением "UGLY" будет время, когда он начнет мигать и сделает повторный вызов таймера, который заставит их появиться до их исчезновения.

Я не знаю, будет ли это работать и как это повлияет на производительность, но если вам это действительно нужно, это может быть решение для исправления.

Ответ 3

Я искал решение, но ничего не нашел, тогда я создал решение, надеюсь, поможет вам с этим. Я создал представление View с высотой и шириной и поместил его поверх моего scrollview, после чего я использовал реквизиты scrollview, например onMomentumScrollBegin, onMomentumScrollEnd, onContentSizeChange и onScroll

после этого я создаю условие с булевой переменной, если эта переменная имеет значение false, представление является видимым, если имеет значение false, представление является скрытым. Как активировать эту переменную? с Prop onMomentumScrollBegin, который обнаруживает, когда вы используете scrollView, и таким же образом устанавливаете переменную в false с onMomentumScrollEnd, который обнаруживает, когда прокрутка заканчивается.

Prop onContentSizeChange позволяет мне получить высоту и ширину моего scrollview, эти значения я использовал, чтобы вычислить, где будет установлен scrollbar/scrollIndicator

и, наконец, с помощью Prop On Scroll я получаю позицию.

пример:

<ScrollView 
  onMomentumScrollBegin={() => {this.setvarScrollState()}}
  onMomentumScrollEnd={() => {this.setvarScrollStateRev()}}
  scrollEventThrottle={5} 
  onContentSizeChange={(w, h) => this.state.hScroll = h}
  showsVerticalScrollIndicator={false}
  onScroll={event => { this.state.wScroll = event.nativeEvent.contentOffset.y }}
  style={{ marginVertical: 15, marginHorizontal:15, width: this.state.measurements3.width}}>                    
   {
   Mydata.map((value, index) => {

   return <TouchableOpacity>
           <Text>{ value.MyDataItem }</Text>
          </TouchableOpacity>
       })
   }

функции:

setvarScrollState() {
    this.setState({VarScroll: true});
}

setvarScrollStateRev() {
    this.setState({VarScroll: false});
}

и переменная

this.state = {VarScroll: false}

Тогда мое состояние

!this.state.VarScroll ?
 <View
  style = {{
  marginTop: 200*(this.state.wScroll / this.state.hScroll),
  marginLeft:338.5,
  height: 35,
  width: 2,
  backgroundColor: 'grey',
  position:'absolute'
  }}
  /> 
 : null

Почему 200? потому что это максимальное значение, которое может установить мой marginTop Проверьте картинку enter image description here

Конечная нота: scrollView должен быть внутри вида с другим видом (полоса прокрутки) как то так

<View>
    {/*---- ScrollBar and conditions----*/}
    <View>
    <View>
    <ScrollView>
    </ScrollView>
</View>

Ответ 4

Добавление ответа, поскольку ничего из вышеперечисленного не помогло мне.

Android теперь имеет persistentScrollbar реквизиты.

iOS не поддерживает это. Поэтому я создал решение JS, которое можно использовать следующим образом:

<SBScrollView persistentScrollbar={true}>...</SBScrollView>

По сути, этот класс будет использовать persistentScrollbar для Android, в то время как добавит панель для iOS. Пока это не гладко, но функционально.

import React, { Component } from "react";
import { Platform, View, ScrollView, TouchableOpacity } from "react-native";

class SBScrollView extends Component {
  state = { hScroll: 0, showScrollBar: false };

  componentWillMount() {
    if (this.props.persistentScrollbar) {
      this.setState({ showScrollBar: true });
    }
  }

  render() {
    const { persistentScrollbar, ...attributes } = this.props;

    if (Platform.OS == "android" || !persistentScrollbar) {
      // Abdroid supports the persistentScrollbar
      return (
        <ScrollView persistentScrollbar={persistentScrollbar} {...attributes}>
          {this.props.children}
        </ScrollView>
      );
    }

    const { hScroll, showScrollBar } = this.state;

    // iOS does not support persistentScrollbar, so
    // lets simulate it with a view.
    return (
      <ScrollView
        ref="scrollview"
        showsVerticalScrollIndicator={false}
        onScroll={event => {
          const ratio =
            event.nativeEvent.contentSize.height /
            event.nativeEvent.layoutMeasurement.height;
          let hScroll;
          if (ratio <= 1) {
            this.setState({ showScrollBar: false });
          } else {
            const hScroll = event.nativeEvent.contentOffset.y * ratio;
            this.setState({ hScroll, showScrollBar: true });
          }
        }}
        {...attributes}
      >
        {this.props.children}
        {showScrollBar && (
          <View
            style={{
              position: "absolute",
              top: hScroll,
              right: 3,
              backgroundColor: "#a6a6a6",
              height: 160,
              width: 2
            }}
          ></View>
        )}
      </ScrollView>
    );
  }
}

export default SBScrollView;

Я надеюсь, что это может помочь другим.