在安卓中,textview.getLineCount总是为0。

39

我试图动态调整我的TextView的大小,但是getlinecount()方法始终返回0,即使在settext()和invalidate()之后。 我正在使用以下代码:

if (convertView == null) {
    convertView = lInflater.inflate(R.layout.listview, null);
    holder = new ViewHolder();
    holder.text2 = (TextView)convertView.findViewById(R.id.TextView02);
    convertView.setTag(holder);
} else {
    holder = (ViewHolder)convertView.getTag();
}

holder.text2.setText(arr2[position]);
holder.text2.invalidate();

int lineCnt = holder.text2.getLineCount();

holder 是一个静态类,如下所示:

static class ViewHolder {
    TextView text2;
}

holder包含非空文本2,且内容设置也非空。

7个回答

92

我知道这个问题很老了,但万一有人在这里找寻实际答案:

holder.text2.setText(arr2[position]);
holder.text2.post(new Runnable() {
    @Override
    public void run() {
        int lineCnt = holder.text2.getLineCount();
        // Perform any actions you want based on the line count here.
    }
});

5
此方法需要 TextView 的可见性为 VISIBLE 或 INVISIBLE。当其为 GONE 时,此方法无法生效。 - Mustafa Berkay Mutlu
1
在Android中使用线程是否正确,因为我已经被建议不要使用线程来完成这个任务? - cammando
根据我的经验,post()方法有时仍然会在布局传递之前被调用。这种情况偶尔发生,但在这些情况下,即使在所提及的Runnable内部,我们仍然会得到行数为0的值。 - Kurovsky
是的,这个答案已经有9年了,在这段时间里发生了很多变化。我不再从事Android方面的工作,所以无法告诉您最新的方法来完成这个任务。 - Scott

27

为了解决这个问题,请应用以下几行代码:

textView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (textView.getLineCount() > 1) {
            textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    }
});

OnGlobalLayoutListener 会在每次更改 TextView(测量、绘制后)后被调用。在这里,您可以捕获屏幕上绘制之前对TextView的更改,并对其进行必要的操作。

代码中的最后一行是为了移除监听器,这很重要,因为我们不希望继续捕获每个布局更改。


mediaAtomLayout是什么? - ericn
我猜mediaAtomLayout在这里代表我们的TextView。 - cammando

24

应该使用post方法在UI线程上完成。

textView.post(new Runnable() {
    @Override
    public void run() {
        Log.v("Line count: ", textView.getLineCount()+"");
    }
});

它能正常工作,但是它是如何工作的?因为我只在 UI 线程中将文本设置到了 TextView 上,而没有使用 textView.post,为什么它没有返回行数呢? - adi

10

在布局过程完成后,getLineCount() 才会给出正确的行数。也就是说,TextView 必须至少绘制一次。 我假设此时您的 TextView 还没有被绘制,因此您得到的行数为 0。


谢谢Rahul。没错,但我担心即使在setText()之后也不知道该设置这个高度的位置。 - neha
我不确定这段代码现在放在哪里。但是,如果您将其放置在getview下面,则仅在返回该位置的视图对象后才显示/绘制文本。 - DeRagan

4
实际上,TextView.getLineCount() 依赖于 TextView.mLayout.getLineCount,但是 TextView.mLayout 是在 onMeasure 之前进行延迟初始化的。您可以像这样操作:
       if (holder.contentTV.getLayout() == null) {
            holder.contentTV.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    holder.contentTV.getLineCount();
                    holder.contentTV.getViewTreeObserver().removeOnPreDrawListener(this);
                    return true;
                }
            });
        } else {
            holder.contentTV.getLineCount();
        }

0

我创建了一个简单易用的扩展:

/**
 * Function for detect when layout completely configure.
 */
fun View.afterLayoutConfiguration(func: () -> Unit) {
    viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            viewTreeObserver?.removeOnGlobalLayoutListener(this)
            func()
        }
    })
}

使用示例:

textView.afterLayoutConfiguration {
    val lineCount = textView.lineCount
    ...
}

-1
我创建了一个异步任务类,并在它的onPostExecute方法中完成了与getLineCount()相关的任务。
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    new myAsyncTask().execute(null, null, null);
}

private class myAsyncTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(final Void... params) {
        // It's okay to leave this as it is
        return null;
    }

    @Override
    protected void onPostExecute(final Void result) {
        super.onPostExecute(result);
        //DO YOUR TASK HERE, getLineCount(), etc.       
    }
}

7
如果有任何反对意见,可能是因为使用计时器等待布局完成存在风险,因为没有保证在异步任务运行时布局就已经完成。监听布局/绘图相关的事件会更好(我还没有代码,否则我会发布它)。 - eselk
有风险吗?不是有风险,而是错误! - Marian Paździoch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接