quantumpotato
quantumpotato

Reputation: 9767

How do I set exact height of views in React Native to get a Square grid?

It is my intention to have a 7x7 grid of tiles. I try to make each tile 30 wide and 30 tall. The result is a rectangle wider than it is tall. I want a square.

rectangle

Board.js

    export default class Board extends React.Component {
  render() {
    if (!this.props.rows) {
      return <View></View>
    }

    let rows = this.props.rows;
    return(
    <View style={styles.container}>
      <Row tiles={rows[0]}/>
      <Row tiles={rows[1]}/>
      <Row tiles={rows[2]}/>
      <Row tiles={rows[3]}/>
      <Row tiles={rows[4]}/>
      <Row tiles={rows[5]}/>
      <Row tiles={rows[6]}/>
    </View>);
  }
}

const styles = StyleSheet.create({
  container: {
    height: 210,
    flex: 1,
    flexDirection: 'row',
    width: 210,
    backgroundColor: '#434f4f',
    color: '#000000',
  },
});

Row.js



export default class Row extends React.Component {
  render() {
    let tiles = this.props.tiles;

    return(
    <View style={styles.container}>
      <TileView tile={tiles[0]}/>
      <TileView tile={tiles[1]}/>
      <TileView tile={tiles[2]}/>
      <TileView tile={tiles[3]}/>
      <TileView tile={tiles[4]}/>
      <TileView tile={tiles[5]}/>
      <TileView tile={tiles[6]}/>
    </View>);
  }
}

const styles = StyleSheet.create({
  container: {
    height: 30,
    width: 210,
    flex: 1,
    flexDirection: 'column',
    backgroundColor: '#434f4f',
    color: '#000000',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

TileView:

    export default class TileView extends React.Component {
      render() {
        // return <View></View>;
        // console.log(this.props.data);
        const kind = this.props.tile[0];
        const wall = this.props.tile[1];
        const team = this.props.tile[2];
        console.log("Kind" + kind);
        console.log("Wall" + wall);
        console.log("Team" + team);
        let tileStyle = "teamNone";
        if (team === "o") {
          tileStyle = "teamO";
        } else if (team === "x") {
          tileStyle = "teamX";
        }
        console.log("The style" + tileStyle);
        return <View style="teamNone"><Text>T</Text></View>
      }
    }


        const styles = StyleSheet.create({
      teamX: {
        color: "#77d4d4",
        width: 30,
        height: 30
      },
      teamO: {
        color: "#9ed36c",
        width: 30,
        height: 30
      },
      teamNone: {
        color: "red",
        width: 30,
        height: 30
      }
       });

My main app

    render() {
    if (!this.state) {
      return <View></View>
    }

    const {playerId, yourTurn, opponentTurn, finished} = this.state;

    const overrideRenderItem = ({ item, index, section: { title, data } }) => <Text key={"foo" + index}>Override{item}</Text>

    if (this.state.table) {
      let table = this.state.table;
      console.log("Biscuit");
      console.log(table.board);
      return <View style={styles.boardContainer}>
        <Board rows={table.board}/>
      </View>
    }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    backgroundColor: '#434f4f',
    color: '#000000',
    alignItems: 'center',
    justifyContent: 'center',
  },

  boardContainer: {
    flex: 1,
    flexDirection: 'row',
    backgroundColor: '#434f4f',
    color: '#000000',
    alignItems: 'center',
    justifyContent: 'center',
  },

  buttons: {
    height: 100
  },

  button: {
    color: '#cccccc'
  },

  list: {
    flex: 1
  },

  playerId: {
    marginTop: 100,
    color: "white",
    height: 40
  }
});

How do I exactly set the height and width of my TileViews, Rows and Board such that the total Board is a square with each tile taking up a square shape?

Thank you! Great answer. How can I center the content? I tried running the code changing Text to T and getenter image description here

Upvotes: 0

Views: 612

Answers (1)

Helmer Barcos
Helmer Barcos

Reputation: 2076

Remember that no all devices have the same Width and Height. I recommend you to use Dimensions component from react-native to have your design a bit more responsive. I made an Expo Snack for you click here for see it in action

import { Dimensions } from "react-native"; //in ALL your self created components

// you should declare a constant for both dimensions on the top of the code
const {
  width: MAX_WIDTH,
  height: MAX_HEIGHT,
} = Dimensions.get('window');

change the following property from your MainApp.js Styles

 boardContainer: {
    flex:1,
    height: MAX_HEIGHT,
    width: MAX_WIDTH,
    flexDirection: 'column',
    backgroundColor: '#434f4f',
    alignItems: 'center',
    justifyContent: 'center',
  },

Change the following property style from your Board.js

const styles = StyleSheet.create({
    height: MAX_WIDTH,
    width: MAX_WIDTH,
    flexDirection: 'column',          
    backgroundColor: "white",//'#434f4f', backgroundcolor here doesnt matter
    alignItems: 'center',
    justifyContent: 'center',
    padding:10,
  },
});

Change the following property style from your Row.js

 container: {
  height: ((MAX_WIDTH-20)/7),
  width: (MAX_WIDTH-20),
  flexDirection: 'row',
  backgroundColor: "blue", //'#434f4f',backgroundcolor here doesnt matter
  alignItems: 'center',
  justifyContent: 'space-between', 
 } 

Change the following property style from your TileView.js

teamNone: {
 height:((MAX_WIDTH-22)/7)),
 width: ((MAX_WIDTH-22)/7),
 backgroundColor: "red",
 alignSelf: 'center',
 alignItems: 'center',
 justifyContent: 'center',
 padding:10,
}

Upvotes: 1

Related Questions