web-dev-qa-db-ja.com

ScrollViewの下部にビューを配置するにはどうすればよいですか?

ScrollViewにいくつかの入力フィールドがあり、画面の下部にボタン(通常のビューでは実際には2つのボタン)がある画面を作成したいと思います。これはかなり簡単ですが、ボタンを画面の一番下に配置したいScrollViewに十分な要素がない場合でも、画面全体に表示されます。絶対配置を使用することもできますが、ScrollViewを画面より大きく(高く)することができます。この場合、ボタンはScrollViewの最後に配置する必要があります。 (つまり、画面の外に表示されます。つまり、ユーザーがボタンを表示するには、スクロールダウンする必要があります)。

私は多くのことを試しましたが、ボタンは常にScollView内の他の要素の直後に来ます。

画像では、スクロールビューには青い境界線があり、ボタンを含む通常のビューには黒い境界線があります。

任意の提案をいただければ幸いです。

enter image description here

8
Márk Farkas

最適なソリューションを見つけました。

キーはcontentContainerStyleプロパティです(ドキュメント: https://facebook.github.io/react-native/docs/scrollview#contentcontainerstyle )。 「これらのスタイルは、すべての子ビューをラップするスクロールビューコンテンツコンテナーに適用されます。」

flexGrow:1、justifyContent: 'space-between'、flexDirection: 'column'をcontentContainerStyleに設定すると、justifyContent: 'flex-startを設定できます'はテキスト付きの上部コンテナービュー用、justifyContent:' flex-end 'はボタン付きの下部コンテナービュー用です。

<ScrollView
  contentContainerStyle={{ flexGrow: 1, justifyContent: 'space-between', flexDirection: 'column' }}
  style={{ backgroundColor: 'white', paddingBottom: 20 }}
>
  <View style={{ flex: 1, justifyContent: 'flex-start' }}>
    <Text>Some text with different length in different cases, or some input fileds.</Text>
  </View>
  <View style={{ flex: 1, justifyContent: 'flex-end' }}>
    <View>
      <TouchableOpacity style={[commonStyles.greenButton, styles.buttonPadding]}>
        <Text style={commonStyles.greenButtonTitle}>Next</Text>
      </TouchableOpacity>
    </View>
    <View>
      <TouchableOpacity style={styles.cancelButtonContainer}>
        <Text style={styles.cancelButton}>Cancel</Text>
      </TouchableOpacity>
    </View>
  </View>
</ScrollView>;
21
Márk Farkas

これの回避策を見つけました。

主な考え方はビューの高さを設定するテキストと入力フィールドを使用する画面の高さからボタンを含むビューを差し引いたものと正確に一致させるです。

課題は、この高さを計算することです。 Abhishek Kumarの答えが私を助けました( https://stackoverflow.com/a/41398953/4109477 )以下の私のコードを参照してください:

         import { View, ScrollView, Text, TouchableOpacity, Dimensions } from 'react-native';

         const screenHeight = Dimensions.get('window').height;

          class MyClass extends React.Component {

          constructor(props) {
            super(props);
            this.state = {buttonViewHeight: 0};
          }

          find_dimesions(layout){
            this.setState({buttonViewHeight: layout.height});
          }
          render() {
            return (
              <View style={{minHeight: screenHeight, flex: 1, alignItems: 'center'}}>
                <ScrollView style={{minHeight: screenHeight}}>
                 <View style={{minHeight: screenHeight}}>
                    <View style={{minHeight: screenHeight - this.state.buttonViewHeight, borderWidth: 2, borderColor: 'red', alignItems: 'center', flex: 1}]}>
                      <Text>Some text with different length in different cases, or some input fileds.</Text>
                    </View>
                    <View onLayout={(event) => { this.find_dimesions(event.nativeEvent.layout) }} style={{paddingBottom: 50, flex: 1, borderWidth: 2, borderColor: 'green'}}>
                      <TouchableOpacity
                        style={[commonStyles.greenButton, styles.buttonPadding]} >
                        <Text style={commonStyles.greenButtonTitle}>Next</Text>
                      </TouchableOpacity>
                      <TouchableOpacity
                        style={styles.cancelButtonContainer} >
                        <Text style={styles.cancelButton}>Cancel</Text>
                      </TouchableOpacity>
                    </View>
                  </View>
                </ScrollView>
              </View>
          }
   }

下の写真で結果を見ることができます

This is how it looks now

このソリューションは、ビューの高さが変更されるため、ビューが複数回レンダリングされるときにアニメーションのような効果を引き起こします。画面を開くと、ボタンのビューは「フェードイン」します。

より良い解決策を見つけた場合はお知らせください!

0
Márk Farkas