Phản ứng chân cố định bản địa


128

Tôi cố gắng tạo phản ứng ứng dụng gốc trông giống như ứng dụng web hiện có. Tôi có một chân trang cố định ở dưới cùng của cửa sổ. Có ai có ý tưởng làm thế nào điều này có thể đạt được với phản ứng bản địa?

trong ứng dụng hiện có, nó đơn giản:

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

Câu trả lời:


166

Ra khỏi đỉnh đầu tôi, bạn có thể làm điều này với ScrollView . Container cấp cao nhất của bạn có thể là một thùng chứa flex, bên trong có ScrollView ở trên cùng và chân trang của bạn ở phía dưới. Sau đó, bên trong ScrollView chỉ cần đặt phần còn lại của ứng dụng của bạn như bình thường.


hoạt động tuyệt vời =) thx, chỉ cần thêm heightvào phần chân trang Xem và nó có vẻ tốt trên 4s và 6
4ega

1
Những công việc này. Nhưng tôi không thể hiểu tại sao. Tại sao điều này làm việc?
Aditi

171

Đây là mã thực tế dựa trên câu trả lời Ramsay của Colin:

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

1
Có, tôi đã thử nhưng không có flex không hoạt động: D Cảm ơn bạn đã cố gắng thử lại :) Và nếu bạn nhấp vào đầu vào, tôi muốn đề cập đến để sử dụng onContentSizeChange. Vì vậy, những gì tôi đã làm tôi đã cuộn scrollview phía trên như thế này: onContentSizeChange = {(width, height) => this.refs.scrollView.scrollTo ({y: this.state.onInputSelectScrollViewPaddingSize})}
Ernestyno

1
nó không hoạt động. tôi không thể hiểu tại sao nó sẽ hoạt động trong mọi trường hợp
Paulo Roberto Rosa

63

Tôi đang sử dụng chân trang cố định cho các nút trong ứng dụng của mình. Cách tôi triển khai chân trang cố định là như vậy:

<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>

Và nếu cần chân trang di chuyển lên khi bàn phím xuất hiện chẳng hạn, bạn có thể sử dụng:

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})
  }
}

Sau đó sử dụng {bottom: this.state.btnLocation} trong lớp chân trang cố định của bạn. Tôi hi vọng cái này giúp được!


2
Bất cứ ai nhận được 'không xác định không phải là một đối tượng (đánh giá "DeviceEventEuctor.addListener")' khi cố gắng thực hiện 'this.setState (...)' trên trình nghe bàn phím?
John Sardinha

@JohnSardinha Hãy thử import { Keyboard} from 'react-native'; Keyboard.addListener('keyboardWillShow', this.showHandler)thay thế.
maxhungry

23

Bạn nhận được Kích thước đầu tiên và sau đó thao tác nó thông qua kiểu flex

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

Trong kết xuất

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

Phương pháp khác là sử dụng flex

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

17

@Alexander Cảm ơn giải pháp

Dưới đây là mã chính xác những gì bạn đang tìm kiếm

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

Dưới đây là ảnh chụp màn hình

ScrollView với chân trang cố định


Ví dụ hay :)
joey rohan


7

Những thứ đơn giản ở đây:

Trong trường hợp bạn không cần ScrollView cho phương pháp này, bạn có thể đi theo đoạn mã dưới đây để đạt được thứ gì đó như thế này:

Một cái gì đó như thế này

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

7

Dưới đây là mã để đặt chân trang và các yếu tố ở trên.

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

Cách tôi đã làm là có chế độ xem (gọi là P) với flex 1, sau đó bên trong chế độ xem đó có thêm 2 chế độ xem (C1 và C2) với flex 0.9 và 0.1 (bạn có thể thay đổi độ cao flex thành giá trị bắt buộc) . Sau đó, bên trong C1 có một cuộn xem. Điều này làm việc hoàn hảo cho tôi. Ví dụ dưới đây.

<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>

Thêm vào đầu này, các kiểu giá trị 0 bên trái, phải và dưới phải được cung cấp để nó hoạt động.
IVI

5

Người ta có thể đạt được một cái gì đó tương tự trong phản ứng bản địa với position: absolute

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

Có một vài điều cần ghi nhớ mặc dù.

  1. absolute vị trí các yếu tố liên quan đến cha mẹ của nó.
  2. Bạn có thể phải đặt chiều rộng và chiều cao của phần tử theo cách thủ công.
  3. Chiều rộng và cao sẽ thay đổi khi định hướng thay đổi. Điều này phải được quản lý bằng tay

Một định nghĩa phong cách thực tế sẽ trông giống như thế này:

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

Tôi thấy sử dụng flex là giải pháp đơn giản nhất.

<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

Khi flex là một số dương, nó làm cho thành phần linh hoạt và nó sẽ có kích thước tỷ lệ thuận với giá trị flex của nó. Vì vậy, một thành phần có flex set thành 2 sẽ chiếm gấp đôi không gian như một thành phần với flex được đặt thành 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
Vui lòng xem xét thêm một số lời giải thích cho câu trả lời của bạn.
HMD

3

Cách tốt nhất là sử dụng thuộc tính justifyContent

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

nếu bạn có nhiều thành phần xem trên màn hình, thì bạn có thể sử dụng

<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;

sau đó viết kiểu này

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

làm việc như người ở


2

Đối với các sự cố Android với điều này:

trong app / src / AndroidManifest.xml thay đổi windowSoftInputMode thành như sau.

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

Tôi hoàn toàn không gặp vấn đề gì với điều này trong ios khi sử dụng Reac -igen và keyboardAwareScroll. Tôi chuẩn bị thực hiện một tấn mã để tìm ra điều này cho đến khi ai đó đưa cho tôi giải pháp này. Làm việc hoàn hảo.


2

nếu bạn chỉ sử dụng Reac gốc để bạn có thể sử dụng đoạn mã sau

<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>

đồng thời, bạn có thể sử dụng https://docs.nativebase.io/ trong dự án gốc phản ứng của mình và sau đó làm một cái gì đó như sau

<Container>

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

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

</Content>

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

</Container>

Phản ứng_Native

NativeBase.io


2

Đặt android: windowSoftInputMode = "điều chỉnh" trong tệp kê khai của bạn và nó sẽ hoạt động như bạn mong đợi.


1

Tôi nghĩ rằng tốt nhất và dễ dàng sẽ là như dưới đây, chỉ cần đặt phần còn lại của chế độ xem ur trong một nội dung và chân trang trong một chế độ xem riêng biệt.

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

hoặc bạn có thể sử dụng chân trang từ gốc

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

1

Gợi ý 1

=> Thân máy có chân cố định

<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>

Hình ảnh demo

Chỉnh sửa 2

=> Chân & Cố định chân trang với các tab

<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>

nhập mô tả hình ảnh ở đây

Ghi chú

import {TouchableOpacity} in 'react-native'

Ưu điểm

Chúng ta có thể sử dụng chân trang đơn giản này mà không phản ứng điều hướng phía dưới

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.