setText в TextView перезапишет предыдущий текст

У меня есть текстовое представление, которое само по себе является частью линейного макета. XML:

<TextView
    android:id="@+id/label_text"
    android:layout_width="fill_parent"
    android:layout_height="77dp"
    android:layout_marginTop="3dp"/>

В основной программе я сначала установил текстовое представление на значение:

private TextView character_speaking;

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

    character_speaking = (TextView) findViewById(R.id.label_text);
    character_speaking.setText("a text string that was large enough for two lines");
}

Это хорошо работает.

Затем я делаю еще один setText в ответ на нажатие кнопки:

public void handleNextButtonClick(View view) {
    character_speaking.setText("first one line message");
}

И это тоже сработало

Но затем я сделал еще один setText в ответ на еще одно нажатие кнопки:

public void handlePrevButtonClick(View view) {
    character_speaking.setText("second one line message");
}

И грянет беда. Второе однострочное сообщение записывается поверх первого однострочного сообщения без его очистки.

Есть ли способ очистить первое однострочное сообщение перед написанием второго однострочного сообщения?

Я уже пытался обойти эту проблему, используя EditText вместо TextEdit, но это было неприемлемо, поскольку позволяло пользователю писать в поле.


person Craig Roll    schedule 12.03.2014    source источник
comment
Вы пытались использовать character_speaking.setText(); прежде чем пытаться написать второе сообщение?   -  person ElectronicGeek    schedule 12.03.2014
comment
setText() должен очищать предыдущее сообщение. Можете ли вы опубликовать скриншот того, что происходит? Кроме того, если вы хотите использовать EditText, вы можете установить android:inputType="none", который отключит редактирование.   -  person BVB    schedule 12.03.2014
comment
Мне непонятно, что не так, текст перекрывается?   -  person ElectronicGeek    schedule 12.03.2014
comment
Скриншот был бы хорош.   -  person Embattled Swag    schedule 13.03.2014
comment
Я только что попробовал character_speaking.setText(); до второго сообщения и никаких изменений в поведении не было. Второе сообщение было написано поверх первого. Я также пробовал для EditText android:inputType=none, и это не сработало, потому что пользователь все еще может коснуться EditText и открыть всплывающую клавиатуру.   -  person Craig Roll    schedule 13.03.2014
comment
По-настоящему загадочным для меня является то, что первое текстовое сообщение очищается, а второе нет. Кроме того, вещи, которые не работают: заполнение третьего сообщения пробелами, чтобы оно состояло из более чем одной строки, или создание всех сообщений более чем из одной строки.   -  person Craig Roll    schedule 13.03.2014


Ответы (6)


Я столкнулся с этой подобной проблемой. Забавно, что это сработало -> я просто добавил черный цвет фона в свой макет (LinearLayout), и теперь он работает нормально.

Кажется, что фон не очищается, если он не знает, каким цветом его очищать.

person ni_lus    schedule 17.09.2019

Я думаю, что я выбрал обходной путь.

Вместо использования TextEdit (который, очевидно, не может быть использован для того, что я хочу), я буду использовать EditText.

<EditText
    android:id="@+id/label_text"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:hint=""
    android:focusable="false"/>

Последняя строка является ключевой. Это не позволяет пользователю щелкнуть EditText и исказить текст с помощью клавиатуры.

Остальной код — это то, что вы ожидаете:

private EditText character_speaking;

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

    character_speaking = (EditText) findViewById(R.id.label_text);
    character_speaking.setText("a text string that was large enough for two lines");
}

public void handleNextButtonClick(View view) {
    character_speaking.setText("first one line message");
}

public void handlePrevButtonClick(View view) {
    character_speaking.setText("second one line message");
}

и все работает нормально.

person Craig Roll    schedule 12.03.2014

Надеюсь, это укажет вам правильное направление.

Обновлено — рабочий код и описание

Минимальный SDK приложения — 11, целевой SDK — 19.

Мой предыдущий ответ был немного ошибочным, потому что на самом деле вы не можете определить ViewGroup в своем XML. Итак, вам нужно создать базовый LinearLayout с идентификатором ресурса. Вот следующий XML, который я придумал для вас.

Я надеюсь, что это именно то, что вы искали. Я забыл отметить для вас, что вы не можете определить ViewGroup в XML, но вы должны преобразовать свой макет в ViewGroup.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<LinearLayout
    android:id="@+id/textViewHolder"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:orientation="vertical" >
</LinearLayout>

<LinearLayout
    android:id="@+id/buttonBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:orientation="horizontal" 
    style="?android:attr/buttonBarStyle">

    <Button
        android:id="@+id/buttonPrevious"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" 
        android:text="@string/text_Previous"
        style="?android:attr/buttonBarButtonStyle" />

    <Button
        android:id="@+id/buttonNext"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" 
        android:text="@string/text_Next"
        style="?android:attr/buttonBarButtonStyle"/>
</LinearLayout>

My strings.xml:

<?xml version="1.0" encoding="utf-8"?>
 <resources>
  <string name="app_name">TextViewSwitcher</string>
  <string name="text_Previous">Previous</string>
  <string name="text_Next">Next</string>
 </resources>

И, наконец, мой MainActivity.class:

public class MainActivity extends Activity {

// ------------------------------------
// Member Variables

private LinearLayout m_textViewHolder = null;
private Button m_btnPrevious = null;
private Button m_btnNext = null;
private final String m_nothingText = "Nothing Pressed";
private final String m_previousText = "Previous Pressed";
private final String m_nextText = "Next Pressed";


// ------------------------------------
// Class Overrides

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

    // Get a reference to the UI Elements
    m_textViewHolder    = (LinearLayout) findViewById(R.id.textViewHolder);
    m_btnPrevious       = (Button) findViewById(R.id.buttonPrevious);
    m_btnNext           = (Button) findViewById(R.id.buttonNext);

    // Add Listeners to the Buttons
    m_btnPrevious.setOnClickListener(PreviousListener);
    m_btnNext.setOnClickListener(NextListener);

    // Populate the Initial Layout with a new TextView, & set the Text
    TextView nothingTextView = new TextView(getBaseContext());
    nothingTextView.setText(m_nothingText);
    ((ViewGroup) m_textViewHolder).addView(nothingTextView);

}

// -----------------------------------------
// Private Methods

// Creates  a new TextView based on the Text Passed in, and returns the new TextView
private TextView createNewTextView(String text)
{
    TextView newTextView = new TextView(getBaseContext());
    newTextView.setText(text);

    return newTextView;
}

// Removes the Child Views of the Parent ViewGroup
private void removeChildViewsFromParent()
{
    ((ViewGroup) m_textViewHolder).removeAllViews();
}

// -------------------------------------
// Listeners

private OnClickListener PreviousListener = new OnClickListener()
{
    @Override
    public void onClick(View v) 
    {
        removeChildViewsFromParent();
        ((ViewGroup) m_textViewHolder).addView(createNewTextView(m_previousText));

    }

};

private OnClickListener NextListener = new OnClickListener()
{
    @Override
    public void onClick(View v) 
    {
        removeChildViewsFromParent();
        ((ViewGroup) m_textViewHolder).addView(createNewTextView(m_nextText));

    }

};

}

Извините за быстрый ответ, но это дает следующие результаты при нажатии кнопок.

Нажата кнопка Нажата предыдущая кнопка

person kandroidj    schedule 12.03.2014
comment
Я пытался это сделать, но не смог разобрать его. Android не позволит мне добавить .setText в .addView. Не могли бы вы выложить более подробное описание? - person Craig Roll; 13.03.2014
comment
Конечно, я обновлю ответ рабочим примером. Дайте мне несколько минут, пожалуйста. - person kandroidj; 13.03.2014
comment
@CraigRoll см. Обновленный ответ выше, который имеет правильное поведение. - person kandroidj; 13.03.2014

Вы хотели очистить предыдущий текст, верно? Таким образом, вы можете использовать EditText и очистить представление с помощью editText.getText().clear().

Чтобы не сделать его кликабельным, просто используйте editText.setFocusable(false) или editText.setClickable(false). Я бы предпочел использовать setClickable, но попробуйте сами.

person larsaars    schedule 28.10.2017
comment
Пожалуйста, добавьте еще немного текста вашего объяснения. - person Derek Brown; 29.10.2017

У меня была такая же проблема, и это было вызвано тем, как я настроил фрагмент. У меня было два фрейма, работающих одновременно в одном и том же макете.

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

person yzernik    schedule 16.05.2020

Метод TextView.setText(String) всегда будет перезаписывать уже сохраненную строку.

См. документацию по этому методу здесь: http://developer.android.com/reference/android/widget/TextView.html#setText(java.lang.CharSequence)

Если вы хотите добавить предыдущую строку и новую строку, используйте:

TextView.setText(TextView.getText().toString() + String)

person ElectronicGeek    schedule 12.03.2014
comment
-1 Прочитай вопрос. Речь идет не о добавлении текста, а о том, чтобы не удалять старый контент - person Emanuel Moecklin; 13.03.2014