React Native 实现动态计算文本高度

本文介绍了一种使用React Native中的普通组件View和Text动态计算文本高度的方法。通过计算每个Item的title和text高度并调整Item的高度,实现了列表项高度的自适应布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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,
        viewStyle:View.propTypes.style,
        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,
                backgroundColor:'transparent',
                justifyContent:'center'
            }
        });
        this.refs.seperate.setNativeProps({
            style:{
               position:'absolute',left:16,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
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.代码实现效果





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值