리액트 네이티브(React Native)로 인스타그램 UI를 구현하는 다섯번째 강의입니다. 이번에는 프로필 화면의 블로그 영역을 구현합니다. 이 포스팅은 아래 무료 동영상 강의를 참고하여 작성되었습니다.
https://youtu.be/JQuhEe9h9ok
동영상 강의는 이번이 마지막 입니다.
ProfileTab에 세그먼트 버튼 만들기
ProfileTab.js
를 수정합니다. 프로필 화면에 버튼 4개를 만듭니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <View style ={{ flexDirection: 'row ', justifyContent: 'space-around ', borderTopWidth:1 ,borderTopColor: '#eae5e5 ' }}> <Button transparent > <Icon name ='ios-apps' /> </Button > <Button transparent > <Icon name ='ios-list' /> </Button > <Button transparent > <Icon name ='ios-people' /> </Button > <Button transparent > <Icon name ='ios-bookmark' /> </Button > </View >
아래와 같이 프로필 화면에 아이콘 버튼 4개가 나타났습니다.
세그먼트 버튼에 이벤트 만들기
그다음은 각 버튼을 누르면 버튼이 활성화된 상태로 보이도록 구현합니다. 우선 state
에 activeIndex
를 선언합니다.
1 2 3 4 state = { activeIndex : 0 , }
그리고 senmentClicked()
함수를 입력합니다.
1 2 3 4 5 senmentClicked = (activeIndex ) => { this .setState({ activeIndex }); }
senmentClicked()
함수가 호출되면 전달된 값으로 state.activeIndex
가 업데이트됩니다.
그다음은 버튼을 선택하면 senmentClicked()
함수가 호출되도록 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <View style ={{ flexDirection: 'row ', justifyContent: 'space-around ', borderTopWidth:1 ,borderTopColor: '#eae5e5 ' }}> <Button transparent onPress ={() => this.segmentClicked(0)} active={this.state.activeIndex === 0}> <Icon name ='ios-apps' style ={[ this.state.activeIndex === 0 ? {} : {color: 'grey '} ]}/> </Button > <Button transparent onPress ={() => this.segmentClicked(1)} active={this.state.activeIndex === 1}> <Icon name ='ios-list' style ={[ this.state.activeIndex === 1 ? {} : {color: 'grey '} ]}/> </Button > <Button transparent onPress ={() => this.segmentClicked(2)} active={this.state.activeIndex === 2}> <Icon name ='ios-people' style ={[ this.state.activeIndex === 2 ? {} : {color: 'grey '} ]}/> </Button > <Button transparent onPress ={() => this.segmentClicked(3)} active={this.state.activeIndex === 3}> <Icon name ='ios-bookmark' style ={[ this.state.activeIndex === 3 ? {} : {color: 'grey '} ]}/> </Button > </View >
각 Button 의 onPress
속성에 {() => this.segmentClicked(0)}
를 입력합니다. segmentClicked()
에는 각 버튼에 해당하는 인덱스 번호를 전달합니다. 그리고 선택된 버튼은 active 속성이 true
가 됩니다. 그리고 선택되지 않은 버튼은 아이콘이 회색으로 표시되도록 하였습니다.
여기까지 작업하고 앱을 확인해봅니다.
선택한 버튼이 활성화되는 효과가 보이나요?
선택한 버튼에 따라 세그먼트 화면 전환하기
이제 선택한 버튼에 따라 화면에 다른 내용이 보여지게 합니다. renderSection()
함수를 입력합니다.
1 2 3 4 5 6 7 8 9 export default class ProfileTab extends Component { renderSection = () => { if (this .state.activeIndex === 0 ) { return <View > <Text > This is first section</Text > </View > } }
우리는 버튼을 선택하면 해당 버튼의 인덱스를 state.activeIndex
에 저장하였습니다. state.activeIndex
값에 따라서 다른 화면 내용이 보여지게 합니다.
버튼 영역 바로 아래에 { this.renderSection() }
코드를 입력합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <View style ={{ flexDirection: 'row ', justifyContent: 'space-around ', borderTopWidth:1 ,borderTopColor: '#eae5e5 ' }}> <Button transparent onPress ={() => this.segmentClicked(0)} active={this.state.activeIndex === 0}> <Icon name ='ios-apps' style ={[ this.state.activeIndex === 0 ? {} : {color: 'grey '} ]}/> </Button > <Button transparent onPress ={() => this.segmentClicked(1)} active={this.state.activeIndex === 1}> <Icon name ='ios-list' style ={[ this.state.activeIndex === 1 ? {} : {color: 'grey '} ]}/> </Button > <Button transparent onPress ={() => this.segmentClicked(2)} active={this.state.activeIndex === 2}> <Icon name ='ios-people' style ={[ this.state.activeIndex === 2 ? {} : {color: 'grey '} ]}/> </Button > <Button transparent onPress ={() => this.segmentClicked(3)} active={this.state.activeIndex === 3}> <Icon name ='ios-bookmark' style ={[ this.state.activeIndex === 3 ? {} : {color: 'grey '} ]}/> </Button > </View > {/* 아래 코드 추가 */} { this.renderSection() }
이제 첫번째 버튼을 선택하면 아래와 같은 화면이 표시됩니다.
첫번째 세그먼트 화면 구현하기
아래와 같이 이미지 더미 데이터를 입력합니다. 이미지 URL은 pixabay 에서 임의로 가져왔습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let images = [ "https://cdn.pixabay.com/photo/2018/11/29/21/19/hamburg-3846525__480.jpg" , "https://cdn.pixabay.com/photo/2018/11/11/16/51/ibis-3809147__480.jpg" , "https://cdn.pixabay.com/photo/2018/11/23/14/19/forest-3833973__480.jpg" , "https://cdn.pixabay.com/photo/2019/01/05/17/05/man-3915438__480.jpg" , "https://cdn.pixabay.com/photo/2018/12/04/22/38/road-3856796__480.jpg" , "https://cdn.pixabay.com/photo/2018/11/04/20/21/harley-davidson-3794909__480.jpg" , "https://cdn.pixabay.com/photo/2018/12/25/21/45/crystal-ball-photography-3894871__480.jpg" , "https://cdn.pixabay.com/photo/2018/12/29/23/49/rays-3902368__480.jpg" , "https://cdn.pixabay.com/photo/2017/05/05/16/57/buzzard-2287699__480.jpg" , "https://cdn.pixabay.com/photo/2018/08/06/16/30/mushroom-3587888__480.jpg" , "https://cdn.pixabay.com/photo/2018/12/15/02/53/flower-3876195__480.jpg" , "https://cdn.pixabay.com/photo/2018/12/16/18/12/open-fire-3879031__480.jpg" , "https://cdn.pixabay.com/photo/2018/11/24/02/05/lichterkette-3834926__480.jpg" , "https://cdn.pixabay.com/photo/2018/11/29/19/29/autumn-3846345__480.jpg" , ];
그다음 Dimensions
를 import 합니다. 그리고 window 에서 width
와 height
를 가져옵니다.
1 2 3 import { View, Text, StyleSheet, Image, Dimensions } from 'react-native' ;const { width, height } = Dimensions.get('window' );
renderSectionOne()
함수를 입력합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 export default class ProfileTab extends Component { renderSectionOne = () => { return images.map((image, index ) => { return ( <View key ={index} style ={{ width: width /3 , height: width /3 }} > <Image source ={{ url: image }} style ={{ flex:1 }}/> </View > ) }) }
renderSectionOne()
함수는 Image 를 화면 너비의 1/3 정사각형 크기로 출력합니다.
그리고 renderSection()
함수를 수정합니다.
1 2 3 4 5 6 7 8 9 renderSection = () => { if (this .state.activeIndex === 0 ) { return ( <View style ={{flexDirection: 'row ',flexWrap: 'wrap '}}> { this.renderSectionOne() } </View > ) } }
state.activeIndex
가 0이면, renderSectionOne()
함수를 호출합니다.
앱 화면을 확인해보면 아래와 같이 표시됩니다.
내 스팀잇 블로그 글 표시하기
두 번째 버튼에 해당하는 세그먼트에는 내 스팀잇 블로그 글을 출력해보도록 합니다. 내 스팀잇 블로그 정보를 가져오는 fetchState()
함수를 구현합니다. fetchState()
함수를 이용하여 내 블로그 글을 표시해보도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 export default class ProfileTab extends Component { fetchState (username ) { const data = { id : 3 , jsonrpc : "2.0" , method : "call" , params : [ "database_api" , "get_state" , [`/@${username}` ] ] }; return fetch('https://api.steemit.com' , { method : 'POST' , body : JSON .stringify(data) }) .then(res => res.json()) .then(res => res.result[0 ]) }
자세한 구현 내용은 ProfileTab.js 파일을 참고하세요.
아래는 완성된 화면입니다.
작업한 코드는 모두 깃허브에 업로드되어 있습니다.
https://github.com/anpigon/rn_instagram_clone
여기까지 읽어주셔서 감사합니다.
시리즈