【问题标题】:Android Fragments Not Being Replaced ProperlyAndroid 片段未正确替换
【发布时间】:2013-06-13 05:19:48
【问题描述】:

不幸的是,当我尝试在选项卡之间切换时,我收到与此人 (FragmentTransaction.replace() not working) 类似的错误,其中我的第一个选项卡中的文本列表出现在所有其他片段的背景中。我确实遵循了将 FrameLayout 与容器一起使用的建议,这样我就可以在切换选项卡时简单地添加或删除相关片段(这里也推荐 Fragment duplication on Fragment Transaction)。我正在尝试使用来自Switching fragments within tab 的@Niek 的TabListener 解决方案,但问题仍然存在。

我们将不胜感激所有帮助,非常感谢您抽出宝贵时间。

来自我的 MainActivity:

//Making an Action Bar
    ActionBar actionbar = getSupportActionBar();
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionbar.setTitle("MyApp");

    //Creating the Tabs
    ActionBar.Tab Frag1Tab = actionbar.newTab().setText("BlackList");
    ActionBar.Tab Frag2Tab = actionbar.newTab().setText("TreeMenu");
    ActionBar.Tab Frag3Tab = actionbar.newTab().setText("Map");
    ActionBar.Tab Frag4Tab = actionbar.newTab().setText("Help");

    //Fragments (Underlying Classes for Each Class)
    Fragment1 = new BlackistFragment();
    Fragment2 = new TreeMenuFragment();
    Fragment3 = new Fragment_3();
    Fragment4 = new Fragment_4();

    //Adding Tab Listeners 
    //new TabListener<StationsFragment>(this, "stations", StationsFragment.class)
    Frag1Tab.setTabListener(new TabListener<BlackistFragment>(this, "frag1", BlackistFragment.class));
    Frag2Tab.setTabListener(new TabListener<TreeMenuFragment>(this, "frag2", TreeMenuFragment.class));
    Frag3Tab.setTabListener(new TabListener<Fragment_3>(this, "frag3", Fragment_3.class));
    Frag4Tab.setTabListener(new TabListener<Fragment_4>(this, "frag4", Fragment_4.class));


    //Adding Tabs to Action Bar
    actionbar.addTab(Frag1Tab);
    actionbar.addTab(Frag2Tab);
    actionbar.addTab(Frag3Tab);
    actionbar.addTab(Frag4Tab);

标签监听器...

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> class1) {
        mActivity = activity;
        mTag = tag;
        mClass = class1;
    }

    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.fragment_container, 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.
    }
}

我的 BlackistFragment 选项卡中的 onCreateView(出现在所有其他选项卡中的那个..)。请注意,它扩展了 SherlockFragment

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    view = inflater.inflate(R.layout.blacklist, container, false);

    ListView listView = (ListView) view.findViewById(R.id.listview);

    //Making BlackList 
    TreeSet<BlacklistWord> theSet =  MainActivity.getInstance().datasource.GetAllWords();
    ArrayList<String> list = new ArrayList<String>();
    for(BlacklistWord i :theSet){
        System.out.println(i.getWord());
        list.add(i.getWord());
    }
    Collections.sort(list);
    adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1,  list);
    listView.setAdapter(adapter);
    ((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();

    ((ViewGroup) listView.getParent()).removeView(listView);
    container.addView(listView);

    return view;
}

我的第二个片段课...

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    MainActivity.getInstance().invalidateOptionsMenu();
    view = inflater.inflate(R.layout.treemenu, container, false);

    //Auto-Complete
    AutoCompleteTextView autoView = (AutoCompleteTextView) view.findViewById(R.id.edit_message);
    String[] itemOptions = getResources().getStringArray(R.array.edit_message);

    ArrayAdapter<String> theAdapter = 
            new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, itemOptions);
    autoView.setAdapter(theAdapter);
    ((BaseAdapter) autoView.getAdapter()).notifyDataSetChanged();
    //      ((ViewGroup) autoView.getParent()).removeView(autoView);
    Button b = (Button) view.findViewById(R.id.post_blacklist_button);
    b.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            AutoCompleteTextView editText=(AutoCompleteTextView) view.findViewById(R.id.edit_message);
            String blackListItem = editText.getText().toString();
            editText.setText("");
            MainActivity.getInstance().postBlackListItem(blackListItem);
            //refreshes the rest 
            MainActivity.getInstance().invalidateOptionsMenu();
        }
    });
    initViews(view);
    if(view != null) { return view; }

    ((ViewGroup) autoView.getParent()).removeView(autoView);
    container.addView(autoView);
    MainActivity.getInstance().invalidateOptionsMenu();
    return view;
}

【问题讨论】:

    标签: android android-layout android-fragments actionbarsherlock


    【解决方案1】:

    我认为向您展示我如何实现它比修改您的代码更容易。然后,您可以轻松地将其调整为适合您的用例。

    编辑:我更改了一些变量以匹配您的程序。

    这是实现 TabListener 的类:

    public class CustomTabListener implements TabListener {
        private Fragment fragment;
    
        public CustomTabListener(Fragment frag){
            fragment = frag;
        }
    
        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            ft.replace(R.id.fragment_container, fragment);      
        }
    
        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            ft.remove(fragment);
        }
    
        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            //Tab Reselected....    
        }
    
        }
    

    然后你可以像这样添加标签...

    private void addTabs() {
        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setTitle("MyApp");
    
        actionBar.addTab(actionBar.newTab()
                .setText("BlackList")
                .setTabListener(new CustomTabListener(Fragment1)));
        actionBar.addTab(actionBar.newTab()
                .setText("TreeMenu")
                .setTabListener(new CustomTabListener(Fragment2)));
        actionBar.addTab(actionBar.newTab()
                .setText("Map")
                .setTabListener(new CustomTabListener(Fragment3)));
        actionBar.addTab(actionBar.newTab()
                .setText("Help")
                .setTabListener(new CustomTabListener(Fragment4)));
    }
    

    您所要做的就是将片段传递给它。

    【讨论】:

    • 您好科里,感谢您的回复。看起来一个显着的区别是你的最后两行涉及 Drawable。我想知道您从哪里存储 R.drawable.gradient_rectangle,因为我没有迹象表明它存在于我的项目中。
    • 对不起,这与您的问题无关,我已经删除了这些并重命名了一些变量以匹配您目前所拥有的。您仍然需要在运行之前创建这些片段。
    • 嗨,Corey,很遗憾,您的代码无法解决我无处不在的片段问题。我已经在表单中定义了选项卡... Fragment1 = new BlackistFragment();等,如我原来的帖子中所见。
    • 好的,错误似乎在您的 Fragment 类之一中。您能否编辑您的原始帖子并添加您的 logcat 中的错误?
    • 嗨,Corey,谢谢你的耐心。没有错误被抛出。如果有帮助,我也添加了我的 TreeMenuFragment onCreateView。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    相关资源
    最近更新 更多