0

我有一个包含两个活动(MainActivity 和 WelcomeActividy)的应用程序都从android.support.v4.app.FragmentActivity

WelcomeActivity 使用 ViewFlipper 在一个 Step 中显示 Fragments (Step1, Step2, ..., StepN) 使用片段列表 (CategoryStarredFragment) WelcomeActivity 没有问题

MainActivity 使用 tabhost 来显示片段也可以正常工作,但是当尝试包含相同的 CategoryStarredFragment (在 WelcomeActivity 中工作正常)时,我得到了一个异常

04-11 15:32:28.197: E/AndroidRuntime(16124): Caused by: java.lang.ClassNotFoundException: android.view.fragment in loader dalvik.system.PathClassLoader[/data/app/com.package.apk]

我在想这是产生问题的tabhost的实现

这里是MainActivity.java

public class MainActivity extends FragmentActivity implements OnTabChangeListener {


    private TabHost mTabHost;

    private SparseArray<Class<?>> mSparseFragments = new SparseArray<Class<?>>(){{
        put(R.id.tab_home, HomeFragment.class);
                // other tabs
        put(R.id.tab_settings, SettingsFragment.class);
    }};

    private SparseArray<String> mSparseTags = new SparseArray<String>(){{
        put(R.id.tab_home, "home");
                // other tabs
        put(R.id.tab_settings, "settings");
    }};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initTabs();         
    }

    private void initTabs() {
        mTabHost = (TabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup();
        mTabHost.setOnTabChangedListener(this);

        mTabHost.addTab(buildTabSpec("home", R.string.title_tab_home, R.layout.regular_home_fragment));
                // other tabs
        mTabHost.addTab(buildTabSpec("settings", R.string.title_tab_settings, R.layout.regular_settings_fragment));
    }
    @Override
    public void onTabChanged(String tabId) {        
        Log.i(TAG, "Tab changed to: " + tabId);

        final FragmentManager fm = getSupportFragmentManager();
        final FragmentTransaction ft = fm.beginTransaction();
        Fragment fragment;
        int current = 0;


        for (int i = R.id.tab_home; i <= R.id.tab_settings; i++) {              
            if(mSparseTags.get(i).equals(tabId)) {
                current = i;
            } else if(null != (fragment = fm.findFragmentByTag(mSparseTags.get(i)))) {
                ft.detach(fragment);
            }
        }


        if(null == (fragment = fm.findFragmentByTag(tabId))) {
            try {
                ft.add(current, (Fragment) mSparseFragments.get(current).newInstance(), tabId);             
            } catch (InstantiationException e) {        
                e.printStackTrace();
            } catch (IllegalAccessException e) {        
                e.printStackTrace();
            }
        } else {
            ft.attach(fragment);
        }

        ft.commit();
    }

    private TabSpec buildTabSpec(String tag, int labelId, int viewId) {     
        final View indicator = LayoutInflater.from(getApplicationContext())
                .inflate(R.layout.tab, (ViewGroup) findViewById(android.R.id.tabs), false);
        ((TextView)indicator.findViewById(R.id.text)).setText(labelId);
        return mTabHost.newTabSpec(tag)
                .setIndicator(indicator)
                .setContent(new TabContent(getApplicationContext(), viewId));
    }

    public class TabContent implements TabContentFactory {

        private Context mContext;
        private int mViewId;

        public TabContent(Context context, int viewId) {
            mContext = context;
            mViewId = viewId;
        }

        @Override
        public View createTabContent(String tag) {
            Log.i(TAG, "Inflation tab content " + tag);
            View view = LayoutInflater.from(mContext).inflate(mViewId, null);           
            return view;
        }

    }   

}

这是 MainActivity 布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TabHost
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@android:id/tabhost">

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

            <TabWidget 
                android:id="@android:id/tabs"            
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/ab_stacked_solid_mainbar">            
            </TabWidget>

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_height="fill_parent"
                android:layout_width="fill_parent">             
                <FrameLayout
                    android:id="@+id/tab_home"
                    android:layout_height="fill_parent"
                    android:layout_width="fill_parent"/>
                <!-- Other tabs --> 
                <FrameLayout 
                    android:id="@+id/tab_settings"
                    android:layout_height="fill_parent"
                    android:layout_width="fill_parent"/>            
             </FrameLayout>

        </LinearLayout>
    </TabHost>
</RelativeLayout>

这是布局第一个选项卡

<?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="vertical" >    

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="@string/title_tab_home"
        android:textSize="64sp"/>

    <fragment
            android:id="@+id/category_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:layout_marginTop="18dp"
            class="com.package.CategoryStarredFragment" />

</LinearLayout>
4

2 回答 2

8

您正在尝试<fragment>在 API 级别 10 或更低的设备上ActivityFragmentActivity.

实际上,在这种情况下,它有点微妙。您正在尝试使用LayoutInflater.from(). 这很好,但是您不能在 API 级别 10 或更低的设备上使用它来解释其中包含<fragment>标签的布局资源文件,因为LayoutInflater从那时起,您不知道<fragment>标签是什么。您需要使用 ,LayoutInflater返回的实例来解释标签。getLayoutInflater()FragmentActivity<fragment>

于 2013-04-11T20:47:36.870 回答
1

我在一个我一直在清理的项目中遇到了同样的问题(你知道,有时你会开始向应用程序添加想法,但其中很多都无法生存到最后,最好擦掉油脂以避免功能和安全问题......如果没有眼前的森林,您将能够看得更清楚)。

看了几个小时后,我在另一个地方修复了它并回到了原来的状态。事实上,解决方案非常简单(和往常一样,它与干净的编码实践有关)。

(1) 100% 确定您正在导入正确的 FragmentActivity:

import android.support.v4.app.FragmentActivity;

(2) 检查您的 Activity 是否从 FragmentActivity 扩展

(3) 检查你的 Fragment 是否也从正确的 android.support.v4.app 扩展... Fragment

(4) 就是这样......常规代码必须工作

@Override
public View onCreateView(
    LayoutInflater inflater, 
    ViewGroup container,
    Bundle savedInstanceState
) {

    View vFragmentView = inflater.inflate(R.layout.my_fragment, container);
    return vFragmentView;
}

// other stuff

使用三星 Galaxy Fit (2.3.4) 和 Kindle Fire HD (4.0) 进行测试。

于 2013-07-15T14:55:43.743 回答