切换选项卡时无效上下文操作栏

时间:2013-12-06 23:20:42

标签: java android tabs contextual-action-bar

我正在寻找一种方法,以便当用户切换标签时,我所拥有的上下文操作栏变得无效。

我进行了设置,以便将标签链接到Fragments,每个标签都有不同的上下文操作栏。我想在onTabUnselected()方法中可能有一种方法可以做到这一点,但我不知道该怎么做。

非常感谢任何帮助。

package com.androidDev.taskmanager;

import java.util.ArrayList;
import java.util.Locale;

import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
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.FragmentPagerAdapter;
import android.support.v4.app.ListFragment;
import android.support.v4.view.ViewPager;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class Home extends FragmentActivity implements ActionBar.TabListener {
    private SectionsPagerAdapter mSectionsPagerAdapter;
    private ViewPager mViewPager;
    public static Menu mainMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the app.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        // When swiping between different sections, select the corresponding
        // tab. We can also use ActionBar.Tab#select() to do this if we have
        // a reference to the Tab.
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        actionBar.setSelectedNavigationItem(position);
                    }
                });

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title defined by
            // the adapter. Also specify this Activity object, which implements
            // the TabListener interface, as the callback (listener) for when
            // this tab is selected.
            actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.home, menu);
        mainMenu = menu;
        return true;
    }




    @Override
    public void onTabSelected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
        // When the given tab is selected, switch to the corresponding page in
        // the ViewPager.
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab,FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a DummySectionFragment (defined as a static inner class
            // below) with the page number as its lone argument.
            if(position==0){
                Fragment fragment = new ViewTaskFragment();
                return fragment;
            }
            else {
                Fragment fragment = new ViewReminderFragment();
                return fragment;
            }
        }

        @Override
        public int getCount() {
            // Show 2 total pages.
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
            case 0:
                return getString(R.string.title_tasks).toUpperCase(l);
            case 1:
                return getString(R.string.title_reminders).toUpperCase(l);
            }
            return null;
        }
    }

    public static class ViewTaskFragment extends ListFragment {
        private final boolean POST_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
        private SimpleCursorAdapter sca;
        private ListView lv;
        private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
            // Called when the action mode is created; startActionMode() was called
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                // Inflate a menu resource providing context menu items
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.task_context_menu, menu);
                return true;
            }

            // Called each time the action mode is shown. Always called after onCreateActionMode, but
            // may be called multiple times if the mode is invalidated.
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false; // Return false if nothing is done
            }

            // Called when the user selects a contextual menu item
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.menu_delete:
                        MyDB db = new MyDB(getActivity());
                        SparseBooleanArray checked = lv.getCheckedItemPositions();
                        ArrayList<String> valueBuilder = new ArrayList<String>();
                        String[] values;
                        for (int i = 0; i < checked.size(); i++) {
                            if(checked.valueAt(i) == true) {
                                valueBuilder.add(String.valueOf(lv.getItemIdAtPosition(i)));
                            }
                        }
                        values = valueBuilder.toArray(new String[valueBuilder.size()]);
                        if(values!=null)
                            db.deleteTasks(values);
                        refreshListView();
                        mode.finish(); // Action picked, so close the CAB
                        return true;
                    default:
                        return false;
                }
            }
            // Called when the user exits the action mode
            @Override
            public void onDestroyActionMode(ActionMode mode) {
                lv.clearChoices();
                for (int i = 0; i < lv.getChildCount(); i++)
                    lv.setItemChecked(i, false);
                mode = null;
            }
        };
        public ViewTaskFragment() {}
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstaceState) {
            final View rootView = inflater.inflate(R.layout.view_task, container, false);
            Context context = getActivity();
            hasOptionsMenu();
            String[] from = {"_id", "task_name", "completion_date"};
            int[] to={R.id.rpt_task_id, R.id.rpt_task_name, R.id.rpt_completion_date};
            MyDB db = new MyDB(context);
            sca = new SimpleCursorAdapter(context, R.layout.task_item, db.selectTasks(), from, to, 0);
            lv = (ListView) rootView.findViewById(android.R.id.list);
            lv.setAdapter(sca);
            lv.setLongClickable(true);
            lv.setOnItemLongClickListener(new OnItemLongClickListener() {
                    public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                        Toast.makeText(getActivity(), "Running onItemLongClick Orig Code", Toast.LENGTH_SHORT).show();
                        if(POST_HONEYCOMB) {
                             getActivity(). startActionMode(mActionModeCallback);
                        }
                        else {
                            //Needs at least honeycomb
                        }
                        return true;
                    }
                });
            return rootView;
        }

        @Override
        public void onResume() {
            super.onResume();
            refreshListView();
        }
        public void refreshListView() {
            MyDB db = new MyDB(getActivity());
            sca.changeCursor(db.selectTasks());
        }

    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        Intent intent = null;
        switch (item.getItemId()) {
        case R.id.mnu_action_settings:
            intent = new Intent(this, Settings.class);
            startActivity(intent);
            return true;
        case R.id.mnu_add_reminder:
            intent = new Intent(this, AddReminder.class);
            startActivity(intent);  
            return true;
        case R.id.mnu_add_task:
            intent = new Intent(this, AddTask.class);
            startActivity(intent);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
    /** New Fragment Section**/
    public static class ViewReminderFragment extends Fragment {
        private final boolean POST_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
        private SimpleCursorAdapter sca;
        private ListView lv;
        private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
            // Called when the action mode is created; startActionMode() was called
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                // Inflate a menu resource providing context menu items
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.task_context_menu, menu);
                return true;
            }

            // Called each time the action mode is shown. Always called after onCreateActionMode, but
            // may be called multiple times if the mode is invalidated.
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false; // Return false if nothing is done
            }

            // Called when the user selects a contextual menu item
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.menu_delete:
                        refreshListView();
                        mode.finish(); // Action picked, so close the CAB
                        return true;
                    default:
                        return false;
                }
            }
            // Called when the user exits the action mode
            @Override
            public void onDestroyActionMode(ActionMode mode) {
                lv.clearChoices();
                for (int i = 0; i < lv.getChildCount(); i++)
                    lv.setItemChecked(i, false);
                mode = null;
            }
        };


        public ViewReminderFragment() {}
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstaceState) {
            final View rootView = inflater.inflate(R.layout.view_reminder, container, false);
            Context context = getActivity();
            hasOptionsMenu();
            String[] from = {"_id", "task_name", "reminder_date"};
            int[] to={R.id.rpt_task_id, R.id.rpt_task_name, R.id.rpt_reminder_date};
            MyDB db = new MyDB(context);
            sca = new SimpleCursorAdapter(context, R.layout.reminder_item, db.selectReminder(), from, to, 0);
            lv = (ListView) rootView.findViewById(R.id.reminderList);
            lv.setAdapter(sca);
            lv.setLongClickable(true);
            lv.setOnItemLongClickListener(new OnItemLongClickListener() {
                    public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                        if(POST_HONEYCOMB) {
                             getActivity(). startActionMode(mActionModeCallback);
                        }
                        else {
                            //Needs at least honeycomb
                        }
                        return true;
                    }
                });
            return rootView;
        }

        @Override
        public void onResume() {
            super.onResume();
            refreshListView();
        }
        public void refreshListView() {
            MyDB db = new MyDB(getActivity());
            sca.changeCursor(db.selectReminder());
        }
    }

3 个答案:

答案 0 :(得分:7)

我想我找到了一种有趣的方式,而不是作弊&#34;。

首先,我创建了一个FragmentTabListener接口,以便活动可以让标签片段知道它们何时被选中或未被选中。

public interface FragmentTabListener {
    public void onTabSelected();

    public void onTabUnselected();
}

然后,在ActionBar.TabListener onTabUnselected()方法上,我可以让每个标签知道它被选中或取消选择的时间。

ActionBar.TabListener tabListener = new ActionBar.TabListener() {

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ((FragmentTabListener) MyFragmentForTab).onTabUnselected();
    }

我创建了一个不同的监听器,因为我并不想将其他东西暴露给选项卡,只是选择或取消选择它。此外,上面是一些隐藏无关信息的伪代码。

接下来,在用于特定选项卡的片段上,无论何时创建它都会保留actionMode(并在它被销毁时将其删除)

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    // Inflate the menu for the CAB
    ...
    MyFragmentForTab.this.mActionMode = mode;
    return true;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
    MyFragmentForTab.this.mActionMode = null;
}

最后,当取消选中标签时,我只需拨打

if (this.mActionMode != null)
    this.mActionMode.finish();

答案 1 :(得分:2)

所以这在做它的方式上有点作弊,但它有效。

我把它放在onTabUnselected()方法中。

        mViewPager.startActionMode(new ActionMode.Callback() {
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            // TODO Auto-generated method stub
            return false;
        }   
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            // TODO Auto-generated method stub

        }   
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // TODO Auto-generated method stub
            return false;
        }   
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            // TODO Auto-generated method stub
            return false;
        }
    });

答案 2 :(得分:0)

隐藏它怎么样?

 getActionBar().hide();

或作弊。如果选项卡打开(布尔值x =真)。如果为true,请使用Action Bar的功能。如果x = false则什么都不做。