【问题标题】:EditText content get jiberrish and overlaps previous content on orientation changeEditText 内容变得混乱并在方向更改时与以前的内容重叠
【发布时间】:2017-04-22 11:07:34
【问题描述】:

我在 Material Design 下使用 EditText,但屏幕方向出现问题。我能够保存 onSavedInstanceState 的内容并再次恢复在 edittext 上写入的内容,但似乎正在发生类似错误的行为。

看看下面这些图片:

活动开始时的原始方向:

当我旋转屏幕时,我仍然可以保留内容,但是当我将 carret 放在现有的文本跨度上时,它会将 carret 返回到 0(编辑文本的开头),然后当我输入一些看起来像这个:

我曾经遇到过这种情况,那是很久以前的事了。 IIRC我能够通过完全替换onCreateView的saveInstanceState的内容来解决它,它似乎不再起作用了。

有什么想法吗?

[编辑] 很多人会期待回答“ONCONFIGURATIONCHANGED”。不,请,这不仅仅是潜在问题的解决方案。实际上,我尝试过但没有用,无论如何都不想实施该解决方案。我相信这并不保证创可贴解决方案,至少作为最后的手段。

阅读答案:Why not use always android:configChanges=“keyboardHidden|orientation”?

这是包含编辑文本的“片段”的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context=".HomeScreenActivity"
    android:weightSum="1">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar_note"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingtoolbarlayout_note"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar_note"
                android:layout_width="match_parent"
                android:layout_height="?attr/colorPrimary"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:contentInsetLeft="0dp"
                app:contentInsetStart="0dp"
                app:layout_collapseMode="pin">
                 ....
            </android.support.v7.widget.Toolbar>

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

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

            <EditText
                android:id="@+id/edittext_note"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="6"
                android:gravity="top"
                android:freezesText="true"
                android:layout_marginLeft="16dp"
                android:layout_marginStart="16dp"
                android:layout_marginEnd="16dp"
                android:layout_marginRight="16dp"
                android:layout_marginTop="16dp" />

            <include
                layout="@layout/layout_rte_toolbar_black_icon"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:gravity="bottom"
                android:layout_weight="0.60"/>

        </LinearLayout>

    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

接下来是我的Activity布局,其实很简单的布局:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/framelayout_note"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

这里是Activity的create方法回调:

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

    Log.i("NoteActivity.OnCreate" , TAG);

    setContentView(R.layout.activity_note);

    NoteFragment fragment = NoteFragment.createInstance();
    fragment.setOnToolbarButtonSelected(this);

    getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.framelayout_note , fragment)
            .commit();
}

这里是片段的create/onSavedInstanceState方法回调

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    Log.i("NoteFragment.onCreateView", TAG);

    if(savedInstanceState != null)
    {
        mTitle = savedInstanceState.getString(KEY_EDITTEXT_TITLE, TAG);
        mContent = Html.fromHtml(savedInstanceState.getString(KEY_EDITTEXT_CONTENT, TAG));
    }

    mNoteDataController = ((NotifireApplication) getActivity().getApplication()).getNoteDataController();

    setHasOptionsMenu(true);
    setRetainInstance(true);
}

@Override
public View onCreateView(LayoutInflater inflater , ViewGroup parent, Bundle savedInstanceState)
{
    Log.i("NoteFragment.onCreateView", TAG);

    View view = inflater.inflate(R.layout.fragment_note, parent, false);
    mNoteContent = (EditText) view.findViewById(R.id.edittext_note);
    mNoteTitle = (EditText) view.findViewById(R.id.edittext_note_title);

    if(mContent != null) mNoteContent.setText(mContent);
    if(mTitle != null) mNoteTitle.setText(mTitle);

    initToolbar(view);

    return view;
}


@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
    Html.toHtml(mNoteContent.getText());

    savedInstanceState.putString(KEY_EDITTEXT_CONTENT, Html.toHtml(mNoteContent.getText()));
    savedInstanceState.putString(KEY_EDITTEXT_TITLE, mNoteTitle.getText().toString());

    super.onSaveInstanceState(savedInstanceState);
}

【问题讨论】:

  • 显示你的布局和活动?
  • @DougStevenson 请看我的编辑
  • 您的内容不会自动保存。我认为您甚至不需要处理 onSaveInstanceState。
  • 片段包含协调器布局和标题栏以及所有这些对我来说非常奇怪。通常这会进入活动。我不知道这在片段中是如何工作的。
  • @DougStevenson 是的,感谢您指出这一点。值得一试。我会尝试在活动中移动它,看看它是如何进行的。 Tnx!

标签: android


【解决方案1】:

有问题。其实你在片段中所做的所有这些工作都应该在活动中完成。在这种情况下,由于您使用的是框架布局,我认为正在发生的事情是您的旧片段就位,一旦您旋转设备,就会创建一个新的片段实例并将其放置在其上方。

在我看来,这就是为什么您的旧文本实际上存在于您之前的片段中的原因。我的意见是要么处理 onConfiguration 更改,要么不要在方向更改时创建新片段。

其次,如果你想测试我所说的是你可以使用垂直方向的线性布局,你会看到有两个片段。

【讨论】:

  • 感谢您的回答,但我主要担心的是它不能完全保留编辑文本或在我想要的地方放置小标题等。我正在解释导致文本与另一个文本重叠的行为。这是我的主要问题,因此是第二张照片。
  • 检查我更新的答案这是模糊行为的原因。
  • 你打败了我!准点!
  • 你完全正确。这就是导致我的问题的原因。在实践中,我在处理布局时总是使用片段,我使用的一些预材质设计的布局正在使用片段,现在决定在 Android 中使用纸张设计的强大功能。我猜他们不兼容?您知道如何让 CoordinatorLayout 与 Fragment 一起使用吗?
【解决方案2】:

当屏幕方向改变时,会创建两个 NoteFragment 实例并将其添加到容器视图中。这是你的根本问题。 FragmentActivity#onCreate 正在创建和添加一个 NoteFragment。另一个 NoteFragment 正在您的活动的 onCreate 回调中创建,它是 FragmentActivity 的子类。

您可以通过在 onCreate 中添加片段之前检查 savedInstanceState 是否为空来解决此问题。如果 savedInstanceState 为空,则添加您的片段。如果没有,则在配置更改后重新创建活动,并且 FragmentActivity 的逻辑将为您恢复片段,所以什么都不做。

【讨论】:

    【解决方案3】:

    onConfigurationChanged()中首先将你的Edit文本的数据获取到一个全局变量中然后调用setContentView()现在将Data设置到你的Edit文本中。

    这应该可行。

    【讨论】:

    • 感谢您的回答。但是,我不喜欢去 onConfigurationChanged 区域,那将是我最后的选择。它通常不用于解决此类问题。
    • 是的,我知道,但这就是我解决问题的方法。
    猜你喜欢
    • 2015-05-28
    • 2014-04-17
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多