TextView заполняется динамически, обрезая последнюю строку текста

Я не уверен, что это только "последняя строка", но у нас есть приложение, которое имеет TextView с шириной fill_parent и высотой wrap_content. Текст вставляется туда динамически из кода Java. Последняя строка текста просто не отображается, хотя в макете достаточно места. Это внутри довольно глубокой иерархии представлений, так что я предполагаю, что мера логики здесь запутана, но это довольно неприятно. Нам нужно угадать, сколько строк будет в тексте, и установить соответственно "android: lines", чтобы оно заработало.

Кто-нибудь видел это? В коде см. Id "contentTextView" внизу. Если я уберу "android: lines", последняя строка текста исчезнет.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:background="@drawable/flag"
        >

    <include android:id="@+id/incHeader" layout="@layout/header"/>

    <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1">

        <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical">

            <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="101dp"
                    android:background="@drawable/headershadow"/>

            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:visibility="invisible"
                    android:layout_weight="1"/>


            <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="101dp"
                    android:background="@drawable/footershadow"/>

        </LinearLayout>

        <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/gybcontentback"
                android:layout_gravity="center_horizontal"
                android:orientation="vertical">

            <include android:id="@+id/gybHeaderInclude" layout="@layout/gybcontentheader"/>


                <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:textColor="#4f4f4f"
                        android:paddingLeft="15dp"
                        android:paddingRight="15dp"
                        android:lines="9"
                        android:id="@+id/contentTextView"/>

            <ImageView
                    android:layout_marginTop="15dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/button_blue_rascal_button"
                    android:id="@+id/buttonMoreInfo"/>

        </LinearLayout>

    </FrameLayout>


    <include android:id="@+id/incFooter" layout="@layout/menu"/>

</LinearLayout>

Java-код Я заполняю TextView стандартной строкой Java во время onCreate.

@Override
protected String body()
{
    return "Rascal Flatts and The Jason Foundation, Inc. are working together to prevent suicide.\n\n" +
            "Your Battle Buddy (or family member) may need a friend.\n\n" +
            "Take the pledge to B1.";
}

Базовый класс вызывает это, чтобы получить фактический текст

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(contentView());
    wireMenu();

    TextView headerText = (TextView) findViewById(R.id.gybHeaderText);
    if(headerText != null)
        headerText.setText(header());

    ((TextView) findViewById(R.id.contentTextView)).setText(body()); // This is where the text is set
}

Во всяком случае, я кипятил это. Я вырезаю части, чтобы посмотреть, что осталось, и все еще получаю ту же проблему. Я думаю, что я нашел триггер и решение, но не "причину".

7 ответов

Решение

Я сварил макет до его основных частей. Вот урезанная версия, которая все еще обрезает текст:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:background="@drawable/flag"
        >


    <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:orientation="vertical">

            <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#4f4f4f"
                    android:id="@+id/contentTextView"/>

            <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/button_blue_rascal_button"
                    android:id="@+id/buttonMoreInfo"/>

        </LinearLayout>



</LinearLayout>

Проблема, я думаю, в том, что родительский LinearLayout получает свою ширину из ImageView внутри него. Где-то в этом миксе TextView получает неправильное значение для своей запрошенной высоты. Я полагаю, это связано с тем, как рассчитывается пользовательский интерфейс. Родитель должен спросить детей об их запрашиваемой ширине, затем вернуться и рассказать всем, какова их ширина, а затем попросить высоту. Что-то вроде того. Во всяком случае, работает следующее. Ширина изображения составляет 263 пикселя (в мдпи), поэтому, если я установлю 263dp вместо wrap_content на родительском макете, все в порядке.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:background="@drawable/flag"
        >


    <LinearLayout
                android:layout_width="263dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:orientation="vertical">

            <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#4f4f4f"
                    android:id="@+id/contentTextView"/>

            <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/button_blue_rascal_button"
                    android:id="@+id/buttonMoreInfo"/>

        </LinearLayout>



</LinearLayout>

Установка TextView на wrap_content тоже работает, хотя затем толкает весь макет больше, чем я хочу.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:background="@drawable/flag"
        >


    <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:orientation="vertical">

            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#4f4f4f"
                    android:id="@+id/contentTextView"/>

            <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/button_blue_rascal_button"
                    android:id="@+id/buttonMoreInfo"/>

        </LinearLayout>



</LinearLayout>

Не уверен, что вынос здесь. Подводя итоги, если вы начнете видеть проблемы с вычисленной высотой, рассмотрите возможность фиксирования ширины там для родителя, просто чтобы расчеты пользовательского интерфейса не запутались.

У меня та же проблема. Я нашел обходной путь. Добавьте новую строку "\n" к вашему тексту. Это всегда будет показывать весь ваш текст.

У меня была другая проблема, но похожая. Вот решение, которое, я думаю, работает и для того, что вам нужно. Вы можете использовать слушателя глобального макета для TextView в любом типе ViewGroup.

    final TextView dSTextView = (TextView)findViewById(R.id.annoyingTextView);
dSTextView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
        dSTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this);

        float lineHeight = dSTextView.getLineHeight();
        int maxLines = (int) (dSTextView.getHeight() / lineHeight);

        if (dSTextView.getLineCount() != maxLines) {
            dSTextView.setLines(maxLines);
        }

    }
});

Вы можете прочитать больше об этом здесь

Вы пытались окружить ваш TextView напрямую с помощью LinearLayout с шириной и высотой, равными wrap_content?

Это сработало для меня...

Ты пытался

android:singleLine="false" 

Попробуйте добавить

Android: обивка

в тебе TextView. работал на меня

Поместите ваш проблемный TextView в FrameLayout(или некоторый контейнер). Я думаю, что проблема из-за вашего взгляда родного брата.

Другие вопросы по тегам