2

コンテキスト

私のアプリケーション アーキテクチャは、新しい Android プロジェクトを作成するときのデフォルトの "Swipe Views" と非常によく似ています。1 つのアクティビティ、3 つのフラグメント、それらをスワイプできます。サポート ライブラリを使用します。すべてが最新です。私がテストしているデバイスは、Android 4.1.2 サポート ライブラリ r11 を実行している Galaxy nexus であり、SDK バージョンは min=14 target=16 です。

問題

2 番目の Fragment には、sharedPreferences から読み取ったさまざまな数値を含む一連の EditText が保持されます。アクティビティが最初に作成されたとき、すべて問題なく EditViews はすべて正しい値を持っていますが、値の 1 つをたとえば 555 に変更してからデバイスを回転させると、すべての EditText が 555 を表示するようになりました。

プログラム全体でsetTextは1つしかなく、この投稿の後半に表示されます。削除しようとしましたが、アクティビティを開始すると予想どおり、すべてのEditTextがデフォルト値(666)を表示し、1つを変更してデバイスを回転させました。すべてが新しい値を表示します!

詳細

SectionsPagerAdapter、ViewPager、および各ページの複数のフラグメントを含む 1 つのアクティビティ。

onViewCreatedメソッドのフラグメント (ConfigurationFragment) の 1 つで、 andEditTextImageButton.

これらの行は実際にはレイアウト (xml ファイル) にあり、追加する行ごとに膨らませてから、editText を取得し、setText を呼び出して、その値を本来あるべき値に設定します。

onViewCreated メソッド:

public void onViewCreated(View view, Bundle savedInstanceState)
{
    // populate ports list on view creation
    ArrayList<String> listenPorts = mServerManagerThread.getListenPorts();
    for (String port : listenPorts)
    {
        EditText v = ((EditText) addListenPortItem().getChildAt(0));
        v.setText(port);
    }

    super.onViewCreated(view, savedInstanceState);
}

当然、メソッドgetListenPortsは呼び出されるたびに同じリストを返します (起動時とデバイスの回転時)。

基本的に addListenPortItem が行うこと:

    // Instantiate a new "row" view.
    final ViewGroup newView = (ViewGroup) LayoutInflater.from(viewGroup.getContext()).inflate(itemResource,
            viewGroup, false);

    // Set a click listener for the "X" button in the row that will remove
    // the row.
    newView.findViewById(R.id.delete_button).setOnClickListener(
            new OnRemoveClickListener(mContainer, viewGroup, newView, emptyListTextResource));

    viewGroup.addView(newView);

viewGroup は、新しく作成されたビューを保持する linearLayout です itemResource は次のレイアウトです

1 行のレイアウト:

<?xml version="1.0" encoding="utf-8"?>
<!--
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?android:listPreferredItemHeightSmall"
    android:layout_marginTop="8dp"
    android:divider="?android:dividerVertical"
    android:dividerPadding="8dp"
    android:gravity="right"
    android:orientation="horizontal"
    android:showDividers="middle" >

    <EditText
        android:id="@+id/editPort"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="number"
        android:text="666" >
    </EditText>

    <ImageButton
        android:id="@+id/delete_button"
        style="?android:attr/borderlessButtonStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/action_remove_item"
        android:src="@drawable/content_remove" />
</LinearLayout>

何か案が?

私はこのバグを数時間じっと見つめていましたが、何が起こっているのかまったくわかりません... SDK またはサポート ライブラリのバグを疑い始めていますが、経験から、バグが最も重要であることはわかっています。しばしば私の脳内で:)

4

2 に答える 2

4

私は解決策を見つけました:コードを onViewCreated から onViewStateRestored(..) に移動して、状態が復元された後に EditTexts に値を入力するようにしました。

問題は、すべての EditText が同じ ID を持っているため、状態を復元するときにめちゃくちゃになっていたことでした。

于 2012-11-22T00:05:53.547 に答える
0

これはバグではないので、心配しないでください。問題は、画面を回転させるとアクティビティとフラグメントが再作成されることです。onCreateView()が再度呼び出され、これにより事態が混乱するため、このような奇妙な動作が発生します。これは、次の 2 つのメソッドをオーバーライドすることで修正できます。

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // Read values from the "savedInstanceState"-object and put them in your textview
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    // Save the values you need from your textview into "outState"-object
    super.onSaveInstanceState(outState);
}
于 2012-11-21T23:25:50.730 に答える