0

我在基于 tabHost 的应用程序中有一个 ListFragment

在我的标签上只有带有“扩展片段”的线性布局,它工作正常,

但我需要在我的一个选项卡上放置一个 ListFragment,

所以当我用 ListFragment 触摸标签时应用程序崩溃,;(

这里是“tab_fragment”的代码

package com.orchard.elasto;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.SimpleAdapter;


//public class Tab2Fragment extends Fragment { //primera pregunta, lo puedo hacer asi o con FragmentActivity
public class Tab2Fragment extends FragmentActivity { //primera pregunta, lo puedo hacer asi o con FragmentActivity

    private FragmentManager fm;
    private ListFragment list;
    private List<Map<String, String>> listItems;
    private String[] froms;
    private int[] viewIds;


/////////////

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.tab_frag2_layout);
        fm = super.getSupportFragmentManager();
        this.listItems = new ArrayList<Map<String, String>>();
        this.list = (ListFragment)fm.findFragmentById(R.id.index_list);
        //set OnClick Listener
        this.list.getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {

            /* (non-Javadoc)
             * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
             */
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                switch(position) {
                case 0:
                    //IndexActivity.this.startActivity(new Intent(IndexActivity.this, TabsFragmentActivity.class));
                    Log.i("mako", " es zeroo");
                    break;
                case 1:
                    //IndexActivity.this.startActivity(new Intent(IndexActivity.this, ViewPagerFragmentActivity.class));
                    Log.i("mako", " es uno");

                    break;
                case 2:
                    //IndexActivity.this.startActivity(new Intent(IndexActivity.this, TabsViewPagerFragmentActivity.class));
                    Log.i("mako", " es dos");

                    break;
                }

            }

        });

        //this.froms = new String[] {"name"};
        //this.viewIds = new int[] {android.R.id.text1};
    }
    /* (non-Javadoc)
     * @see android.support.v4.app.FragmentActivity#onResume()
     */
    @Override
    protected void onResume() {
        // bind data to the view
        if (this.listItems.isEmpty()) {
            this.bind(0, "name", "Tab Fragments Example");
            this.bind(1, "name", "ViewPager Example");
            this.bind(2, "name", "Tabs View Pager");
        }
        // Initialise List Adapter
        this.list.setListAdapter(new SimpleAdapter(this, this.listItems, android.R.layout.simple_list_item_1, this.froms, this.viewIds));
        super.onResume();
    }

    /**
     * Binds the key-value data pair to the list item at the specified list position 
     * @param pos List item position
     * @param col the column name
     * @param val column value
     * @return the mapping of column values
     */
    private Map<String, String> bind(int pos, String col, String val) {
        Map<String, String> map = null;
        if (!this.listItems.isEmpty() && pos < this.listItems.size()) 
            map = this.listItems.get(pos);
        else if (map == null) {
            map = new HashMap<String, String>();
            this.listItems.add(Math.min(pos, this.listItems.size()), map);
        }
        map.put(col, val);
        return map;
    }
}

这里是我的 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="vertical" 
    android:background="#00FF00">

    <fragment
        android:name="android.support.v4.app.ListFragment"
        android:id="@+id/index_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>
</LinearLayout>

错误日志:

error::
05-31 21:07:38.402: W/dalvikvm(264): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
05-31 21:07:38.412: E/AndroidRuntime(264): FATAL EXCEPTION: main
05-31 21:07:38.412: E/AndroidRuntime(264): java.lang.ClassCastException: com.orchard.elasto.Tab2Fragment
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.support.v4.app.Fragment.instantiate(Fragment.java:384)
05-31 21:07:38.412: E/AndroidRuntime(264):  at com.orchard.elasto.ElastoTabsActivity.onTabChanged(ElastoTabsActivity.java:145)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.widget.TabHost.invokeOnTabChangeListener(TabHost.java:356)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.widget.TabHost.setCurrentTab(TabHost.java:341)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.widget.TabHost$2.onTabSelectionChanged(TabHost.java:129)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.widget.TabWidget$TabClickListener.onClick(TabWidget.java:453)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.view.View.performClick(View.java:2408)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.view.View$PerformClick.run(View.java:8816)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.os.Handler.handleCallback(Handler.java:587)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.os.Handler.dispatchMessage(Handler.java:92)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.os.Looper.loop(Looper.java:123)
05-31 21:07:38.412: E/AndroidRuntime(264):  at android.app.ActivityThread.main(ActivityThread.java:4627)
05-31 21:07:38.412: E/AndroidRuntime(264):  at java.lang.reflect.Method.invokeNative(Native Method)
05-31 21:07:38.412: E/AndroidRuntime(264):  at java.lang.reflect.Method.invoke(Method.java:521)
05-31 21:07:38.412: E/AndroidRuntime(264):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
05-31 21:07:38.412: E/AndroidRuntime(264):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
05-31 21:07:38.412: E/AndroidRuntime(264):  at dalvik.system.NativeStart.main(Native Method)
05-31 21:07:38.442: W/ActivityManager(70):   Force finishing activity com.orchard.elasto/.ElastoTabsActivity

编辑,ElastoTabsActivity 的代码:

package com.orchard.elasto;

import java.util.HashMap;




import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;

public class ElastoTabsActivity extends FragmentActivity implements TabHost.OnTabChangeListener{

    private TabHost mTabHost;
    private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, ElastoTabsActivity.TabInfo>();
    private TabInfo mLastTab = null;
    /**
     * 
     * @author mwho
     *
     */
    private class TabInfo {
         private String tag;
         private Class<?> clss;
         private Bundle args;
         private Fragment fragment;
         TabInfo(String tag, Class<?> clazz, Bundle args) {
             this.tag = tag;
             this.clss = clazz;
             this.args = args;
         }

    }
    /**
     * 
     * @author mwho
     *
     */
    class TabFactory implements TabContentFactory {

        private final Context mContext;

        /**
         * @param context
         */
        public TabFactory(Context context) {
            mContext = context;
        }

        /** (non-Javadoc)
         * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
         */
        public View createTabContent(String tag) {
            View v = new View(mContext);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }

    }
    /** (non-Javadoc)
     * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
     */
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tabs_layout);
        initialiseTabHost(savedInstanceState);
        if (savedInstanceState != null) {
            mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
        }
    }

    /** (non-Javadoc)
     * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
     */
    protected void onSaveInstanceState(Bundle outState) {
        outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
        super.onSaveInstanceState(outState);
    }

    /**
     * Initialise the Tab Host
     */
    private void initialiseTabHost(Bundle args) {
        mTabHost = (TabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup();
        TabInfo tabInfo = null;
        ElastoTabsActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("Tab 1"), ( tabInfo = new TabInfo("Tab1", Tab1Fragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        ElastoTabsActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("Tab 2"), ( tabInfo = new TabInfo("Tab2", Tab2Fragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        ElastoTabsActivity.addTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("Tab 3"), ( tabInfo = new TabInfo("Tab3", Tab3Fragment.class, args)));
        this.mapTabInfo.put(tabInfo.tag, tabInfo);
        // Default to first tab
        this.onTabChanged("Tab1");
        //
        mTabHost.setOnTabChangedListener(this);
    }

    /**
     * @param activity
     * @param tabHost
     * @param tabSpec
     * @param clss
     * @param args
     */
    private static void addTab(ElastoTabsActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
        // Attach a Tab view factory to the spec
        tabSpec.setContent(activity.new TabFactory(activity));
        String tag = tabSpec.getTag();

        // Check to see if we already have a fragment for this tab, probably
        // from a previously saved state.  If so, deactivate it, because our
        // initial state is that a tab isn't shown.
        tabInfo.fragment = activity.getSupportFragmentManager().findFragmentByTag(tag);
        if (tabInfo.fragment != null && !tabInfo.fragment.isDetached()) {
            FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
            ft.detach(tabInfo.fragment);
            ft.commit();
            activity.getSupportFragmentManager().executePendingTransactions();
        }

        tabHost.addTab(tabSpec);
    }

    /** (non-Javadoc)
     * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
     */
    public void onTabChanged(String tag) {
        TabInfo newTab = this.mapTabInfo.get(tag);
        if (mLastTab != newTab) {
            FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
            if (mLastTab != null) {
                if (mLastTab.fragment != null) {
                    ft.detach(mLastTab.fragment);
                }
            }
            if (newTab != null) {
                if (newTab.fragment == null) {
                    newTab.fragment = Fragment.instantiate(this,
                            newTab.clss.getName(), newTab.args);
                    ft.add(R.id.realtabcontent, newTab.fragment, newTab.tag);
                } else {
                    ft.attach(newTab.fragment);
                }
            }

            mLastTab = newTab;
            ft.commit();
            this.getSupportFragmentManager().executePendingTransactions();
        }
    }
}

所以我做错了什么,或者错过了请!

多谢!

4

1 回答 1

1

你在 com.orchard.elasto.ElastoTabsActivity.onTabChanged(ElastoTabsActivity.java:145) 做了错误的对象转换

就行 newTab.fragment = Fragment.instantiate(this, newTab.clss.getName(), newTab.args);

您正在尝试实例化 Tab2Fragment,它是从 FragmentActivity 扩展而来的。上面的代码期望 Fragment 子类的类名。这就是你得到 ClassCastException 的原因。

于 2012-05-31T12:01:32.677 回答