如何preserve片段列表视图内容? [英] How to preserve Fragment List View Contents?

查看:145
本文介绍了如何preserve片段列表视图内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

preamble:我使用ActionBarSherlock,目标SDK是17(Android 4.2版),闵SDK为5(Android 2.0的)

Preamble: I am using ActionBarSherlock, Target SDK is 17 (Android 4.2), Min SDK is 5 (Android 2.0)

情况:

我在我的应用程序,其中presents某种登录有一个片段。它允许用户对设备多个用户帐户。(因为Android和所述; 4.2没有该系统支持我们的用户似乎使用,由于设备共享)

I've got a fragment in my app, which presents some kind of login. It allows the user to have several user accounts on device (because Android < 4.2 didn't have system support for that and our users seem to use that due to device sharing).

该片段布局由一个列表视图按钮和大风景还可以增加新帐户(通过提供溢出菜单以其他方式)。

The fragment layout consists of a listview and on large-landscape also a button to add new accounts (otherwise via overflow menu available).

的列表视图附着到BaseAdapter-导数称为AccountAdapter,其中从数据库中获取的帐目以及创建经由layoutinflater每个帐户对应子视图。有3种可能性:用户提供登录和密码/用户只提供登录/用户提供什么。因此,也有这些情况下,其中丢失的数据经由的EditText-元素请求和存储的数据经由TextView的显示3个不同的布局。此外,缺少数据的布局商店提供一个复选框,丢失的数据和一个提交按钮。如果提供的所有数据,为对缺少提交按钮onclicklistener被直接附着到帐户根视图。
该onclicklistener信息输入的数据到网络code类modifys适配器模式;在这之后,适配器只显示所选条目,但与进步的观点,以可视化的当前操作给用户(用户XXX正在登录,请站在...)。

The listview is attached to a BaseAdapter-Derivate called "AccountAdapter", which gets the accounts from a database and creating corresponding child views per account via layoutinflater. There are 3 Possibilities: User provided both Login and Password / User provided only login / User provided nothing. Therefore, there are 3 different Layouts for those cases, where the missing data is requested via EditText-Elements and stored data is shown via TextView. Also, the layouts with missing data provide a checkbox for store the missing data and a submit-button. If all data is provided, the onclicklistener for the missing submit button gets directly attached to the account root view. The onclicklistener messages the entered data to the network code class and modifys the adapter mode; after that, the adapter only shows the selected entry, but with the "progress" view, to visualize the current action to the user ("User XXX is being logged in, please stand by...").

这已经工作得很好。

问题:

在方向的变化,所有输入的数据丢失。输入的登录数据,密码,如果左右应存储的登录数据的信息。

On orientation changes, all entered data gets lost. Entered login data, passwords, information about if the login data should be stored.

布局:

<!-- 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>

code:

在code都没有实现和的onSaveInstanceState尚未onConfigurationChange。
(全报价将会太长恕我直言,> 1.000线code的)

The code both doesn't implement onSaveInstanceState and onConfigurationChange yet. (whole quotation would be too long imho, > 1.000 lines of code)

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是否设置与否的主要活动,所以我的活动已经是prepared的片段娱乐条款。

I check for whether savedInstanceState is set or not in the main activity, so my activity is already "prepared" in terms of fragment recreation.

片段检查适配器是否已经存在或不创建和其附加到列表视图之前。
但是:至于我的理解是,即使重现片段使用相同的适配器,默认的所有getViews()得到召回,因此创建一个重置了内容的视图的新实例

Fragment checks for whether the adapter already exists or not before creating and attaching it to the listview. But: As far as my understanding is, even if the "recreated" fragment use the same Adapter, "by default" all getViews() get recalled and therefore create a new instance of the view with "resetted" contents.

该AccountAdapter被专用的帐户从​​数据库中的用户ID,用户名,密码-Objects。此外,帐户可以扩展到容纳更多的数据,想缓存视图。

The AccountAdapter gets dedicated "Account"-Objects with user-id, username, password from the database. Also, "Account" could be extended to hold additional data, like to cache the view.

我的想法是实现这样的getView:

My idea was to implement a getView like this:

    @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类。

But then I noticed, that the AccountAdapter didn't survive the recreation, Android re-instantiates the LoginFragment class.

我需要什么:


  • 如何从列表视图内容formulars /如何preserve恢复数据AccountAdapter及其相关意见

  • 如何优化,提高我的建筑设计
  • 温馨提示

推荐答案

如果您添加它不是从你的code清楚一个片段每次的onCreate()你的活动的方式获取叫做

It is not clear from your code if you add a Fragment every time the onCreate() method of your Activity get's called.

您应该添加片段或第一个片段只有当活动 GET的首次创建的。

You should add a Fragment or the first Fragment only when the Activity get's created for the first time .

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

如果这不是你的活动被重新创建,它也将重新添加previous 片段。埃文如果你有更多的片段 backstack 他们都将在你的活动被放回

if this is not null your Activity gets re-created, and it will also re-add your previous Fragments. Evan if you have more Fragments in the backstack they will all be put back in your Activity.

要保持数据的片段,您应该使用 setRetainInstance(真); 片段 的onCreate()的方法,或者使用的onSaveInstanceState(束束)来保存特定的数据。

To keep the data in your fragments, you should either use setRetainInstance(true); on your Fragments onCreate() method, or use onSaveInstanceState(Bundle bundle) to save the specific data.

这篇关于如何preserve片段列表视图内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆