无需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"> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="120dp" > <ImageView
android:id="@+id/backgroundPicture_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/background" /> <ImageView
android: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" /> <TextView
android: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> <LinearLayout
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:gravity="center"
android:orientation="horizontal" > <ImageView
android:id="@+id/personalSetting_id"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_marginRight="10dp"
android:src="@drawable/personalsettingbutton"
android:scaleType="fitCenter" /> <ImageView
android: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"> <ListView
android: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; @Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.activity = (MainActivity)activity;
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
View v = inflater.inflate(R.layout.app_menu, null);
return v;
} @Override
public 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{ @Override
public 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 { @Override
public 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.ViewPager
android: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; @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO 自动生成的方法存根
return inflater.inflate(R.layout.first_fragment, null);
} @Override
public 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;
} @Override
public int getCount() {
return mViewList.size();
} @Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
} @Override
public void destroyItem(View arg0, int arg1, Object arg2) {
if (mViewList.get(arg1) != null) {
((ViewPager) arg0).removeView(mViewList.get(arg1));
}
} @Override
public 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; @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO 自动生成的方法存根
return inflater.inflate(R.layout.first_fragment, null);
} @Override
public 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;
} @Override
public int getCount() {
return mViewList.size();
} @Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
} @Override
public void destroyItem(View arg0, int arg1, Object arg2) {
if (mViewList.get(arg1) != null) {
((ViewPager) arg0).removeView(mViewList.get(arg1));
}
} @Override
public 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;
} @Override
public void onPageScrollStateChanged(int arg0) {
// TODO 自动生成的方法存根 } @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO 自动生成的方法存根 } @Override
public 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;
} @Override
public 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
*/
@Override
public void onTabSelected(Tab tab, FragmentTransaction arg1) {
if (viewPager != null && viewPager.getCurrentItem() != tab.getPosition()) {
viewPager.setCurrentItem(tab.getPosition());
}
} @Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) { } }
源码下载:http://download.csdn.net/detail/shark0017/7976759
无需SherlockActionbar的SlidingMenu使用详解(二)——向Fragment中添加ViewPager和Tab的更多相关文章
- 无需SherlockActionbar的SlidingMenu使用详解(一)——通过SlidingMenu设置容器并解决滑动卡顿的问题
想必很多人都听过这个开源框架,一年前真的是风靡一时.只是它的配置较为繁琐,还需要sherlockActionbar的支持,我这里下载了最新的开源库,并且在实际用套用了AppCompat的官方库,这样就 ...
- P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...
- 剑指Offer-编程详解-二维数组中的查找
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...
- Java面试题详解二:java中的关键字
一,final1.被final修饰的类不可以被继承2.被final修饰的方法不可以被重写3.被final修饰的变量不可以被改变 重点就是第三句.被final修饰的变量不可以被改变,什么不可以被改变呢 ...
- (转)android Fragments详解二:创建Fragment
创建Fragment 要创建fragment,必须从Fragment或Fragment的派生类派生出一个类.Fragment的代码写起来有些像activity.它具有跟activity一样的回调方法, ...
- Android Fragment详解(二):Fragment创建及其生命周期
Fragments的生命周期 每一个fragments 都有自己的一套生命周期回调方法和处理自己的用户输入事件. 对应生命周期可参考下图: 创建片元(Creating a Fragment) To c ...
- .NET DLL 保护措施详解(二)关于性能的测试
先说结果: 加了缓存的结果与C#原生代码差异不大了 我对三种方式进行了测试: 第一种,每次调用均动态编译 第二种,缓存编译好的对象 第三种,直接调用原生C#代码 .net dll保护系列 ------ ...
- Android Widget 开发详解(二) +支持listView滑动的widget
转载请标明出处:http://blog.csdn.net/sk719887916/article/details/47027263 不少开发项目中都会有widget功能,别小瞧了它,他也是androi ...
- PopUpWindow使用详解(二)——进阶及答疑
相关文章:1.<PopUpWindow使用详解(一)——基本使用>2.<PopUpWindow使用详解(二)——进阶及答疑> 上篇为大家基本讲述了有关PopupWindow ...
随机推荐
- Selenium Books
Recently, some of my projects rely heavily upon tests with selenium. Some books about selenium are c ...
- 【LOJ】#2109. 「JLOI2015」骗我呢
题解 我深思熟虑许久才算是明白个大概的计数问题吧 先是转化成一个矩形,列一条直线y = x,y = x - (m + 1)我们从(0,0)走到(n + m + 1,m + 1)就是答案 因为我们起始相 ...
- 牛客练习赛16 E - 求值
题目大意: 链接:https://www.nowcoder.com/acm/contest/84/E 给定n个数字a1, a2, ..., an. 定义f(l, r) = al | al+1| ... ...
- 使用libvirt管理KVM(一)
一. 安装和配置libvirt,源码下载http://www.qemu-project.org/download/#source. 二. 从包和源码包进行安装libvirt. 1. 在ubuntu系统 ...
- 001 SpringMVC的helloWorld程序
一:helloworld程序 1.结构目录 2.添加lib包 3.在web.xml中配置DispatchServlet 这个就是主servlet. <?xml version="1.0 ...
- P3512 [POI2010]PIL-Pilots
P3512 [POI2010]PIL-Pilots我一开始打的O(n^2)(最坏情况)的算法.枚举区间长度.60分 #include<iostream> #include<cstdi ...
- pip 安装包提速
豆瓣源 pip3 install 第三方库名 -i https://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com
- Xamarin iOS教程之显示和编辑文本
Xamarin iOS教程之显示和编辑文本 Xamarin iOS显示和编辑文本 在一个应用程序中,文字是非常重要的.它就是这些不会说话的设备的嘴巴.通过这些文字,可以很清楚的指定这些应用程序要表达的 ...
- Bzoj3122:多项式BSGS
根据鸽笼原理,在p次后一定循环,一眼BSGS.发现他给的函数是个一次函数,一次函数有什么性质呢?f(f(x))还是一次函数,这样就能做了.首先我们暴力预处理出f(f(f(x)))......sqrt( ...
- WorldFinal11 (2/11)
WorldFinal 11 Trash Removal 题意 给你一个多边形,问这个多边形至少需要多宽的长度,才能把这个多边形放进去. 数据范围100 题解 数据范围只有100,暴力枚举两点,然后算最 ...