java.lang.ClassNotFoundException:android.view.fragment

时间:2013-04-11 20:45:44

标签: android android-fragments

我有一个带有两个活动的应用程序(MainActivity和WelcomeActividy),它们都来自android.support.v4.app.FragmentActivity

WelcomeActivity使用ViewFlipper显示片段(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>

2 个答案:

答案 0 :(得分:8)

您正在尝试从<fragment>而不是Activity加载API级别10或更低设备上包含FragmentActivity标记的布局。

实际上,在这种情况下,它有点微妙。您正在尝试使用LayoutInflater.from()。这没关系,但您不能在API级别10或更低版本的设备上使用它来解释其中包含<fragment>标记的布局资源文件,因为后面的LayoutInflater不知道<fragment>是什么标签是。您需要使用LayoutInflatergetLayoutInflater()返回的FragmentActivity实例,以便解释<fragment>代码。

答案 1 :(得分:1)

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

几个小时后看着问题,我把它固定在另一个地方并恢复原状。实际上,解决方案非常简单(像往常一样,它与清晰的编码实践相关)。

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

import android.support.v4.app.FragmentActivity;

(2)检查您的活动是否从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)测试。