1

前文: 私は ActionBarSherlock を使用しています。ターゲット SDK は 17 (Android 4.2)、最小 SDK は 5 (Android 2.0) です。

状況:

アプリにフラグメントがあり、ある種のログインが表示されます。これにより、ユーザーはデバイス上で複数のユーザー アカウントを持つことができます (Android < 4.2 ではシステムがサポートされておらず、ユーザーはデバイス共有のためにそれを使用しているようです)。

フラグメント レイアウトは、リストビューと大きなランドス ケープで構成され、新しいアカウントを追加するためのボタンも含まれます (それ以外の場合は、利用可能なオーバーフロー メニューを使用します)。

リストビューは、「AccountAdapter」と呼ばれる BaseAdapter-Derivate にアタッチされ、データベースからアカウントを取得し、layoutinflater を介してアカウントごとに対応する子ビューを作成します。ユーザーがログインとパスワードの両方を提供する/ユーザーがログインのみを提供する/ユーザーが何も提供しないという 3 つの可能性があります。したがって、不足しているデータが EditText-Elements を介して要求され、格納されたデータが TextView を介して表示される場合には、3 つの異なるレイアウトがあります。また、欠落データのあるレイアウトには、欠落データを保存するためのチェックボックスと送信ボタンがあります。すべてのデータが提供されると、不足している送信ボタンの onclicklistener がアカウントのルート ビューに直接アタッチされます。onclicklistener は、入力されたデータをネットワーク コード クラスにメッセージで送信し、アダプタ モードを変更します。その後、アダプタは選択されたエントリのみを表示します。

これはすでにうまく機能しています。

問題:

向きを変更すると、入力したすべてのデータが失われます。入力されたログイン データ、パスワード、ログイン データを保存するかどうかに関する情報。

レイアウト:

<!-- layout/main.xml -->
<?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"
    android:orientation="horizontal" >

    <FrameLayout
        android:id="@id/main_fragment_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

<!-- layout-large-land/main.xml -->
<?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"
    android:orientation="horizontal" >

    <FrameLayout
        android:id="@id/main_fragment_sidebar"
        android:layout_width="@dimen/main_sidebar_width"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@id/main_fragment_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

<!-- layout/fragment_login.xml -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@id/fragment_login_accountlist"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</RelativeLayout>

<!-- layout-large-land/fragment_login.xml -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@id/fragment_login_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="@string/string_fragment_login" />

    <ListView
        android:id="@id/fragment_login_accountlist"
        android:layout_width="@dimen/fragment_login_accountlist_width"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" >

    </ListView>

</RelativeLayout>

<!-- layout/view_login_account_new.xml -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@id/view_login_account_profileimage"
        android:layout_width="@dimen/view_login_account_profileimage_width"
        android:layout_height="@dimen/view_login_account_profileimage_height"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:contentDescription="@string/string_view_login_account_profileimage_contentdescription"
        android:scaleType="fitCenter"
        android:src="@drawable/img_kb" />

    <EditText
        android:id="@id/view_login_account_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@id/view_login_account_profileimage"
        android:ems="10"
        android:hint="@string/string_view_login_account_username_hint"
        android:inputType="text" >

        <requestFocus />
    </EditText>

    <EditText
        android:id="@id/view_login_account_password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/view_login_account_username"
        android:layout_alignParentRight="true"
        android:layout_below="@id/view_login_account_username"
        android:ems="10"
        android:hint="@string/string_view_login_account_password_hint"
        android:inputType="textPassword" />

    <CheckBox
        android:id="@id/view_login_account_storecredentials"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@id/view_login_account_password"
        android:layout_toRightOf="@id/view_login_account_profileimage"
        android:text="@string/string_view_login_account_storecredentials_text" />

    <Button
        android:id="@id/view_login_account_submit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@id/view_login_account_storecredentials"
        android:text="@string/string_view_login_account_submit_text" />

</RelativeLayout>

<!-- layout/view_login_account_progress.xml -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@id/view_login_account_profileimage"
        android:layout_width="@dimen/view_login_account_profileimage_width"
        android:layout_height="@dimen/view_login_account_profileimage_height"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:contentDescription="@string/string_view_login_account_profileimage_contentdescription"
        android:scaleType="fitCenter"
        android:src="@drawable/img_kb" />

    <TextView
        android:id="@id/view_login_account_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@id/view_login_account_profileimage"
        android:ems="10"
         >
    </TextView>

    <TextView
        android:id="@id/view_login_account_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/view_login_account_username"
        android:layout_alignParentRight="true"
        android:layout_below="@id/view_login_account_username"
        android:ems="10"
        android:text="@string/string_view_login_account_progress_text" />

</RelativeLayout>

<!-- layout/view_login_account_stored_password.xml -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@id/view_login_account_profileimage"
        android:layout_width="@dimen/view_login_account_profileimage_width"
        android:layout_height="@dimen/view_login_account_profileimage_height"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:contentDescription="@string/string_view_login_account_profileimage_contentdescription"
        android:scaleType="fitCenter"
        android:src="@drawable/img_kb" />

    <TextView
        android:id="@id/view_login_account_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@id/view_login_account_profileimage"
        android:ems="10"
         >
    </TextView>

    <TextView
        android:id="@id/view_login_account_password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/view_login_account_username"
        android:layout_alignParentRight="true"
        android:layout_below="@id/view_login_account_username"
        android:ems="10"
        android:text="@string/string_view_login_account_password_text"
         />

</RelativeLayout>

<!-- layout/view_login_account_stored_username.xml -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@id/view_login_account_profileimage"
        android:layout_width="@dimen/view_login_account_profileimage_width"
        android:layout_height="@dimen/view_login_account_profileimage_height"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:contentDescription="@string/string_view_login_account_profileimage_contentdescription"
        android:scaleType="fitCenter"
        android:src="@drawable/img_kb" />

    <TextView
        android:id="@id/view_login_account_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@id/view_login_account_profileimage"
        android:ems="10"
        android:hint="@string/string_view_login_account_username_hint" >

        <requestFocus />
    </TextView>

    <EditText
        android:id="@id/view_login_account_password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/view_login_account_username"
        android:layout_alignParentRight="true"
        android:layout_below="@id/view_login_account_username"
        android:ems="10"
        android:hint="@string/string_view_login_account_password_hint"
        android:inputType="textPassword" />

    <CheckBox
        android:id="@id/view_login_account_storecredentials"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@id/view_login_account_password"
        android:layout_toRightOf="@id/view_login_account_profileimage"
        android:text="@string/string_view_login_account_storecredentials_text" />

    <Button
        android:id="@id/view_login_account_submit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@id/view_login_account_storecredentials"
        android:text="@string/string_view_login_account_submit_text" />

</RelativeLayout>

コード:

コードは両方ともまだ onSaveInstanceState と onConfigurationChange を実装していません。(全体の引用は長すぎます。1.000行以上のコードです)

public class MessengerActivity extends SherlockFragmentActivity {

    // -------------------------------------------------------------------------

    FrameLayout fragmentSidebar = null;
    FrameLayout fragmentContent = null;

    Content     content         = null;

    // -------------------------------------------------------------------------

    boolean     hasSidebar      = false;

    // -------------------------------------------------------------------------

    public void onCreate(Bundle savedInstanceState) {

        // ---------------------------------------------------------------------

        super.onCreate(savedInstanceState);

        // ---------------------------------------------------------------------

        content = Content.getInstance(this);

        // ---------------------------------------------------------------------

        setContentView(R.layout.main);

        // ---------------------------------------------------------------------

        captureFragmentViews();

        // ---------------------------------------------------------------------

        // ---------------------------------------------------------------------

        if (savedInstanceState == null) {

            // -----------------------------------------------------------------

            gotoLogin();

            // -----------------------------------------------------------------

        }
        else {

            // -----------------------------------------------------------------

            // -----------------------------------------------------------------

        }


        // ---------------------------------------------------------------------

    }

    // -------------------------------------------------------------------------
    // Disabled through android manifest at the moment

    @Override
    public void onConfigurationChanged(Configuration newConfig) {

        // ---------------------------------------------------------------------

        super.onConfigurationChanged(newConfig);

        // ---------------------------------------------------------------------

        Log.d(getClass().getSimpleName(), "onConfigurationChanged");

        // ---------------------------------------------------------------------

    }

    // -------------------------------------------------------------------------

    public void captureFragmentViews() {

        // ---------------------------------------------------------------------

        fragmentSidebar = (FrameLayout) findViewById(R.id.main_fragment_sidebar);
        fragmentContent = (FrameLayout) findViewById(R.id.main_fragment_content);

        // ---------------------------------------------------------------------

        if ((fragmentSidebar != null) && (fragmentContent != null)) {

            hasSidebar = true;

        }
        else {

            hasSidebar = false;

        }

        // ---------------------------------------------------------------------

    }

    // -------------------------------------------------------------------------

    public void gotoLogin() {

        // ---------------------------------------------------------------------

        Fragment fragment = SherlockFragment.instantiate(this,
                LoginFragment.class.getName());

        // ---------------------------------------------------------------------

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

        if (hasSidebar) {

            ft.add(R.id.main_fragment_content, fragment);
            fragmentSidebar.setVisibility(View.GONE);

        }
        else {

            ft.add(R.id.main_fragment_content, fragment);

        }

        // ---------------------------------------------------------------------

        ft.commit();
        getSupportFragmentManager().executePendingTransactions();

        // ---------------------------------------------------------------------

    }

    // -------------------------------------------------------------------------

    public void gotoSignup() {
        // TODO Auto-generated method stub

    }

    // -------------------------------------------------------------------------

    public void gotoContactList(int filterId) {
        // TODO Auto-generated method stub

    }

    // -------------------------------------------------------------------------

    public void gotoConversation(int userId) {
        // TODO Auto-generated method stub

    }

    // -------------------------------------------------------------------------

    public void gotoOnlineStatusList(int categoryId) {
        // TODO Auto-generated method stub

    }

    // -------------------------------------------------------------------------

    public void gotoSettings(int categoryId) {
        // TODO Auto-generated method stub

    }

    // -------------------------------------------------------------------------

}

メイン アクティビティで savedInstanceState が設定されているかどうかを確認するため、アクティビティはフラグメントの再作成に関して既に「準備」されています。

フラグメントは、アダプターを作成してリストビューにアタッチする前に、アダプターが既に存在するかどうかを確認します。しかし:私の理解では、「再作成された」フラグメントが同じアダプターを使用していても、「デフォルトで」すべての getViews() がリコールされるため、「リセットされた」コンテンツを持つビューの新しいインスタンスが作成されます。

AccountAdapter は、データベースからユーザー ID、ユーザー名、パスワードを持つ専用の「アカウント」オブジェクトを取得します。また、「アカウント」を拡張して、ビューをキャッシュするなど、追加のデータを保持することもできます。

私の考えは、次のような getView を実装することでした:

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        // ---------------------------------------------------------------------

        final Account account = (Account) getItem(position);
        View view = null;

        // ---------------------------------------------------------------------

        if (account == null) {

            return view;

        }

        // ---------------------------------------------------------------------

        if (account.view != null) {

            return account.view;

        }

        // ---------------------------------------------------------------------
    [...]
    }

しかし、その後、AccountAdapter が再現されなかったことに気付きました。Android は LoginFragment クラスを再インスタンス化します。

必要なもの:

  • リストビュー コンテンツ フォーミュラーからデータを復元する方法 / AccountAdapter とそれに関連付けられたビューを保持する方法
  • 建築設計を最適化および改善するためのヒント
4

1 に答える 1

1

get のメソッドが呼び出されるFragmentたびに a を追加する場合、コードからは明確ではありません。onCreate()Activity

get が初めて作成された場合にのみ、Fragmentまたはを追加する必要があります。FragmentActivity

if(savedInstanceState==null){
     addFragment();
}

これが再作成されない場合は、以前nullの. Evan にさらにある場合、それらはすべて に戻されます。ActivityFragmentsFragmentsbackstackActivity

データをフラグメントに保持するには、メソッドで を使用するか、 をsetRetainInstance(true);使用Fragments onCreate()onSaveInstanceState(Bundle bundle)て特定のデータを保存する必要があります。

于 2013-01-31T11:26:39.553 に答える