首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Android TextView inside ListView直到手动滚动后才能测量正确的高度。

在Android开发中,当我们将TextView放置在ListView中时,有时候会遇到一个问题:TextView的高度无法正确测量,直到手动滚动ListView后才能得到正确的高度。

这个问题的原因是ListView的item在初始渲染时,会根据屏幕上可见的item数量进行快速测量和布局,以提高性能。而TextView的高度计算需要根据其内容进行动态调整,因此在初始渲染时无法得到准确的高度。

解决这个问题的方法是通过监听ListView的滚动事件,在滚动结束后重新测量TextView的高度。具体步骤如下:

  1. 在ListView的适配器中,为每个TextView设置一个全局变量用于保存其高度。
  2. 在getView()方法中,为每个TextView设置一个OnGlobalLayoutListener监听器,用于在布局完成后获取其高度。
  3. 在OnGlobalLayoutListener的onGlobalLayout()方法中,获取TextView的高度并保存到全局变量中。
  4. 在ListView的OnScrollListener中,监听滚动事件,在滚动结束后重新测量TextView的高度。

以下是一个示例代码:

代码语言:txt
复制
public class MyAdapter extends BaseAdapter {
    private List<String> data;
    private int[] textHeights;

    public MyAdapter(List<String> data) {
        this.data = data;
        textHeights = new int[data.size()];
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
            holder = new ViewHolder();
            holder.textView = convertView.findViewById(R.id.text_view);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.textView.setText(data.get(position));
        holder.textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                textHeights[position] = holder.textView.getHeight();
                holder.textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });

        return convertView;
    }

    public int getTextHeight(int position) {
        return textHeights[position];
    }

    private static class ViewHolder {
        TextView textView;
    }
}

public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = findViewById(R.id.list_view);
        List<String> data = new ArrayList<>();
        // 添加数据到data中
        adapter = new MyAdapter(data);
        listView.setAdapter(adapter);
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (scrollState == SCROLL_STATE_IDLE) {
                    // 滚动结束后重新测量TextView的高度
                    int firstVisiblePosition = listView.getFirstVisiblePosition();
                    int lastVisiblePosition = listView.getLastVisiblePosition();
                    for (int i = firstVisiblePosition; i <= lastVisiblePosition; i++) {
                        View view = listView.getChildAt(i - firstVisiblePosition);
                        if (view != null) {
                            int position = i;
                            int height = adapter.getTextHeight(position);
                            TextView textView = view.findViewById(R.id.text_view);
                            textView.setHeight(height);
                        }
                    }
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            }
        });
    }
}

在上述代码中,我们通过自定义适配器MyAdapter来管理TextView的高度。在getView()方法中,我们为每个TextView设置了一个OnGlobalLayoutListener监听器,在布局完成后获取其高度并保存到全局变量textHeights中。在ListView的OnScrollListener中,我们监听滚动事件,在滚动结束后重新测量TextView的高度并设置。

这样,当ListView滚动时,TextView的高度就能正确地被测量和设置了。

推荐的腾讯云相关产品:腾讯云移动应用分析(MTA),该产品提供了丰富的移动应用数据分析功能,可帮助开发者深入了解用户行为和应用性能,优化应用体验。产品介绍链接地址:https://cloud.tencent.com/product/mta

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Android开发那些坑和小技巧

但如果在列表如ListView中,用错了问题就大了。ListViewgetView方法需要计算列表条目,那就必然需要确定ListView高度,onMesure才能测量。...如果嵌套View过于复杂,解决方案可以是通过代码测量列表所需要高度,或者在getView中使用一个小技巧:parent.getChildCount == position @Override public...6、ScrollView嵌套ListView 这样设计是不是很奇怪?两个同样会滚动View居然放到了一起,而且还是嵌套关系。...服务端返回荣誉图片,由于是3列显示方式,只需要计算需要显示几行,然后给定行间距和图片高度,再设置setLayoutParams就行了。...ListView inside ScrollView is not scrolling on Android (http://stackoverflow.com/questions/6210895/listview-inside-scrollview-is-not-scrolling-on-android

1.1K30

Android从零单排系列四十六】《Android中自定义ListView实现方法》

一  ListView 介绍 ListViewAndroid经典列表控件,用于展示一组垂直滚动项目。...基本功能支持:ListView 提供了基本滚动和点击事件处理,可以通过设置点击监听器来响应用户点击操作。...这可能导致滚动卡顿或列表加载速度慢。 有限布局灵活性:默认情况下,ListView 每个列表项使用相同布局结构。...缺少分页支持:ListView 不支持自动分页加载数据,要实现分页效果,需要手动监听滚动事件并加载下一页数据。...固定高度限制:ListView 默认情况下要求每个列表项具有相同高度,这限制了列表项灵活性。如果列表项高度不同,需要重写适配器来处理不同高度情况。

32220
  • 智能下拉刷新框架-SmartRefreshLayout

    框架 如果你看完了效果图,或许框架意思应该有所了解了~~SmartRefreshLayout对下拉刷新功能进行系统拆分、组合,主要由四个部分组成: RefreshLayout 下拉基本功能,包括布局测量... 在 Android Studio 中预览效果图 和 运行效果图 ?...这好办呀,一般我们会开开心心下下这样代码: <LinearLayout android:orientation="vertical"> <TextView android...View) 和多层嵌套 Layout 支持自定义并且已经集成了很多炫酷 Header 和 Footer 支持和ListView同步滚动 和 RecyclerView、AppBarLayout、CoordinatorLayout...支持自动刷新、自动上拉加载(自动检测列表滚动到底部,而不用手动上拉). 支持通用刷新监听器 OnRefreshListener 和更详细滚动监听 OnMultiPurposeListener.

    3.6K50

    Android仿QQ空间顶部条背景变化效果

    一、上代码,具体实现 笔者之前文章第二部分总是二话不说,直接上代码,很干脆,其实更好方式是引导读者思考:这个效果如何实现。前期做好效果功能分析,才能读者更好理解。...那么我们要自定义View是哪一个,明显是样式变化ListView,因为它长和普通ListView不一样,“谁家ListView顶个黑色矩形做头部” ①自定义View代码段——核心代码段 package...* 拿到ListView滚动事件 * 拿到高度变化 * 根据高度变化,设置顶部条背景 * powered by Cpf.com. */ public class ScrollChangeHeadView...} 本段代码是核心代码段:我们在这段代码里做了最关键三件事: 1)拿到在自定义View内部拿到ListView滚动事件; 2)在滚动事件里面拿到矩形头部高度变化; 3)根据矩形头部高度变化...,作用就是获得一个View高度,在滚动事件里调用这个方法,就可以不断得到View高度数据,以便于当做参数值传入setAlpha()方法中。 ②自定义ViewXML布局文件 <?

    67750

    android scrollview嵌套listview计算高度问题

    但是为啥在scrollview中嵌套listview会出现只显示第一条listitem高度呢,原因是:scrollviewontach方法滚动事件消费处理,ListView控件高度设定问题 从谷歌那里找到...高度 但是这个代码里面有一个问题,就是这个当你ListView里面有多行TextView的话,ListView高度就会计算错误,它只算到了一行TextView高度, 这个问题在so上概述为以下...这个问题头疼了一阵,查找了一下,应该重写一个TextViewonMeasure方法比较好解决 代码有 @Override   protected void onMeasure(int widthMeasureSpec...开始测量时,测量TextView时,就调用我们onMeasure方法,我们就可以测量字体总宽度除与去掉边距屏幕大小,就可以算出文字要几行来显示,然后测量字体高度*行数可以得到字体高度,然后在加上上下边距就是...TextView真正高度,然后setMeasuredDimension进去就可以计算出正确值出来。

    2.3K60

    Android中文API——ScrollView

    TextView类也有自己滚动功能,所以不需要使用ScrollView,但是只有两个结合使用,才能保证显示较多内容时候效率。但只有两者结合使用才可以实现在一个较大容器中一个文本视图效果。...,并且前提需要正确执行View.onTouchEvent(MotionEvent)。...如果此方法被重写,那么子类责任是确认测量高度测量宽度要大于视图view最小宽度和最小高度(getSuggestedMinimumHeight() 和getSuggestedMinimumWidth...参数 w     视图当前宽度 h     视图当前高度 oldw       视图改变前宽度 oldh       视图改变前高度   六、补充 文章精选 Android ApiDemos.../ScrollView2 添加自动滚动和智能焦点切换 [Android学习指南]使用ScrollView实现滚动效果 Android中ScrollView与ListView共用问题解决方案   示例代码

    4.6K30

    抢购倒计时自定义控件实现与优化

    ,第一个参数是系统测量该View得到规格值,这里使用0代表省略(在系统对该View绘制之前就直接调用了measure方法,所以宽高为0,该值与最终获取宽高无关),第二个参数MeasureSpec.UNSPECIFIED...获取完成也就顺利完成具体view宽度测量。 通过该方法返回值,我们就可以控制两个倒计时view展示与隐藏,从而达到自适应折行展示效果。...,数字相同位绘制新数字,数字不同位一起移动即可; 4、在移动数字时,需要将旧数字向上移动,移动距离是 0 至 负最大滚动距离;同时要将新数字向上移动,移动距离为最大滚动距离 至 0;其中最大滚动距离是数字滚动控件高度...其中,最大滚动距离mMaxMoveHeight是UI稿中时/分/秒数字控件整体高度;画笔设置字体颜色、大小等,均为UI稿中时/分/秒数字字体颜色、大小等。...变为负最大滚动距离mMaxMoveHeight;每次计算出新滚动距离,调用invalidate()方法,触发onDraw()方法,不断地绘制旧数字和新数字,以实现数字滚动效果。

    1.5K30

    android ListView 嵌套 ListView

    实现效果是这个样子 看上去效果还是不错,不过现在有个刷新问题一直没能解决,刷新时候里面的adapter进行刷新时候总是会让里面的listview消失掉,应该是父listview先刷新完,子...listview还未刷新完成,导致测量高度不对,就会消失,像当前组已关闭这种,现在这个问题还没有想到办法解决,试过比较多方法,添加接口让子listview 刷新完成再去更新父listview,但还是没有作用...,我猜应该是在刷新子listview时候,父listview先更新完成,子listview高度测量就没有对!...下面是我源码 listview 嵌套listview都有个高度测量问题,在更新时候动态更新子listview就,下面是布局源码 <?...高度,因为我这边子listviewitem高度是50dp,这里可以自己修改 listpar.height = dp2px(50*viewHolder.adapter.getCount

    1.3K20

    Android带你解析ScrollView--仿QQ空间标题栏渐变

    参照fadingEdgeLength效果图 android:fadingEdgeLength 设置边框渐变长度 android:scrollX 以像素为单位设置水平方向滚动偏移值,在GridView...中可看这个效果 android:scrollY 以像素为单位设置垂直方向滚动偏移值 android:scrollbarAlwaysDrawHorizontalTrack 设置是否始终显示垂直滚动条...android:scrollbarDefaultDelayBeforeFade 设置N毫秒开始淡化,以毫秒为单位。...android:background="#00000000" /> 最外层是我们自定义ScrollView,包裹着一张背景图片和一个ListViewListView...image.png 然后我们需要获取图片高度,并且设置滚动监听,随着滚动距离来设置标题栏颜色透明度和字体颜色透明度 /** * 获取顶部图片高度,设置滚动监听 */

    1.5K10

    Android从零单排系列二十】《Android视图控件——ListView

    ListView基本介绍 ListViewAndroid开发中常用列表视图控件,用于展示垂直滚动可变长度数据列表。...功能:ListView可以在有限屏幕空间内显示大量数据,并支持用户滚动浏览。它提供了一个可滚动列表容器,可以逐项地展示数据元素。...数据源:ListView通过与适配器(Adapter)配合使用来提供数据。适配器负责将数据与每个列表项进行绑定,以便正确渲染和展示。...android:layout_height:指定ListView高度,可以使用具体数值(如"match_parent"、"wrap_content")或者具体数值。...android:dividerHeight:设置列表项之间分割线高度,可以使用具体数值和单位(如"dp")。

    54910

    浅谈Android RecyclerView UI滚动控件示例

    还有就是只能够纵向滚动,如果要想实现横向移动,用 ListView 是做不到。 RecyclerView 可以说是一个增强版 ListView 。...它不仅实现了和 ListView 同样效果,而且还优化了 ListView 存在各种不足。...RecyclerView 现在可是官方推荐使用滚动控件哦O(∩_∩)O~ 1 基本用法 RecyclerView 也是新增控件,所以必须先在项目的 build.gradle 中添加相应依赖库才能使用...: compile 'com.android.support:recyclerview-v7:24.2.1' 注意不要拼错哦O(∩_∩)O~ 添加,记得点击 Sync Now 链接哦。...recyclerView 示例 我们使用了 recyclerView 创建出了 ListView 效果,而且代码逻辑更清晰咯。 2 横向滚动 现在让我们把这些猫变为 “横向滚动” 吧。

    85410

    从0系统学Android--3.5 最常用和最难用控件---ListView

    数据不能直接传递给 ListView 需要借助适配器来完成。Android 中提供了许多适配器实现类。...这里使用最简单 ArrayAdapter ,android.R.layout.simple_list_itme_1 是 Android 内置布局文件,里面只有一个简单 TextView。...getItem() 方法在每个子项被滚动到屏幕内时候都会被调用。...,第三个参数指定成 false 表示只让我们在父布局中声明 layout 属性生效,其实就是为了测量一下这个生成布局,但是不会将这个 View 添加到父布局中,因为一旦 View 有了父布局,就不能再添加到...因为在 getView() 方法中每次都将布局重新加载了一遍,当 ListView 快速滚动时候,性能就会出现问题。

    59210
    领券