带有 ScrollView 的 Android 操作栏选项卡在方向更改后制作了重复 View

标签 android screen-orientation android-actionbar

我有一个非常简单的代码,我在其中使用带有选项卡 fragment 的操作栏。加载后它工作正常,但在方向改变后它变得疯狂。旧 fragment 也可见(为什么?)。

抱歉图片上有匈牙利语文字,但我希望这没关系。 After orientation change

我附上代码,也许它有助于解决这个问题。

主要 Activity :

public class Main extends Activity
{
    private static ActionBar actionBar;

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

        // setup action bar for tabs
        actionBar = getActionBar();
        actionBar.removeAllTabs();
        if (actionBar.getTabCount() == 0)
        {
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

            Tab tab = actionBar.newTab().setText(R.string.starter).setTabListener(new TabListener<Starter>(this, "starter", Starter.class));
            actionBar.addTab(tab);

            tab = actionBar.newTab().setText(R.string.newword).setTabListener(new TabListener<NewWord>(this, "newwod", NewWord.class));
            actionBar.addTab(tab);

            tab = actionBar.newTab().setText(R.string.feedback).setTabListener(new TabListener<Feedback>(this, "feedback", Feedback.class));
            actionBar.addTab(tab);
        }

        if (savedInstanceState != null)
        {
            actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
        outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
    }
}

TabListener(与 Google 示例相同):

public class TabListener<T extends Fragment> implements android.app.ActionBar.TabListener
{
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    /**
     * Constructor used each time a new tab is created.
     * 
     * @param activity
     *            The host Activity, used to instantiate the fragment
     * @param tag
     *            The identifier tag for the fragment
     * @param clz
     *            The fragment's Class, used to instantiate the fragment
     */
    public TabListener(Activity activity, String tag, Class<T> clz)
    {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft)
    {
        // User selected the already selected tab. Usually do nothing.

    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft)
    {
        // Check if the fragment is already initialized
        if (mFragment == null)
        {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else
        {
            // If it exists, simply attach it in order to show it
            ft.attach(mFragment);
        }

    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft)
    {
        if (mFragment != null)
        {
            // Detach the fragment, because another one is being attached
            ft.detach(mFragment);
        }
    }

}

fragment :

public class Starter extends Fragment
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        setRetainInstance(false);
        return inflater.inflate(R.layout.newword, container, false);
    }
}

和布局 XML:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dp" >

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="@string/newword"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <EditText
            android:id="@+id/newwordtext"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="@string/wordhint" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="@string/description"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/descriptionwordtext"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="@string/descriptionhint"
            android:inputType="textMultiLine"
            android:minLines="4" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="@string/origin"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/origintext"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="@string/originhint" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="@string/source"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/sourcetext"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="@string/sourcehint" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="@string/name"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/nametext"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:inputType="textPersonName" />

        <Button
            android:id="@+id/sendbutton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="@string/send" />
    </LinearLayout>

</ScrollView>

提前致谢!

最佳答案

我在其他 question 中找到了可用的答案.

我需要修改我的 TabListener(我将它作为内部类移到了我的 Main Activity 类中):

private class TabListener<T extends Fragment> implements android.app.ActionBar.TabListener
    {
        private Fragment mFragment;
        private final Activity mActivity;
        private final String mTag;
        private final Class<T> mClass;

        /**
         * Constructor used each time a new tab is created.
         * 
         * @param activity
         *            The host Activity, used to instantiate the fragment
         * @param tag
         *            The identifier tag for the fragment
         * @param clz
         *            The fragment's Class, used to instantiate the fragment
         */
        public TabListener(final Activity activity, final String tag, final Class<T> clz)
        {
            mActivity = activity;
            mTag = tag;
            mClass = clz;
        }

        @Override
        public void onTabReselected(final Tab tab, final FragmentTransaction ft)
        {
            // User selected the already selected tab. Usually do nothing.
        }

        @Override
        public void onTabSelected(final Tab tab, final FragmentTransaction ft)
        {
            mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
            if (mFragment == null)
            {
                mFragment = Fragment.instantiate(mActivity, mClass.getName());
                ft.add(android.R.id.content, mFragment, mTag);
            }
            else
            {
                ft.attach(mFragment);
            }
        }

        @Override
        public void onTabUnselected(final Tab tab, final FragmentTransaction ft)
        {
            if (mFragment != null)
            {
                ft.detach(mFragment);
            }
        }
    }

所以在我(再次)添加 fragment 之前,我检查它是否存在(并获取它的引用),如果它存在我只附加它。

关于带有 ScrollView 的 Android 操作栏选项卡在方向更改后制作了重复 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8885594/

相关文章:

android - TaskStackBuilder 和后栈的附加功能

android - 在 `ActionBar` 项目单击时显示弹出菜单

android - 方向改变时的 radio 组行为

ios - iPad 在 Landscape 中启动仅接收 768x768 内的触摸

android - 将 windowTranslucentStatus 与 CollapsingToolbarLayout 一起使用

java - 为叠加操作栏指定布局上边距

java - 如何将 ArrayAdapter 添加到 ArrayList<ArrayList<String>>()?

android - Sqlite 报错

android - 设置动态壁纸时出错

在横向和纵向上具有不同项目的 Android 布局