Android的碎片oncreateview要求标签的变化碎片、标签、Android、oncreateview

2023-09-05 07:18:23 作者:浅酒

我一直在与Android的一段时间,但碎片一点点新的给我(因为它们是大多数人可能)。无论如何,我已经得到了以下code,并能正常工作。我有三个片段,一个在每个选项卡。我想知道如果这是正常的onCreateView被称为每次我切换标签,以及是否有意义这样做呢?不应该有一种方法,每次以不重绘片段的标签的变化?

我是从一个应用程序,有3个活动,一个在每个选项卡转换这一点,这似乎是一种浪费每一次重新创建视图的选项卡的变化,当它曾经被就好具有标签之间存在意见变化...

顺便说一句,这code,从借来的:http://thepseudo$c$cr.word$p$pss.com/2011/10/04/android-tabs-the-fragment-way/

 公共类标签扩展FragmentActivity工具
    TabHost.OnTabChangeListener {

最后弦乐MAP_TAB =地图;
最后弦乐IMAGES_TAB =图像;
最后弦乐SETTINGS_TAB =设置;

TabHost mTab​​Host;
HashMap的<字符串,TabInfo> mapTabInfo =新的HashMap<字符串,TabInfo>();
TabInfo mLastTab = NULL;

私有类TabInfo {
    私人字符串标签;
    私有类CLSS;
    私人捆绑ARGS;
    私人片段片段;
    TabInfo(字符串标记,类clazz中,捆绑参数){
        this.tag =标签;
        this.clss = clazz所;
        this.args = ARGS;
    }

}

类TabFactory实现TabContentFactory {

    私人最终语境mContext;

    公共TabFactory(上下文的背景下){
        mContext =背景;
    }

    公共查看createTabContent(字符串变量){
        视图V =新景(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        返回伏;
    }

}

保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    的setContentView(R.layout.main);

    initialiseTabHost(savedInstanceState);
    如果(savedInstanceState!= NULL)
        mTabHost.setCurrentTabByTag(savedInstanceState.getString(标签)); //设置选项卡按保存的状态
}

保护无效的onSaveInstanceState(包outState){
    outState.putString(标签,mTabHost.getCurrentTabTag()); //保存选定的标签
    super.onSaveInstanceState(outState);
}

私人无效initialiseTabHost(捆绑的args){
    mTabHost =(TabHost)findViewById(android.R.id.tabhost);
    mTabHost.setup();
    TabInfo tabInfo;

    Tabs.addTab(这一点,
            mTabHost,
            mTabHost.newTabSpec(MAP_TAB).setIndicator(
                    MAP_TAB,
                    getResources()。getDrawable(R.drawable.ic_tab_map_states)),
            (tabInfo =新TabInfo(MAP_TAB,HMapFragment_NEW.class,参数)));
    mapTabInfo.put(tabInfo.tag,tabInfo);

    Tabs.addTab(这一点,
            mTabHost,
            mTabHost.newTabSpec(IMAGES_TAB).setIndicator(
                    IMAGES_TAB,
                    getResources()。getDrawable(R.drawable.ic_tab_gallery_states)),
            (tabInfo =新TabInfo(IMAGES_TAB,ImageGridFragment.class,参数)));
    mapTabInfo.put(tabInfo.tag,tabInfo);

    Tabs.addTab(这一点,
            mTabHost,
            mTabHost.newTabSpec(SETTINGS_TAB).setIndicator(
                    SETTINGS_TAB,
                    getResources()。getDrawable(R.drawable.ic_tab_settings_states)),
            (tabInfo =新TabInfo(SETTINGS_TAB,SettingsFragment.class,参数)));
    mapTabInfo.put(tabInfo.tag,tabInfo);

    //默认为第一个选项卡
    this.onTabChanged(MAP_TAB);
    mTabHost.setOnTabChangedListener(本);
}

私有静态无效addTab(标签活动,TabHost tabHost,TabHost.TabSpec则tabspec,TabInfo tabInfo){
    //附加选项卡视图工厂规范
    tabSpec.setContent(activity.new TabFactory(活动));
    字符串变量= tabSpec.getTag();

    //检查,看看是否已经有此标签的片段,可能
    //从previously保存的状态。如果是这样,禁用它,因为我们
    //初始状态是一个选项卡不显示。
    tabInfo.fragment = activity.getSupportFragmentManager()findFragmentByTag(标签)。
    如果(tabInfo.fragment =空&安培;!&安培;!tabInfo.fragment.isDetached()){
        FragmentTransaction英尺= activity.getSupportFragmentManager()的BeginTransaction()。
        ft.detach(tabInfo.fragment);
        ft.commit();
        activity.getSupportFragmentManager()executePendingTransactions()。
    }

    tabHost.addTab(则tabspec);
}

公共无效onTabChanged(字符串标签){
    TabInfo newTab = this.mapTabInfo.get(标签);
    //如果他们点击过改变标签
    如果(mLastTab!= newTab){
        FragmentTransaction英尺= this.getSupportFragmentManager()的BeginTransaction()。
        如果(mLastTab!= NULL)
            如果(mLastTab.fragment!= NULL)ft.detach(mLastTab.fragment);
        如果(newTab!= NULL){
            如果(newTab.fragment == NULL){
                newTab.fragment = Fragment.instantiate(这一点,newTab.clss.getName(),newTab.args);
                ft.add(R.id.realtabcontent,newTab.fragment,newTab.tag);
            }其他ft.attach(newTab.fragment);
        }

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

解决方案

有三种方法可以从视图中删除一个片段:

在隐藏它(对交易对象隐藏功能) 在分离它(在交易对象分离功能) 删除它(取消对交易对象功能)

如果您隐藏的视图获取隐藏,但仍然是在布局,并应保持不变。如果您分离它,认为被推倒,但该片段由FragmentManager仍设法(和将被重新创建一个配置更改,例如)。如果您删除它它就会从FragmentManager完全删除,它的国家将不再进行管理。

Android 4 Fragment,ViewPager

I've been working with Android for a while, but fragments are a little new to me (as they are to most people probably). Anyway, I've got the below code, and it works fine. I've got three fragments, one in each tab. I'm wondering if it's normal for onCreateView to be called everytime I switch tabs, and does it make sense to do so? Shouldn't there be a way to NOT redraw the fragment every time the tab changes?

I'm converting this from an app that had 3 activities, one in each tab, and it seems like a waste to recreate the view every time the tab changes, when it used to be just fine having the views exist between tab changes...

BTW, this code borrowed from: http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/

public class Tabs extends FragmentActivity implements
    TabHost.OnTabChangeListener {

final String MAP_TAB = "Map";
final String IMAGES_TAB = "Images";
final String SETTINGS_TAB = "Settings";

TabHost mTabHost;
HashMap<String, TabInfo> mapTabInfo = new HashMap<String, TabInfo>();
TabInfo mLastTab = null;

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

}

class TabFactory implements TabContentFactory {

    private final Context mContext;

    public TabFactory(Context context) {
        mContext = context;
    }

    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }

}

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);

    initialiseTabHost(savedInstanceState);
    if (savedInstanceState != null)
        mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
}

protected void onSaveInstanceState(Bundle outState) {
    outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
    super.onSaveInstanceState(outState);
}

private void initialiseTabHost(Bundle args) {
    mTabHost = (TabHost)findViewById(android.R.id.tabhost);
    mTabHost.setup();
    TabInfo tabInfo;

    Tabs.addTab(this,
            mTabHost,
            mTabHost.newTabSpec(MAP_TAB).setIndicator(
                    MAP_TAB,
                    getResources().getDrawable(R.drawable.ic_tab_map_states)),
            ( tabInfo = new TabInfo(MAP_TAB, HMapFragment_NEW.class, args)));
    mapTabInfo.put(tabInfo.tag, tabInfo);

    Tabs.addTab(this,
            mTabHost,
            mTabHost.newTabSpec(IMAGES_TAB).setIndicator(
                    IMAGES_TAB,
                    getResources().getDrawable(R.drawable.ic_tab_gallery_states)),
            ( tabInfo = new TabInfo(IMAGES_TAB, ImageGridFragment.class, args)));
    mapTabInfo.put(tabInfo.tag, tabInfo);

    Tabs.addTab(this,
            mTabHost,
            mTabHost.newTabSpec(SETTINGS_TAB).setIndicator(
                    SETTINGS_TAB,
                    getResources().getDrawable(R.drawable.ic_tab_settings_states)),
            ( tabInfo = new TabInfo(SETTINGS_TAB, SettingsFragment.class, args)));
    mapTabInfo.put(tabInfo.tag, tabInfo);

    // Default to first tab
    this.onTabChanged(MAP_TAB);
    mTabHost.setOnTabChangedListener(this);
}

private static void addTab(Tabs 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);
}

public void onTabChanged(String tag) {
    TabInfo newTab = this.mapTabInfo.get(tag);
    // if they've clicked to change tabs
    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();
    }
}
}

解决方案

There a 3 ways to remove a Fragment from view:

Hide it (hide function on transaction object) Detach it (detach function on transaction object) Remove it (remove function on transaction object)

If you hide it the view gets hidden, but is still in the layout and should stay intact. If you detach it, the view gets torn down, but the fragment is still managed by the FragmentManager (and will be recreated on a configuration change, for example). If you remove it it gets removed from the FragmentManager completely and it's state will no longer be managed.