rkmax
rkmax

Reputation: 18143

java.lang.ClassNotFoundException: android.view.fragment

I have an application with Two Activities (MainActivity and WelcomeActividy) both extends from android.support.v4.app.FragmentActivity

WelcomeActivity uses a ViewFlipper for display Fragments (Step1, Step2, ..., StepN) in one Step uses a fragment list (CategoryStarredFragment) the WelcomeActivity no have problems

MainActivity uses a tabhost for display fragment too all work fine but when try to include a the same CategoryStarredFragment (works fine in WelcomeActivity) i get a exception

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]

I'm thinking that is the implementation of the tabhost which is generating the problem

here's 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;
        }

    }   

}

Here is MainActivity layout

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

Here is layout first tab

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

Upvotes: 0

Views: 9081

Answers (2)

user2583872
user2583872

Reputation: 109

I had the same problem in a project I have been cleaning (you know, sometimes you start adding ideas to an application, but just many of them won't survive to the end and it is much better to erase the grease to avoid functionality and security problems ... you would be able to see better without the forest in front of your eyes).

After some hours looking at the problem, I fixed it in another place and returned to my original situation. In fact, the solution is very simple (as usual and it is related with clean coding practices).

(1) be 100% sure you are importing the right FragmentActivity:

import android.support.v4.app.FragmentActivity;

(2) check that your Activity extends from FragmentActivity

(3) check that your Fragment also extends from the right android.support.v4.app... Fragment

(4) that's all ... the regular code must work

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

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

// other stuff

Tested with a Samsung Galaxy Fit (2.3.4) and a Kindle Fire HD (4.0).

Upvotes: 1

CommonsWare
CommonsWare

Reputation: 1007659

You are attempting to load a layout containing a <fragment> tag, on an API Level 10 or lower device, from an Activity instead of a FragmentActivity.

Actually, in this case, it is a bit more subtle. You are attempting to use LayoutInflater.from(). This is fine, but you cannot use it on API Level 10 or lower devices to interpret layout resource files with <fragment> tags in them, as LayoutInflater from back then had no idea what a <fragment> tag was. You need to use the LayoutInflater instance returned by getLayoutInflater() on your FragmentActivity, in order to interpret <fragment> tags.

Upvotes: 8

Related Questions