Android: 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, но это было неприемлемо, потому что это позволило пользователю писать в поле.
Заранее спасибо.
4 ответа
Я столкнулся с подобной проблемой. Забавно, что заставило его работать -> Я просто добавил черный цвет фона в свой макет (LinearLayout), и теперь он работает нормально.
Вроде не очищается фон, если не знает, каким цветом его очистить.
Надеюсь, что это указывает вам в правильном направлении.
Обновлено - рабочий код и описание
Минимальное значение 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>
Мой 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));
}
};
}
Извините за быстрый ответ раньше, но это дает следующие результаты при нажатии кнопок.
Вы хотели очистить предыдущий текст, верно? Таким образом, вы можете использовать EditText и очистить вид с помощью editText.getText().clear()
,
Чтобы не сделать его кликабельным, просто используйте editText.setFocusable(false)
или же editText.setClickable(false)
, Я бы лучше использовал setClickable
, но попробуй сам.
У меня была такая же проблема, и она была вызвана тем, как я настроил фрагмент. У меня в макете одновременно работали две фракции в одном и том же макете.
После того, как я удалил лишний фрагмент, проблема решилась.
Я думаю, что я выбрал обходной путь.
Вместо использования 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");
}
и все работает нормально.
Метод TextView.setText(String) всегда будет перезаписывать уже сохраненную строку.
См. Документацию по этому методу здесь: http://developer.android.com/reference/android/widget/TextView.html
Если вы хотите добавить предыдущую строку и новую строку, используйте:
TextView.setText(TextView.getText().toString() + String)