无需SherlockActionbar的SlidingMenu使用详解(二)——向Fragment中添加ViewPager和Tab
之前我們對大體框架有了一定的認識,現在我們來做Fragment界面,其實這里面和這個框架的關系就不大了,但因為有些同學對于在SlidingMenu中切換fragment還是有問題,所以我就在本篇進行詳細講解。
1.定義MenuFragment
1.1首先定義這個fragment的布局文件,其實很簡單了就是幾張圖片和一個listview
app_menu.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="200dp" android:layout_height="match_parent"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="120dp" ><ImageViewandroid:id="@+id/backgroundPicture_id"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitXY"android:src="@drawable/background" /><ImageViewandroid:id="@+id/head_pic_id"android:layout_width="60dp"android:layout_height="60dp"android:layout_alignParentLeft="true"android:layout_marginLeft="22dp"android:layout_marginTop="40dp"android:scaleType="fitXY"android:src="@drawable/kale" /><TextViewandroid:id="@+id/name_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignBottom="@+id/head_pic_id"android:layout_marginBottom="20dp"android:layout_marginLeft="20dp"android:layout_marginTop="55dp"android:layout_toRightOf="@id/head_pic_id"android:text="JackTony"android:textColor="#ffffff"android:textSize="20sp" /></RelativeLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="90dp"android:layout_marginTop="10dp"android:layout_marginBottom="10dp"android:gravity="center"android:orientation="horizontal" ><ImageViewandroid:id="@+id/personalSetting_id"android:layout_width="90dp"android:layout_height="90dp"android:layout_marginRight="10dp"android:src="@drawable/personalsettingbutton"android:scaleType="fitCenter" /><ImageViewandroid:id="@+id/releaseMessageButton_id"android:layout_width="90dp"android:layout_height="90dp"android:layout_marginLeft="10dp"android:src="@drawable/releasemessagebutton"android:scaleType="fitCenter" /></LinearLayout><RelativeLayout android:layout_width="match_parent"android:layout_height="match_parent"><ListViewandroid:id="@+id/menu_list"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="15dp" /></RelativeLayout></LinearLayout>
?
1.2和往常一樣,我們在Fragment中加載布局文件,并且給里面的listview添加適配器用于綁定數據
MenuFragment
package com.kale.slidingmenutest.fragment;import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView;import com.kale.slidingmenutest.MainActivity; import com.kale.slidingmenutest.R;/*** @author:JackTony* @tips :菜單的fragment* @date :2013-11-17*/ public class MenuFragment extends Fragment {private MainActivity activity;@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);this.activity = (MainActivity)activity;}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){View v = inflater.inflate(R.layout.app_menu, null);return v;}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);String []items = {"第一個欄目","第二個欄目"};ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1,items);ListView menuLv = (ListView)getActivity().findViewById(R.id.menu_list);//設置適配器和監聽器 menuLv.setAdapter(adapter);menuLv.setOnItemClickListener(new MenuItemClickListener());}class MenuItemClickListener implements OnItemClickListener{@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {Fragment newFragment = null; MainActivity.NOW_FRAGMENT_NO = position;activity.supportInvalidateOptionsMenu();switch (position) {case 0:newFragment = new FirstFragment();break;case 1:newFragment = new SecondFragment();break;}if (newFragment != null) {//交給Activity來切換正文fragment activity.switchContent(newFragment);}}}}?
講解:
1.listview用一個最簡單的ArrayAdapter來放了兩個數據,并且添加了監聽器來監聽點擊事件。
2.在實際使用中不同的fragment很可能會需要不同的菜單,所以我通過對MainActivity中靜態變量的設置和activity.supportInvalidateOptionsMenu();來使得每次切換Fragment的時候都重新根據靜態變量的值來生成菜單項
3.這里面因為要用到MainActivity中切換Fragment的方法,所以要生成MainActivity對象。需要注意的是在多次切換后這個Fragment中的getActivity()方法很可能會出錯,返回null值。因此這里在綁定activity時實例化一個activity對象是很有必要的!
?
2.簡單的Fragment
SecondFragment是個很簡單的Fragment,就是為了舉例子用的。
package com.kale.slidingmenutest.fragment;import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;public class SecondFragment extends MenuFragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {TextView textView = new TextView(getActivity());textView.setGravity(Gravity.CENTER);textView.setText("第二個Fragment");textView.setTextSize(30);return textView;} }?
3.擁有TAB和ViewPager的FirstFragment
先貼上布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><android.support.v4.view.ViewPagerandroid:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="match_parent"android:visibility="visible" /></LinearLayout>?
這里面稍微有個難點就是,在不同的頁面滑動時要實時改變slidingMenu的觸控范圍,是邊緣還是全屏觸控都需要設置。
3.1初始化viewPager和actionbar,并添加監聽器。
因為actionbar監聽器中需要傳入viewpager做判斷,所以要先初始化viewpager。
ViewPager viewPager;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO 自動生成的方法存根return inflater.inflate(R.layout.first_fragment, null);}@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {// TODO 自動生成的方法存根super.onActivityCreated(savedInstanceState);//設置actionbar initViewPager();initActionBar();}/***/private void initActionBar() {ActionBar actionBar = ((MainActivity)getActivity()).getSupportActionBar();//設定有Tab actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);ActionBar.Tab tab;//開始添加Tab,這里添加4個,并且設置監聽器for (int i = 1; i <= 4; i++) {tab = actionBar.newTab();tab.setText("Tab " + i);tab.setTabListener(new MyTabListener(viewPager));actionBar.addTab(tab);}}private void initViewPager() {ArrayList<View> list = new ArrayList<View>();for (int i = 0; i < 4; i++) {list.add(newTextView("第"+(i+1)+"個界面"));}viewPager = (ViewPager)getActivity().findViewById(R.id.viewPager);viewPager.setAdapter(new MyPagerAdapter(list));viewPager.setOnPageChangeListener(new PageChangeListener((MainActivity)getActivity()));}private TextView newTextView(String text) {TextView tv = new TextView(getActivity());tv.setText(text);tv.setTextSize(30);tv.setGravity(Gravity.CENTER);return tv;} /*** @author:Jack Tony 這里配置適配器* @tips :這里傳入一個list數組,從每個list中可以剝離一個view并顯示出來* @date :2014-9-24*/public class MyPagerAdapter extends PagerAdapter {private ArrayList<View> mViewList;private int pagerNum = 0;public MyPagerAdapter(ArrayList<View> viewList) {mViewList = viewList;}public int getPagerNum() {return pagerNum;}@Overridepublic int getCount() {return mViewList.size();}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic void destroyItem(View arg0, int arg1, Object arg2) {if (mViewList.get(arg1) != null) {((ViewPager) arg0).removeView(mViewList.get(arg1));}}@Overridepublic Object instantiateItem(View arg0, int arg1) {try {if (mViewList.get(arg1).getParent() == null) {((ViewPager) arg0).addView(mViewList.get(arg1), 0);} else {/** 很難理解新添加進來的view會自動綁定一個父類,由于一個兒子view不能與兩個父類相關,* 所以得解綁不這樣做否則會產生 viewpager java.lang.IllegalStateException:* The specified child already has a parent. You must call* removeView() on the child's parent first.*/((ViewGroup) mViewList.get(arg1).getParent()).removeView(mViewList.get(arg1));((ViewPager) arg0).addView(mViewList.get(arg1), 0);}} catch (Exception e) {e.printStackTrace();} finally {pagerNum = arg1;}return mViewList.get(arg1);}}?
全部代碼:
package com.kale.slidingmenutest.fragment;import java.util.ArrayList;import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;import com.kale.slidingmenutest.MainActivity; import com.kale.slidingmenutest.R; import com.kale.slidingmenutest.listener.MyTabListener; import com.kale.slidingmenutest.listener.PageChangeListener;public class FirstFragment extends Fragment {ViewPager viewPager;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO 自動生成的方法存根return inflater.inflate(R.layout.first_fragment, null);}@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {// TODO 自動生成的方法存根super.onActivityCreated(savedInstanceState);//設置actionbar initViewPager();initActionBar();}/***/private void initActionBar() {ActionBar actionBar = ((MainActivity)getActivity()).getSupportActionBar();//設定有Tab actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);ActionBar.Tab tab;//開始添加Tab,這里添加4個,并且設置監聽器for (int i = 1; i <= 4; i++) {tab = actionBar.newTab();tab.setText("Tab " + i);tab.setTabListener(new MyTabListener(viewPager));actionBar.addTab(tab);}}private void initViewPager() {ArrayList<View> list = new ArrayList<View>();for (int i = 0; i < 4; i++) {list.add(newTextView("第"+(i+1)+"個界面"));}viewPager = (ViewPager)getActivity().findViewById(R.id.viewPager);viewPager.setAdapter(new MyPagerAdapter(list));viewPager.setOnPageChangeListener(new PageChangeListener((MainActivity)getActivity()));}private TextView newTextView(String text) {TextView tv = new TextView(getActivity());tv.setText(text);tv.setTextSize(30);tv.setGravity(Gravity.CENTER);return tv;}/*** @author:Jack Tony 這里配置適配器* @tips :這里傳入一個list數組,從每個list中可以剝離一個view并顯示出來* @date :2014-9-24*/public class MyPagerAdapter extends PagerAdapter {private ArrayList<View> mViewList;private int pagerNum = 0;public MyPagerAdapter(ArrayList<View> viewList) {mViewList = viewList;}public int getPagerNum() {return pagerNum;}@Overridepublic int getCount() {return mViewList.size();}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic void destroyItem(View arg0, int arg1, Object arg2) {if (mViewList.get(arg1) != null) {((ViewPager) arg0).removeView(mViewList.get(arg1));}}@Overridepublic Object instantiateItem(View arg0, int arg1) {try {if (mViewList.get(arg1).getParent() == null) {((ViewPager) arg0).addView(mViewList.get(arg1), 0);} else {/** 很難理解新添加進來的view會自動綁定一個父類,由于一個兒子view不能與兩個父類相關,* 所以得解綁不這樣做否則會產生 viewpager java.lang.IllegalStateException:* The specified child already has a parent. You must call* removeView() on the child's parent first.*/((ViewGroup) mViewList.get(arg1).getParent()).removeView(mViewList.get(arg1));((ViewPager) arg0).addView(mViewList.get(arg1), 0);}} catch (Exception e) {e.printStackTrace();} finally {pagerNum = arg1;}return mViewList.get(arg1);}}}?
3.2設置ViewPager的滑動監聽,滑動時要求tab也需要跟著變換,并且滑動到最左邊的界面時將觸控范圍變為全屏有效。
PageChangeListener
package com.kale.slidingmenutest.listener;import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity;import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; import com.kale.slidingmenutest.MainActivity;public class PageChangeListener implements ViewPager.OnPageChangeListener {private ActionBarActivity activity;public PageChangeListener(ActionBarActivity activity) {this.activity = activity;}@Overridepublic void onPageScrollStateChanged(int arg0) {// TODO 自動生成的方法存根 }@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO 自動生成的方法存根 }@Overridepublic void onPageSelected(int position) {//System.out.println("position:" + position); activity.getSupportActionBar().setSelectedNavigationItem(position);//設置在其他頁面滑動時slingmenu是邊緣模式,最邊上頁面是全屏模式(防誤觸)switch (position) {case 0: ((MainActivity)activity).getMySlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);break;default: ((MainActivity)activity).getMySlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);break;}} }?
3.3MyTabListener
注意:要判斷viewpager是否為空
package com.kale.slidingmenutest.listener;import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar.Tab;/*** @author:Jack Tony* @tips :設置tab的監聽器,控制viewpager的顯示* @date :2014-7-30*/ public class MyTabListener implements ActionBar.TabListener {ViewPager viewPager;public MyTabListener(ViewPager viewPager) {this.viewPager = viewPager;}@Overridepublic void onTabReselected(Tab arg0, FragmentTransaction arg1) {}/* 核心方法* @see android.support.v7.app.ActionBar.TabListener#onTabSelected(android.support.v7.app.ActionBar.Tab, android.support.v4.app.FragmentTransaction)* 選中某個tab時,同時切換viewpager*/@Overridepublic void onTabSelected(Tab tab, FragmentTransaction arg1) {if (viewPager != null && viewPager.getCurrentItem() != tab.getPosition()) {viewPager.setCurrentItem(tab.getPosition());}}@Overridepublic void onTabUnselected(Tab arg0, FragmentTransaction arg1) {}}?
源碼下載:http://download.csdn.net/detail/shark0017/7976759
?
總結
以上是生活随笔為你收集整理的无需SherlockActionbar的SlidingMenu使用详解(二)——向Fragment中添加ViewPager和Tab的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel2003怎样拆分单元格
- 下一篇: android传感器实现摇一摇功能