Реагуйте нативним колонтитулом


128

Я намагаюся створити власний додаток для реагування, схожий на існуючий веб-додаток. У мене внизу вікна фіксований колонтитул. Хтось має уявлення, як цього можна досягти за допомогою реагуючих рідних?

у існуючому додатку це просто:

.footer {
  position: fixed;
  bottom: 0;
}

Відповіді:


167

Зверху моєї голови ви могли це зробити за допомогою ScrollView . Ваш контейнер верхнього рівня може бути гнучким контейнером, усередині якого розташований ScrollView, а нижній - нижній колонтитул. Потім всередині ScrollView просто поставте решту програми як звичайну.


працює чудово =) thx, щойно доданий heightу Footer View, і це добре виглядає на 4 та 6
4ега

1
Це працює. Але я не міг зрозуміти, чому. Чому це працює?
Адіті

171

Ось власне код на основі відповіді Коліна Рамсей:

<View style={{flex: 1}}>
  <ScrollView>main</ScrollView>
  <View><Text>footer</Text></View>
</View>

1
Так, я спробував це, але без флексу не працював: D Дякую за натиск, щоб спробувати його знову :) І якщо ви натиснули на вхід, я хочу згадати про використання onContentSizeChange. Отже, що я робив, я прокручував прокрутку вгорі так: onContentSizeChange = {(ширина, висота) => this.refs.scrollView.scrollTo ({y: this.state.onInputSelectScrollViewPaddingSize})}
Ернестіно

1
це не працює. я не можу зрозуміти, чому це спрацювало б у будь-якому випадку
Паулу Роберто Роза

63

Я використовую фіксовані колонтитули для кнопок у своєму додатку. Те, як я реалізую фіксований колонтитул, виглядає так:

<View style={{flex: 1}}>
<View><Text>my text</Text></View>
<View style={{position: 'absolute', left: 0, right: 0, bottom: 0}}><Text>My fixed footer</Text></View>
</View>

І якщо вам потрібно, щоб колонтитул рухався вгору при появі, наприклад, клавіатури, ви можете використовувати:

const {  DeviceEventEmitter } = React

class MyClass {
  constructor() {
     this.state = {
       btnLocation: 0
     }
  }

  componentWillMount() {
     DeviceEventEmitter.addListener('keyboardWillShow', this.keyboardWillShow.bind(this))
     DeviceEventEmitter.addListener('keyboardWillHide', this.keyboardWillHide.bind(this))
  }

  keyboardWillShow(e) {
    this.setState({btnLocation: e.endCoordinates.height})
  }

  keyboardWillHide(e) {
    this.setState({btnLocation: 0})
  }
}

Потім використовуйте {bottom: this.state.btnLocation} у своєму фіксованому колонтитулі. Я сподіваюся, що це допомагає!


2
Хто не отримує "невизначений", це не об'єкт (оцінюючи "DeviceEventEmitter.addListener") "", намагаючись зробити "this.setState (...)" на слухачах клавіатури?
Джон Сардінья

Спробуйте import { Keyboard} from 'react-native'; Keyboard.addListener('keyboardWillShow', this.showHandler)натомість @JohnSardinha .
maxhungry

23

Спочатку ви отримуєте розмір, а потім маніпулюєте ним за допомогою стилю flex

var Dimensions = require('Dimensions')
var {width, height} = Dimensions.get('window')

У візуалізації

<View style={{flex: 1}}>
    <View style={{width: width, height: height - 200}}>main</View>
    <View style={{width: width, height: 200}}>footer</View>
</View>

Інший метод - використовувати флекс

<View style={{flex: 1}}>
    <View style={{flex: .8}}>main</View>
    <View style={{flex: .2}}>footer</View>
</View>

17

@Alexander Дякую за рішення

Нижче наведено код саме того, що ви шукаєте

import React, {PropTypes,} from 'react';
import {View, Text, StyleSheet,TouchableHighlight,ScrollView,Image, Component, AppRegistry} from "react-native";

class mainview extends React.Component {
 constructor(props) {
      super(props);

  }

  render() {
    return(
      <View style={styles.mainviewStyle}>
        <ContainerView/>
          <View style={styles.footer}>
          <TouchableHighlight style={styles.bottomButtons}>
              <Text style={styles.footerText}>A</Text>
          </TouchableHighlight>
          <TouchableHighlight style={styles.bottomButtons}>
              <Text style={styles.footerText}>B</Text>
          </TouchableHighlight>
          </View>
      </View>
    );
  }
}

class ContainerView extends React.Component {
constructor(props) {
      super(props);
}

render() {
    return(
      <ScrollView style = {styles.scrollViewStyle}>
          <View>
            <Text style={styles.textStyle}> Example for ScrollView and Fixed Footer</Text>
          </View>
      </ScrollView>
    );
  }
}

var styles = StyleSheet.create({
  mainviewStyle: {
  flex: 1,
  flexDirection: 'column',
},
footer: {
  position: 'absolute',
  flex:0.1,
  left: 0,
  right: 0,
  bottom: -10,
  backgroundColor:'green',
  flexDirection:'row',
  height:80,
  alignItems:'center',
},
bottomButtons: {
  alignItems:'center',
  justifyContent: 'center',
  flex:1,
},
footerText: {
  color:'white',
  fontWeight:'bold',
  alignItems:'center',
  fontSize:18,
},
textStyle: {
  alignSelf: 'center',
  color: 'orange'
},
scrollViewStyle: {
  borderWidth: 2,
  borderColor: 'blue'
}
});

AppRegistry.registerComponent('TRYAPP', () => mainview) //Entry Point    and Root Component of The App

Нижче - Скріншот

ScrollView з фіксованим колонтитулом


Гарний приклад :)
joey rohan

7

Ви також можете поглянути на NativeBase ( http://nativebase.io ). Це бібліотека компонентів для React Native, які містять гарну структуру компонування ( http://nativebase.io/docs/v2.0.0/components#anatomy ), включаючи заголовки та колонтитули.

Це трохи схоже на Bootstrap для мобільних пристроїв.


1
Він не включає макет для фіксованого колонтитула.
svlada

7

Тут прості речі:

Якщо вам не потрібен ScrollView для цього підходу, ви можете скористатися наведеним нижче кодом, щоб досягти чогось подібного:

Щось на зразок цього

<View style={{flex: 1, backgroundColor:'grey'}}>
    <View style={{flex: 1, backgroundColor: 'red'}} />
    <View style={{height: 100, backgroundColor: 'green'}} />
</View>

7

Нижче наведено код для встановлення нижнього колонтитулу та елементів.

import React, { Component } from 'react';
import { StyleSheet, View, Text, ScrollView } from 'react-native';
export default class App extends Component {
    render() {
      return (
      <View style={styles.containerMain}>
        <ScrollView>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
          <Text> Main Content Here</Text>
        </ScrollView>
        <View style={styles.bottomView}>
          <Text style={styles.textStyle}>Bottom View</Text>
        </View>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  containerMain: {
    flex: 1,
    alignItems: 'center',
  },
  bottomView: {
    width: '100%',
    height: 50,
    backgroundColor: '#EE5407',
    justifyContent: 'center',
    alignItems: 'center',
    position: 'absolute',
    bottom: 0,
  },
  textStyle: {
    color: '#fff',
    fontSize: 18,
  },
});

6

Так, як я це зробив, було мати вигляд (давайте назвати його P) з flex 1, то всередині цього виду є ще 2 подання (C1 і C2) з flex 0,9 і 0,1 відповідно (ви можете змінити висоту згинання до потрібних значень) . Потім всередині C1 виберіть прокрутку. Це прекрасно працювало для мене. Приклад нижче.

<View style={{flex: 1}}>
    <View style={{flex: 0.9}}>
        <ScrollView>
            <Text style={{marginBottom: 500}}>scrollable section</Text>
        </ScrollView>
    </View>
    <View style={{flex: 0.1}}>
        <Text>fixed footer</Text>
    </View>
</View>

Додаючи до цього, лівий, правий і нижній стилі значення 0 повинні бути надані для того, щоб він працював.
IVI

5

Можна було б досягти чогось подібного в реакції рідного position: absolute

let footerStyle = {
  position: 'absolute',
  bottom: 0,
}

Однак слід пам’ятати про кілька речей.

  1. absolute позиціонує елемент відносно свого батьківського.
  2. Можливо, вам доведеться встановити ширину та висоту елемента вручну.
  3. Ширина і висота змінюватимуться при зміні орієнтації. Цим потрібно керувати вручну

Практичне визначення стилю виглядатиме приблизно так:

import { Dimensions } from 'react-native';

var screenWidth = Dimensions.get('window').width; //full screen width

let footerStyle = {
  position: 'absolute',
  bottom: 0,
  width: screenWidth,
  height: 60
}

5

Я виявив, що використання флексу є найпростішим рішенням.

<View style={{flex:1, 
    justifyContent: 'space-around', 
    alignItems: 'center',
    flexDirection: 'row',}}>

  <View style={{flex:8}}>
    //Main Activity
  </View>
  <View style={{flex:1}}>
    //Footer
  </View>

 </View>

4

Коли flex є додатним числом, це робить компонент гнучким, і він буде розміром пропорційно його значенню flex. Таким чином, компонент з гнучким набором 2 буде займати вдвічі більше місця, як компонент з гнучким набір 1.

   <View style={{flex: 1}>
            
     <ScrollView>
        //your scroll able content will be placed above your fixed footer content. 
        //when your content will grow bigger and bigger it will hide behind 
        //footer content. 
     </ScrollView>

     <View style={styles.footerContainer}>
        //your fixed footer content will sit fixed below your screen 
     </View>

</View>


1
Будь ласка, подумайте, щоб додати відповідь.
HMD

3

Найкращий спосіб - використовувати властивість justifyContent

<View style={{flexDirection:'column',justifyContent:'flex-end'}}>
     <View>
        <Text>fixed footer</Text>
    </View>
</View>

якщо у вас на екрані кілька елементів перегляду, ви можете використовувати

<View style={{flexDirection:'column',justifyContent:'space-between'}}>
     <View>
        <Text>view 1</Text>
    </View>
    <View>
        <Text>view 2</Text>
    </View>
    <View>
        <Text>fixed footer</Text>
    </View>
</View>

3
import {Dimensions} from 'react-native'

const WIDTH = Dimensions.get('window').width;
const HEIGHT = Dimensions.get('window').height;

то на пишіть ці стилі

 position: 'absolute',
 top: HEIGHT-80,
 left: 0,
 right: 0,

працював як шарм


2

Для проблем Android з цим:

у app / src / AndroidManifest.xml змінити вікноSoftInputMode на таке.

<activity
   android:windowSoftInputMode="stateAlwaysHidden|adjustPan">

У мене не було абсолютно ніяких проблем з цим у ios, використовуючи рідну реакцію та клавіатуруAwareScroll. Я збирався реалізувати тонну коду, щоб зрозуміти це, поки хтось не дав мені це рішення. Працювали чудово.


2

якщо ви просто використовуєте рідну реакцію, ви можете використовувати наступний код

<View style={{flex:1}}>

{/* Your Main Content*/}
<View style={{flex:3}}>

<ScrollView>
   {/* Your List View ,etc */}
</ScrollView>

</View>

{/* Your Footer */}
<View style={{flex:1}}>
   {/*Elements*/}
</View>


 </View>

також ви можете використовувати https://docs.nativebase.io/ у своєму реальному проекті, а потім зробити щось на кшталт наступного

<Container>

{/*Your Main Content*/}
<Content>

<ScrollView>
   {/* Your List View ,etc */}
</ScrollView>

</Content>

{/*Your Footer*/}
<Footer>
   {/*Elements*/}
</Footer>

</Container>

React_Native

NativeBase.io


2

Встановіть android: windowSoftInputMode = "коригуватиPan" у вашому файлі маніфесту, і він буде працювати так, як ви очікуєте.


1

Я думаю, що найкращим і простим було б, як нижче, просто розмістіть решту перегляду ур у вмісті, а нижній колонтитул - в окремому вікні.

`<Container>
   <Content>
     <View>
      Ur contents
    </View>
  </Content>
  <View>
  Footer
  </View>
</Container>`

або ви можете використовувати колонтитул з рідної бази

`<Container>
  <Content>
    <View>
Ur contents
    </View>
  </Content>
<Footer>
Footer
</Footer>
</Container>`

1

Пропозиція 1

=> Тіло з фіксованим колонтитулом

<View style={{ flex: 1, backgroundColor: 'gray' }}>

        <View style={{ flex: 9, backgroundColor: 'gray',alignItems: 'center', justifyContent: 'center',  }}>
          <Text style={{color:'white'}}>...Header or Body</Text>
        </View>


        <View style={{ flex: 1, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center', }}>
          <Text>...Footer</Text>
        </View>

</View>

Демонстраційне зображення

Редагувати 2

=> Body & Fixed footer з вкладками

<View style={{ flex: 1, backgroundColor: 'gray' }}>

        <View style={{ flex: 9, backgroundColor: 'gray', alignItems: 'center', justifyContent: 'center', }}>
          <Text style={{ color: 'white' }}>...Header or Body</Text>
        </View>


        <View style={{ flex: 1, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center', }}>
          <View style={{ flex: 1, flexDirection: 'row' }}>
            <TouchableOpacity style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' }}>
              <View>
                <Text>
                  ...Home
              </Text>
              </View>
            </TouchableOpacity>
            <TouchableOpacity style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' }}>
              <View>
                <Text>
                  ...Settings
              </Text>
              </View>
            </TouchableOpacity>
          </View>
        </View>
</View>

введіть тут опис зображення

Примітки

import {TouchableOpacity} in 'react-native'

Переваги

Ми можемо використовувати цей простий колонтитул без реагування на нижню навігацію

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.