草庐IT

android - 在选项卡内切换 fragment

coder 2023-06-08 原文

我正在创建一个使用 ActionBarSherlock 的应用。该应用程序由三个选项卡组成,在每个选项卡中,多个屏幕根据用户输入连续显示。我可以在选项卡之间切换 fragment ,但是在 选项卡中切换 fragment 会出现问题。我试过这样:

在主类中:

SingleStationFragment singleStationFragment = new SingleStationFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, singleStationFragment);
transaction.addToBackStack(null);
transaction.commit();

确实替换了第二个 fragment 的第一个 fragment ,但是当我更改选项卡时,第二个 fragment 仍然可见,在旧选项卡的内容之上显示新选项卡的内容。我想我需要以某种方式分离 onTabUnselected 中的第二个 fragment ,但我不知道如何获取对这个 fragment 的引用。

谁能帮我解决这个问题?

为了清楚起见,一些重要的类:

我的主要类(class):

public class TreinVerkeer extends SherlockFragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupTabs(savedInstanceState);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    private void setupTabs(Bundle savedInstanceState) {
        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        Tab tab = actionBar.newTab().setText("STATIONS").setTabListener(new TabListener<StationsFragment>(this, "stations", StationsFragment.class));
        actionBar.addTab(tab);

        tab = actionBar.newTab().setText("ROUTE").setTabListener(new TabListener<RouteFragment>(this, "route", RouteFragment.class));
        actionBar.addTab(tab);

        tab = actionBar.newTab().setText("DELAYS").setTabListener(new TabListener<DelaysFragment>(this, "delays", DelaysFragment.class));
        actionBar.addTab(tab);

        if (savedInstanceState != null) {
            actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
    }
}

TabListener(来自 "Adding Navigations Tabs" on the Android developer site,有一些小的改动):

public class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener {
    private SherlockFragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    /**
     * Constructor used each time a new tab is created.
     * 
     * @param activity
     *            The host Activity, used to instantiate the fragment
     * @param tag
     *            The identifier tag for the fragment
     * @param clz
     *            The fragment's Class, used to instantiate the fragment
     */
    public TabListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    /* The following are each of the ActionBar.TabListener callbacks */

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
    SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);

    // Check if the fragment is already initialized
    if (mFragment == null && preInitializedFragment == null) {
        // If not, instantiate and add it to the activity
        mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName());
        ft.add(android.R.id.content, mFragment, mTag);
    } else if (mFragment != null) {
        // If it exists, simply attach it in order to show it
        ft.attach(mFragment);
    } else if (preInitializedFragment != null) {
        ft.attach(preInitializedFragment);
        mFragment = preInitializedFragment;
    }
}

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            // Detach the fragment, because another one is being attached
            ft.detach(mFragment);
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

StationsFragment(RouteFragmentDelaysFragment是一样的,只是文字不同)

public class StationsFragment extends SherlockFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.stationsfragment, container, false);
    }
}

最佳答案

所以发生的事情是,在 TabListener 中,在 onTabUnselected 方法中,Fragment 没有分离,导致它仍然显示同时显示了一个新的 Fragment

造成这种情况的原因是,被分离的 Fragment 是第一个 fragment ,而不是我的第二个 fragment 。我做了一些改变。

Activity中:

SingleStationFragment singleStationFragment = new SingleStationFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, singleStationFragment, "STATIONS");
transaction.addToBackStack(null);
transaction.commit();

这里我在replace()方法中添加了"STATIONS"标签,和第一个 fragment 是同一个标签。
TabListener 现在如下:

public class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener {
    private final SherlockFragmentActivity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    private SherlockFragment mFragment;

    public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
        if (preInitializedFragment == null) {
            mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName());
            ft.add(R.id.treinverkeer_fragmentcontent, mFragment, mTag);
        } else {
            ft.attach(preInitializedFragment);
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);

        if (preInitializedFragment != null) {
            ft.detach(preInitializedFragment);
        } else if (mFragment != null) {
            ft.detach(mFragment);
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

onTabUnselected 方法中,我现在首先检索正确的 Fragment,然后将其分离。

希望这对某人有所帮助!

关于android - 在选项卡内切换 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10502786/

有关android - 在选项卡内切换 fragment的更多相关文章

  1. ruby-on-rails - Ruby on Rails with Haml - 如何从 erb 切换 - 2

    我正在从erb文件切换到HAML。我将hamlgem添加到我的系统中。我创建了app/views/layouts/application.html.haml文件。我应该只删除application.html.erb文件吗?此外,仍然有/public/index.html文件被呈现为默认页面。我想创建自己的默认index.html.haml页面。我应该把它放在哪里以及如何使系统呈现该文件而不是默认索引文件?谢谢! 最佳答案 是的,您可以删除任何已转换为HAML的View的ERB版本。至于你的另一个问题,删除public/index/h

  2. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  3. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  4. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  5. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

  6. ruby - 选项卡的 Rubocop - 2

    我们想使用Rubocop来验证我们的ruby​​在语法上是否正确并遵循基本代码指南。除此之外我们有这个规则:我们使用制表符缩进以允许任何人决定他们希望如何呈现它们(将它们显示为2或4个空格)问题是rubocop似乎设计为完全拒绝缩进标签。我们怎样才能超越所有这些规则成为太空合规者?编辑:我正在考虑覆盖这个模块https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/source_parser.rb将我文件中的所有制表符替换为2个空格,以创建gem的幻觉... 最佳答案 添加

  7. ruby - Ruby 中的选项菜单 - 2

    我正在尝试在Ruby中创建一个菜单,以便根据用户输入的内容,取决于调用的类。然后在这种情况下它将返回到“Main”或类“Options”。我希望有人能帮助我。这是我的代码。modulePhysicsG=21C=20000Pi=3.14D=100endclassOptionsputs"Pleaseselect1forAccelerationand2forEnergy."option=gets()ifoption==1thenputs"AccelCalc"#ThisisthebitthatneedstodirecttheusertotheclassAccelCalcelseputs"Ene

  8. ruby-on-rails - 用一系列时间增量填充选择,加上其他选项 - 2

    使用RubyonRails,我使用给定的增量(例如每30分钟)用时间填充“选择”。目前我正在YAML文件中写出所有的可能性,但我觉得有一种更巧妙的方法。我想我想提供一个开始时间、一个结束时间、一个增量,并且目前只提供一个名为“关闭”的选项(想想“business_hours”)。所以,我的选择可能会显示:'Closed'5:00am5:30am6:00am...[allthewayto]...11:30pm谁能想出更好的方法,或者只是将它们全部“拼写”出来的最佳方法? 最佳答案 此答案基于@emh的答案。defcreate_hour

  9. ruby - 如何获取适用于 ruby​​ 1.9.1 的 to_yaml 方法的格式化选项? - 2

    根据YAML文档,可以传递hashofoptions到.to_yaml方法。目前,当我按照文档中的建议传递选项时,它不起作用,哈希被忽略。irb(main):001:0>require'yaml'=>trueirb(main):002:0>user={"1"=>{"name"=>"john","age"=>44}}user.to_yaml=>"---\n\"1\":\nname:john\nage:44\n"现在,传递一些选项:irb(main):014:0>user.to_yaml(:Indent=>4,:UseHeader=>true,:UseVersion=>true)=>"--

  10. ruby-on-rails - 语言环境不在 Rails 4 中切换 - 2

    我的Rails应用程序在rails4.0.2上,我在使用locale变量和params[:locale]切换翻译时遇到问题官方railsguide.我在mysite有一个单页网站.我的国际化路线:scope"(:locale)",locale:/en|de/do#myrouteshereend我的应用程序Controllerbefore_filter:set_localedefset_localeI18n.locale=params[:locale]||I18n.default_locale#Rails.application.routes.default_url_options[:l

随机推荐