ViewPager,ActionBar,Fragment应用--模仿通讯录滑动效果

最近由Android2.3切换到Android4.0的开发,一下子居然有点不适应,Android4.0新增了一些功能模块如ActionBar,Fragment等其实在Android3.0就有了,但一直没有做过平板上的开发,所以对这些模块非常陌生,一下子感觉Android4.0的开发难度甚大,经过十来天的努力,终于略微有所悟,在看通讯录的时候,感觉如果将其效果模仿出来岂不是初步达到掌握这些模块。

先看图,再列举出代码:

按住左右滑动时会自动切换。

源代码下载:http://download.csdn.net/detail/hjj0212/5023509

主要代码如下:

    1. package com.example.testtabactionbar;  
    2.   
    3. import android.net.Uri;  
    4. import android.os.Bundle;  
    5. import android.os.Parcelable;  
    6. import android.provider.ContactsContract.Contacts;  
    7. import android.app.ActionBar;  
    8. import android.app.Activity;  
    9. import android.app.Fragment;  
    10. import android.app.FragmentManager;  
    11. import android.app.FragmentTransaction;  
    12. import android.app.ListFragment;  
    13. import android.app.ActionBar.Tab;  
    14. import android.app.LoaderManager.LoaderCallbacks;  
    15. import android.content.CursorLoader;  
    16. import android.content.Loader;  
    17. import android.database.Cursor;  
    18. import android.support.v4.view.PagerAdapter;  
    19. import android.support.v4.view.ViewPager;  
    20. import android.text.TextUtils;  
    21. import android.util.Log;  
    22. import android.view.ContextMenu;  
    23. import android.view.LayoutInflater;  
    24. import android.view.Menu;  
    25. import android.view.MenuItem;  
    26. import android.view.View;  
    27. import android.view.ViewGroup;  
    28. import android.view.ContextMenu.ContextMenuInfo;  
    29. import android.widget.ArrayAdapter;  
    30. import android.widget.ListView;  
    31. import android.widget.SimpleCursorAdapter;  
    32. import android.widget.Toast;  
    33. import android.widget.SearchView.OnQueryTextListener;  
    34.   
    35. public class MainActivity extends Activity {  
    36.     private ActionBar mActionBar;  
    37.     private static final TabState DEFAULT_TAB = TabState.GROUPS;  
    38.     private TabState mCurrentTab = DEFAULT_TAB;  
    39.     private final MyTabListener mTabListener = new MyTabListener();  
    40.     private ArraListFragment mArrayFragment;  
    41.     private CursorLoaderFragment mCursorFragment;  
    42.     private ContextMenuFragment mContextMenuFragment;  
    43.     private ViewPager mTabPager;  
    44.     private TabPagerAdapter mTabPagerAdapter;     
    45.     private final TabPagerListener mTabPagerListener = new TabPagerListener();  
    46.       
    47.     @Override  
    48.     protected void onCreate(Bundle savedInstanceState) {  
    49.         super.onCreate(savedInstanceState);  
    50.         setContentView(R.layout.tab_view_pager);  
    51.         initActionBar();  
    52.         createViewAndFragment();  
    53.     }  
    54.       
    55.     private void createViewAndFragment(){  
    56.         final FragmentManager fragmentManager = getFragmentManager();  
    57.         final FragmentTransaction transaction = fragmentManager.beginTransaction();  
    58.           
    59.         mTabPager = getView(R.id.tab_pager);  
    60.         mTabPagerAdapter = new TabPagerAdapter();  
    61.         mTabPager.setAdapter(mTabPagerAdapter);  
    62.         mTabPager.setOnPageChangeListener(mTabPagerListener);  
    63.   
    64.         final String FAVORITE_TAG = "tab-pager-favorite";  
    65.         final String ALL_TAG = "tab-pager-all";  
    66.         final String GROUPS_TAG = "tab-pager-groups";  
    67.   
    68.         // Create the fragments and add as children of the view pager.  
    69.         // The pager adapter will only change the visibility; it'll never create/destroy  
    70.         // fragments.  
    71.         // However, if it's after screen rotation, the fragments have been re-created by  
    72.         // the fragment manager, so first see if there're already the target fragments  
    73.         // existing.  
    74.         mContextMenuFragment = (ContextMenuFragment) fragmentManager  
    75.                 .findFragmentByTag(FAVORITE_TAG);  
    76.         mArrayFragment = (ArraListFragment) fragmentManager  
    77.                 .findFragmentByTag(ALL_TAG);  
    78.         mCursorFragment = (CursorLoaderFragment) fragmentManager  
    79.                 .findFragmentByTag(GROUPS_TAG);  
    80.   
    81.         if (mContextMenuFragment == null) {  
    82.             Log.e("HJJ", "ContextMenuFragmentd == null");  
    83.             mContextMenuFragment = new ContextMenuFragment();  
    84.             mArrayFragment = new ArraListFragment();  
    85.             mCursorFragment = new CursorLoaderFragment();  
    86.   
    87.             transaction.add(R.id.tab_pager, mContextMenuFragment, FAVORITE_TAG);  
    88.             transaction.add(R.id.tab_pager, mArrayFragment, ALL_TAG);  
    89.             transaction.add(R.id.tab_pager, mCursorFragment, GROUPS_TAG);  
    90.         }  
    91.   
    92.         // Hide all fragments for now. We adjust visibility when we get  
    93.         // onSelectedTabChanged()  
    94.         // from ActionBarAdapter.  
    95.         transaction.hide(mContextMenuFragment);  
    96.         transaction.hide(mArrayFragment);  
    97.         transaction.hide(mCursorFragment);  
    98.           
    99.         transaction.commitAllowingStateLoss();  
    100.         fragmentManager.executePendingTransactions();  
    101.     }  
    102.       
    103.     private class TabPagerListener implements ViewPager.OnPageChangeListener {  
    104.         @Override  
    105.         public void onPageScrollStateChanged(int state) {  
    106.         }  
    107.   
    108.         @Override  
    109.         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
    110.         }  
    111.   
    112.         @Override  
    113.         public void onPageSelected(int position) {  
    114.             // Make sure not in the search mode, in which case position != TabState.ordinal().  
    115.             TabState selectedTab = TabState.fromInt(position);  
    116.             setCurrentTab(selectedTab, false);  
    117.             invalidateOptionsMenu();  
    118.         }  
    119.     }  
    120.       
    121.     private void initActionBar(){  
    122.         mActionBar = getActionBar();  
    123.         mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  
    124.         // 去掉默认标题栏  
    125.         mActionBar.setDisplayShowHomeEnabled(false);    
    126.         mActionBar.setDisplayShowTitleEnabled(false);   
    127.         // Set up tabs  
    128.         addTab(TabState.GROUPS, R.drawable.ic_tab_groups);  
    129.         addTab(TabState.ALL, R.drawable.ic_tab_all);  
    130.         addTab(TabState.FAVORITES, R.drawable.ic_tab_starred);  
    131.     }  
    132.       
    133.     private class TabPagerAdapter extends PagerAdapter {  
    134.         private final FragmentManager mFragmentManager;  
    135.         private FragmentTransaction mCurTransaction = null;  
    136.   
    137.         private boolean mTabPagerAdapterSearchMode;  
    138.   
    139.         private Fragment mCurrentPrimaryItem;  
    140.   
    141.         public TabPagerAdapter() {  
    142.             mFragmentManager = getFragmentManager();  
    143.         }  
    144.   
    145.         @Override  
    146.         public int getCount() {  
    147.             return mTabPagerAdapterSearchMode ? 1 : TabState.values().length;  
    148.         }  
    149.   
    150.         /** Gets called when the number of items changes. */  
    151.         @Override  
    152.         public int getItemPosition(Object object) {  
    153.             if (mTabPagerAdapterSearchMode) {  
    154.                 if (object == mArrayFragment) {  
    155.                     return 0; // Only 1 page in search mode  
    156.                 }  
    157.             } else {  
    158.                 if (object == mContextMenuFragment) {  
    159.                     return TabState.FAVORITES.ordinal();  
    160.                 }  
    161.                 if (object == mArrayFragment) {  
    162.                     return TabState.ALL.ordinal();  
    163.                 }  
    164.                 if (object == mCursorFragment) {  
    165.                     return TabState.GROUPS.ordinal();  
    166.                 }  
    167.             }  
    168.             return POSITION_NONE;  
    169.         }  
    170.   
    171.         @Override  
    172.         public void startUpdate(View container) {  
    173.         }  
    174.   
    175.         private Fragment getFragment(int position) {  
    176.             if (position == TabState.FAVORITES.ordinal()) {  
    177.                 return mContextMenuFragment;  
    178.             } else if (position == TabState.ALL.ordinal()) {  
    179.                 return mArrayFragment;  
    180.             } else if (position == TabState.GROUPS.ordinal()) {  
    181.                 return mCursorFragment;  
    182.             }  
    183.             throw new IllegalArgumentException("position: " + position);  
    184.         }  
    185.   
    186.         @Override  
    187.         public Object instantiateItem(View container, int position) {  
    188.             if (mCurTransaction == null) {  
    189.                 mCurTransaction = mFragmentManager.beginTransaction();  
    190.             }  
    191.             Fragment f = getFragment(position);  
    192.             mCurTransaction.show(f);  
    193.   
    194.             // Non primary pages are not visible.  
    195.             //f.setUserVisibleHint(f == mCurrentPrimaryItem);  
    196.             return f;  
    197.         }  
    198.   
    199.         @Override  
    200.         public void destroyItem(View container, int position, Object object) {  
    201.             if (mCurTransaction == null) {  
    202.                 mCurTransaction = mFragmentManager.beginTransaction();  
    203.             }  
    204.             mCurTransaction.hide((Fragment) object);  
    205.         }  
    206.   
    207.         @Override  
    208.         public void finishUpdate(View container) {  
    209.             if (mCurTransaction != null) {  
    210.                 mCurTransaction.commitAllowingStateLoss();  
    211.                 mCurTransaction = null;  
    212.                 mFragmentManager.executePendingTransactions();  
    213.             }  
    214.         }  
    215.   
    216.         @Override  
    217.         public boolean isViewFromObject(View view, Object object) {  
    218.             return ((Fragment) object).getView() == view;  
    219.         }  
    220.   
    221.         @Override  
    222.         public void setPrimaryItem(View container, int position, Object object) {  
    223.             Fragment fragment = (Fragment) object;  
    224.             if (mCurrentPrimaryItem != fragment) {  
    225.                 if (mCurrentPrimaryItem != null) {  
    226.                     //mCurrentPrimaryItem.setUserVisibleHint(false);  
    227.                 }  
    228.                 if (fragment != null) {  
    229.                     //fragment.setUserVisibleHint(true);  
    230.                 }  
    231.                 mCurrentPrimaryItem = fragment;  
    232.             }  
    233.         }  
    234.   
    235.         @Override  
    236.         public Parcelable saveState() {  
    237.             return null;  
    238.         }  
    239.   
    240.         @Override  
    241.         public void restoreState(Parcelable state, ClassLoader loader) {  
    242.         }  
    243.     }  
    244.       
    245.     @SuppressWarnings("unchecked")  
    246.     public <T extends View> T getView(int id) {  
    247.         T result = (T)findViewById(id);  
    248.         if (result == null) {  
    249.             throw new IllegalArgumentException("view 0x" + Integer.toHexString(id)  
    250.                     + " doesn't exist");  
    251.         }  
    252.         return result;  
    253.     }  
    254.       
    255.     protected static void showFragment(FragmentTransaction ft, Fragment f) {  
    256.         if ((f != null) && f.isHidden()) ft.show(f);  
    257.     }  
    258.   
    259.     protected static void hideFragment(FragmentTransaction ft, Fragment f) {  
    260.         if ((f != null) && !f.isHidden()) ft.hide(f);  
    261.     }  
    262.       
    263.     private void addTab(TabState tabState, int icon) {  
    264.         final Tab tab = mActionBar.newTab();  
    265.         tab.setTag(tabState);  
    266.         tab.setTabListener(mTabListener);  
    267.         tab.setIcon(icon);  
    268.         mActionBar.addTab(tab);  
    269.     }  
    270.   
    271.     public enum TabState {  
    272.         GROUPS, ALL, FAVORITES;  
    273.   
    274.         public static TabState fromInt(int value) {  
    275.             if (GROUPS.ordinal() == value) {  
    276.                 return GROUPS;  
    277.             }  
    278.             if (ALL.ordinal() == value) {  
    279.                 return ALL;  
    280.             }  
    281.             if (FAVORITES.ordinal() == value) {  
    282.                 return FAVORITES;  
    283.             }  
    284.             throw new IllegalArgumentException("Invalid value: " + value);  
    285.         }  
    286.     }  
    287.       
    288.     private class MyTabListener implements ActionBar.TabListener {  
    289.         /** 
    290.          * If true, it won't call {@link #setCurrentTab} in {@link #onTabSelected}. 
    291.          * This flag is used when we want to programmatically update the current tab without 
    292.          * {@link #onTabSelected} getting called. 
    293.          */  
    294.         public boolean mIgnoreTabSelected;  
    295.   
    296.         @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { }  
    297.         @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { }  
    298.   
    299.         @Override public void onTabSelected(Tab tab, FragmentTransaction ft) {  
    300.             Log.e("HJJ", "onTabSelected..tag:" + tab.getTag());  
    301.             if (!mIgnoreTabSelected) {  
    302.                 setCurrentTab((TabState)tab.getTag());  
    303.             }  
    304.         }  
    305.     }  
    306.   
    307.     /** 
    308.      * Change the current tab, and notify the listener. 
    309.      */  
    310.     public void setCurrentTab(TabState tab) {  
    311.         setCurrentTab(tab, true);  
    312.     }  
    313.   
    314.     /** 
    315.      * Change the current tab 
    316.      */  
    317.     public void setCurrentTab(TabState tab, boolean notifyListener) {  
    318.         if (tab == null) throw new NullPointerException();  
    319.         //实际上按照Contacts中的设计,这个是应该有效的,但在此模拟程序中,它会出现问题,因此暂时将此段去掉  
    320. //        if (tab == mCurrentTab) {  
    321. //            return;  
    322. //        }  
    323.         mCurrentTab = tab;  
    324.   
    325.         int index = mCurrentTab.ordinal();  
    326.         if ((mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS)  
    327.                 && (index != mActionBar.getSelectedNavigationIndex())) {  
    328.             mActionBar.setSelectedNavigationItem(index);  
    329.         }  
    330.   
    331.         if (notifyListener) onSelectedTabChanged(tab);  
    332.     }  
    333.       
    334.     private void onSelectedTabChanged(TabState tab){  
    335.         FragmentManager fragmentManager = getFragmentManager();  
    336.         FragmentTransaction ft = fragmentManager.beginTransaction();  
    337.         int tabIndex = tab.ordinal();  
    338.         Log.e("HJJ", "tabIndex:" + tabIndex);  
    339.         switch (tab) {  
    340.         case FAVORITES:  
    341.             if(mContextMenuFragment!=null){  
    342.                 mTabPager.setCurrentItem(tabIndex, false);  
    343.             }  
    344.             showFragment(ft, mContextMenuFragment);  
    345.             hideFragment(ft, mArrayFragment);  
    346.             hideFragment(ft, mCursorFragment);  
    347.             break;  
    348.         case ALL:  
    349.             if(mArrayFragment!=null){  
    350.                 mTabPager.setCurrentItem(tabIndex, false);  
    351.             }  
    352.             hideFragment(ft, mContextMenuFragment);  
    353.             hideFragment(ft, mCursorFragment);  
    354.             showFragment(ft, mArrayFragment);  
    355.             break;  
    356.         case GROUPS:  
    357.             if(mCursorFragment!=null){  
    358.                 mTabPager.setCurrentItem(tabIndex, false);  
    359.             }  
    360.             hideFragment(ft, mContextMenuFragment);  
    361.             hideFragment(ft, mArrayFragment);  
    362.             showFragment(ft, mCursorFragment);  
    363.             break;  
    364.         }  
    365.         if (!ft.isEmpty()) {  
    366.             Log.e("HJJ", "not ft isEmpty");  
    367.             ft.commitAllowingStateLoss();  
    368.             fragmentManager.executePendingTransactions();  
    369.             // When switching tabs, we need to invalidate options menu, but executing a  
    370.             // fragment transaction does it implicitly.  We don't have to call invalidateOptionsMenu  
    371.             // manually.  
    372.         }  
    373.     }  
    374.       
    375.       
    376.       
    377.     public static class ArraListFragment extends ListFragment{  
    378.         @Override  
    379.         public void onActivityCreated(Bundle savedInstanceState) {  
    380.             // TODO Auto-generated method stub  
    381.             super.onActivityCreated(savedInstanceState);  
    382.             String [] array = new String[]{"C", "C++", "Java"};  
    383.             setListAdapter(new ArrayAdapter<String>(getActivity(),   
    384.                     android.R.layout.simple_list_item_1, array));  
    385.         }  
    386.           
    387.         @Override  
    388.         public void onListItemClick(ListView l, View v, int position, long id) {  
    389.             // TODO Auto-generated method stub  
    390.             super.onListItemClick(l, v, position, id);  
    391.         }  
    392.     }  
    393.       
    394.     public static class CursorLoaderFragment extends ListFragment implements  
    395.             OnQueryTextListener, LoaderCallbacks<Cursor> {  
    396.   
    397.         SimpleCursorAdapter mAdapter;  
    398.         String mCurFilter;  
    399.   
    400.         final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {  
    401.                 Contacts._ID, Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS,  
    402.                 Contacts.CONTACT_PRESENCE, Contacts.PHOTO_ID,  
    403.                 Contacts.LOOKUP_KEY, };  
    404.   
    405.         @Override  
    406.         public void onActivityCreated(Bundle savedInstanceState) {  
    407.             // TODO Auto-generated method stub  
    408.             super.onActivityCreated(savedInstanceState);  
    409.   
    410.             setEmptyText("No phone numbers");  
    411.             setHasOptionsMenu(true);  
    412.   
    413.             mAdapter = new SimpleCursorAdapter(getActivity(),  
    414.                     android.R.layout.simple_list_item_2, null, new String[] {  
    415.                             Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },  
    416.                     new int[] { android.R.id.text1, android.R.id.text2 }, 0);  
    417.             setListAdapter(mAdapter);  
    418.             setListShown(false);  
    419.             getLoaderManager().initLoader(0, null, this);  
    420.         }  
    421.   
    422. //      @Override  
    423. //      public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {  
    424. //          // TODO Auto-generated method stub  
    425. //          MenuItem item = menu.add("Search");  
    426. //          item.setIcon(android.R.drawable.ic_menu_search);  
    427. //          item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM  
    428. //                  | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);  
    429. //          SearchView sv = new SearchView(getActivity());  
    430. //          sv.setOnQueryTextListener(this);  
    431. //          item.setActionView(sv);  
    432. //      }  
    433.   
    434.         @Override  
    435.         public boolean onQueryTextChange(String newText) {  
    436.             // TODO Auto-generated method stub  
    437.             String newFilter = !TextUtils.isEmpty(newText) ? newText : null;  
    438.             if (mCurFilter == null && newFilter == null) {  
    439.                 return true;  
    440.             }  
    441.             if (mCurFilter != null && mCurFilter.equals(newFilter)) {  
    442.                 return true;  
    443.             }  
    444.   
    445.             mCurFilter = newFilter;  
    446.             getLoaderManager().restartLoader(0, null, this);  
    447.             return true;  
    448.         }  
    449.   
    450.         @Override  
    451.         public boolean onQueryTextSubmit(String query) {  
    452.             // TODO Auto-generated method stub  
    453.             return true;  
    454.         }  
    455.   
    456.         @Override  
    457.         public void onListItemClick(ListView l, View v, int position, long id) {  
    458.             // TODO Auto-generated method stub  
    459.             super.onListItemClick(l, v, position, id);  
    460.             Cursor c = (Cursor) mAdapter.getItem(position);  
    461.             String name = c.getString(0);  
    462.             Toast.makeText(getActivity(), "name:" + name, Toast.LENGTH_SHORT)  
    463.                     .show();  
    464.         }  
    465.   
    466.         @Override  
    467.         public Loader<Cursor> onCreateLoader(int id, Bundle args) {  
    468.             // TODO Auto-generated method stub  
    469.             Uri baseUri;  
    470.             if (mCurFilter != null) {  
    471.                 baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,  
    472.                         Uri.encode(mCurFilter));  
    473.             } else {  
    474.                 baseUri = Contacts.CONTENT_URI;  
    475.             }  
    476.             String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("  
    477.                     + Contacts.HAS_PHONE_NUMBER + "=1) AND ("  
    478.                     + Contacts.DISPLAY_NAME + " != '' ))";  
    479.             return new CursorLoader(getActivity(), baseUri,  
    480.                     CONTACTS_SUMMARY_PROJECTION, select, null,  
    481.                     Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");  
    482.         }  
    483.   
    484.         @Override  
    485.         public void onLoadFinished(Loader<Cursor> loader, Cursor data) {  
    486.             // TODO Auto-generated method stub  
    487.             mAdapter.swapCursor(data);  
    488.             if (isResumed()) {  
    489.                 setListShown(true);  
    490.             } else {  
    491.                 setListShownNoAnimation(true);  
    492.             }  
    493.         }  
    494.   
    495.         @Override  
    496.         public void onLoaderReset(Loader<Cursor> arg0) {  
    497.             // TODO Auto-generated method stub  
    498.             mAdapter.swapCursor(null);  
    499.         }  
    500.     }  
    501.       
    502.     public static class ContextMenuFragment extends Fragment{  
    503.         @Override  
    504.         public View onCreateView(LayoutInflater inflater, ViewGroup container,  
    505.                 Bundle savedInstanceState) {  
    506.             // TODO Auto-generated method stub  
    507.             View root = inflater.inflate(R.layout.fragment_context_menu, container, false);  
    508.             registerForContextMenu(root.findViewById(R.id.long_press));  
    509.             return root;  
    510.         }  
    511.           
    512.         @Override  
    513.         public void onCreateContextMenu(ContextMenu menu, View v,  
    514.                 ContextMenuInfo menuInfo) {  
    515.             // TODO Auto-generated method stub  
    516.             super.onCreateContextMenu(menu, v, menuInfo);  
    517.             menu.add(Menu.NONE, R.id.a_item, Menu.NONE, "Menu A");  
    518.             menu.add(Menu.NONE, R.id.b_item, Menu.NONE, "Menu B");  
    519.         }  
    520.           
    521.         @Override  
    522.         public boolean onContextItemSelected(MenuItem item) {  
    523.             // TODO Auto-generated method stub  
    524.             switch (item.getItemId()) {  
    525.             case R.id.a_item:  
    526.                 Toast.makeText(getActivity(), "a_item...", Toast.LENGTH_SHORT).show();  
    527.                 break;  
    528.             case R.id.b_item:  
    529.                 Toast.makeText(getActivity(), "b_item...", Toast.LENGTH_SHORT).show();  
    530.                 break;  
    531.             default:  
    532.                 break;  
    533.             }  
    534.             return super.onContextItemSelected(item);  
    535.         }  
    536.     }  
    537.       
posted @ 2016-11-05 17:02  天涯海角路  阅读(112)  评论(0)    收藏  举报