-
1.需求
在实际手机开发中经常遇到,需要动态计算文本的高度,尤其在文本列表中,当然你可以实现动态计算ListView 的cell的高度,
请参考:
react native 实现动态高度Listview 和图文混排,但是现在我们的目标是通过普通的组件View 和 text 实现动态计算文本,怎么实现呢?
2.实现思路
1.通过计算每个Item的title 和 text 的高度,比较最大的高度,通过设置item的state改变自身的高度
2.通过Item的回调函数,将每个item 的高度,传给 Item所在的组件
3.item的父组件通过回调过来的Item的高度,通过过滤,计算所有Item的总高度
4.item的父组件 改变自身state,设置自身高度
3.代码实现
item.js
- export default class Item extends Component {
- static defaultProps = {
- title:'',text:'',itemCount:0,titleStyle:View.propTypes.style,textStyle:View.propTypes.style,viewStyle:View.propTypes.style,callBackItemHeight:PropTypes.func
- }
- static propTypes ={
- title:PropTypes.string,text:PropTypes.string,itemCount:PropTypes.number,titleStyle:Text.propTypes.style,textStyle:Text.propTypes.style,callBackItemHeight:PropTypes.func
- }
- constructor(props) {
- super(props);
- this.titleHeight=0;
- this.textHeight=0;
- this.state={
- itemHeight:40
- }
- }
- _titleLayout(event) {
- this.titleHeight=event.nativeEvent.layout.height
- // this.getItemHeight(this.titleHeight,this.textHeight)
- }
- _textLayout(event) {
- this.textHeight=event.nativeEvent.layout.height
- this.getItemHeight(this.titleHeight,this.textHeight)
- }
- getItemHeight(titleHeight,textHeight){
- let maxHeight=titleHeight>textHeight?titleHeight:textHeight
- this.setState({
- itemHeight:maxHeight
- })
- if(this.props.callBackItemHeight){
- this.props.callBackItemHeight(maxHeight)
- }
- this.refs.title.setNativeProps({
- style:{
- top:(this.state.itemHeight-titleHeight)/2,left:16,width:134,backgroundColor:'transparent',height:titleHeight,justifyContent:'center'
- }
- });
- this.refs.text.setNativeProps({
- style:{
- left:10,top:(this.state.itemHeight-textHeight)/2,width:Globle.window.width-170,height:textHeight,justifyContent:'center'
- }
- });
- this.refs.seperate.setNativeProps({
- style:{
- position:'absolute',width:Globle.window.width-16,height:1,backgroundColor:'#1a1a1a',top:this.state.itemHeight-1
- }
- })
- }
- render (){
- let container={height:this.state.itemHeight}
- return(
- <View style={[styles.item,container]}>
- <View ref="title">
- <Text style={{color:'#666666'}} onLayout={this._titleLayout.bind(this)}>
- {this.props.title}
- </Text>
- </View>
- <View ref="text">
- <Text style={{color:'#000000'}} onLayout={this._textLayout.bind(this)}>
- {this.props.text}
- </Text>
- </View>
- <View ref="seperate"></View>
- </View>
- )
- }
- }
- const styles=StyleSheet.create({
- item:{
- flexDirection:'row'
- }
- })
Index.android.js
- export default class Item extends Component {
- static defaultProps = {
- title:'',text:'',itemCount:0,titleStyle:View.propTypes.style,textStyle:View.propTypes.style,viewStyle:View.propTypes.style,callBackItemHeight:PropTypes.func
- }
- static propTypes ={
- title:PropTypes.string,text:PropTypes.string,itemCount:PropTypes.number,titleStyle:Text.propTypes.style,textStyle:Text.propTypes.style,callBackItemHeight:PropTypes.func
- }
- constructor(props) {
- super(props);
- this.titleHeight=0;
- this.textHeight=0;
- this.state={
- itemHeight:40
- }
- }
- _titleLayout(event) {
- this.titleHeight=event.nativeEvent.layout.height
- // this.getItemHeight(this.titleHeight,this.textHeight)
- }
- _textLayout(event) {
- this.textHeight=event.nativeEvent.layout.height
- this.getItemHeight(this.titleHeight,this.textHeight)
- }
- getItemHeight(titleHeight,textHeight){
- let maxHeight=titleHeight>textHeight?titleHeight:textHeight
- this.setState({
- itemHeight:maxHeight
- })
- if(this.props.callBackItemHeight){
- this.props.callBackItemHeight(maxHeight)
- }
- this.refs.title.setNativeProps({
- style:{
- top:(this.state.itemHeight-titleHeight)/2,left:16,width:134,backgroundColor:'transparent',height:titleHeight,justifyContent:'center'
- }
- });
- this.refs.text.setNativeProps({
- style:{
- left:10,top:(this.state.itemHeight-textHeight)/2,width:Globle.window.width-170,height:textHeight,justifyContent:'center'
- }
- });
- this.refs.seperate.setNativeProps({
- style:{
- position:'absolute',width:Globle.window.width-16,height:1,backgroundColor:'#1a1a1a',top:this.state.itemHeight-1
- }
- })
- }
- render (){
- let container={height:this.state.itemHeight}
- return(
- <View style={[styles.item,container]}>
- <View ref="title">
- <Text style={{color:'#666666'}} onLayout={this._titleLayout.bind(this)}>
- {this.props.title}
- </Text>
- </View>
- <View ref="text">
- <Text style={{color:'#000000'}} onLayout={this._textLayout.bind(this)}>
- {this.props.text}
- </Text>
- </View>
- <View ref="seperate"></View>
- </View>
- )
- }
- }
- const styles=StyleSheet.create({
- item:{
- flexDirection:'row'
- }
- })
- var heightArray=[]
- var hh=0
- export default class test extends Component {
- constructor(props) {
- super(props)
- this.state={
- dataSource:[],totalHeight:0
- }
- }
- componentWillMount(){
- this.setState({
- dataSource:[
- {title: '范冰冰',text:"近日,第11届亚洲电影大奖在香港落幕,《我不是潘金莲》获得包括最佳电影、最佳摄影在内的三项大奖,范冰冰凭借该片拿下最佳女主角奖。范冰冰在领奖台上表示,这是送给冯小刚导演的生日礼物,“你是我伯乐,我是你福将”"},{title: '陈数',text:"2009年,凭借《倾城之恋》入围韩国首尔电视节,唯一一位亚洲女演员获 韩国首尔电视节最佳女演员提名。2011年,获得第十七届上海电视节白玉兰奖“最佳女演员”,2011年第六届华鼎奖“最佳女主角”,2012年凭借《铁梨花》荣获“金鹰奖“观众喜爱女演员”奖项"},{title: '胡歌',text:"2005年1月24日,主演的古装仙侠剧《仙剑奇侠传》播出,胡歌饰演豪爽深情的李逍遥,并演唱两首插曲《六月的雨》和《逍遥叹》 "},{title: '何塞·保罗·贝塞拉·马希尔·儒尼奥尔(José Paulo Bezerra Maciel Júnior),简称保利尼奥[1] ,1988年7月25日出生于巴西圣保罗,巴西足球运动员。司职中前卫、后腰等。现效力于中国广州恒大淘宝足球俱乐部',text:"暴力鸟"}
- ]
- })
- }
- renderItem(data,i){
- return(<Item key={i}
- title={data.title}
- text={data.text}
- itemCount={this.state.dataSource.length}
- callBackItemHeight={(h)=>{
- console.log("h===>"+h)
- heightArray.push(h)
- hh+=h
- heightArray.sort().reverse()
- for(let i=0;i<this.state.dataSource.length;i++){
- hh+=heightArray[i]
- }
- this.setState({
- totalHeight:hh
- })
- }
- }
- />)
- }
- render() {
- return (
- <View >
- <View style={{backgroundColor:'white',top:0,height:this.state.totalHeight}}>
- {this.state.dataSource.map((data,i)=>this.renderItem(data,i))}
- </View>
- </View>
- );
- }
- }
4.代码实现效果
- 顶
- 0
- 踩
- 0