接着继续主页的设计,在设计主页时,使用一个Activity管理两个Fragment,这样便于管理侧边栏和主界面。侧边栏和主界面都使用FrameLayout布局,然后将Fragment填充到帧布局中。
侧边栏帧布局:
<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fl_leftmenu"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout></span>
主界面帧布局类似,改下id即可。
接下来将两个Fragment填充到FrameLayout 中,这里使用了FragmentManager以及FragmentTransaction的replace方法。代码如下:
<span style="font-size:18px;">public class MainActivity extends SlidingFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
setBehindContentView(R.layout.layout_leftmenu);
//设置侧边栏一些属性
SlidingMenu left_menu=getSlidingMenu();//获取侧边栏对象
left_menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);//设置触摸方式为全屏触摸
left_menu.setBehindOffset(200);//设置侧边栏的宽度
//使用fragment填充framelayout
FragmentManager fm=getSupportFragmentManager();
FragmentTransaction transaction=fm.beginTransaction();
transaction.replace(R.id.fl_leftmenu, new LeftMenuFragment());
transaction.replace(R.id.fl_main, new ContentFargment());
transaction.commit();
}
}</span>
LeftMenuFragment和ContentFargment是两个继承自Fragment的子类,说道Fragment就不得不说Fragment的生命周期了,以下是Fragment和Activity生命周期方法的比较:
onCreate():当创建 fragment 时系统调用此方法。在其中必须初始化 fragment 的基础组件们。可参考 activity 的说明。
onCreateView():系统在 fragment 要画自己的界面时调用(在真正显示之前)此方法。这个方法必须返回 frament 的 layout 的根控件。如果这个fragment不提供界面,那它应返回 null。
需要注意的是,Fragment依附于Activity,当Activity销毁时,Fragment也将不复存在。LeftMenuFragment有自己的布局,加入布局文件需要在onCreateView()方法中,该方法返回一个布局文件的View对象。
<span style="font-size:18px;">public View initViews() {
View view=View.inflate(mActivity, R.layout.leftmenu_fargment, null);
lv_leftmenu=(ListView) view.findViewById(R.id.lv_leftmenu);
return view;
}</span>
该方法在onCreateView()中调用。
ContentFargment的结构比较复杂,首先是一个上下结构的线性布局,上面是一个ViewPager,下面的tab是一个RadioGroup,如图:
布局文件如下:
<span style="font-size:18px;"><?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" >
<com.lenuy.fasttobuildapp.view.NoScrollViewPager
android:id="@+id/noscroll_vp_content"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1">
</com.lenuy.fasttobuildapp.view.NoScrollViewPager>
<RadioGroup
android:id="@+id/rg_bottom_tab"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:padding="8dp"
android:background="@android:color/white"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_item01"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:checked="true"
android:drawableTop="@drawable/item01"
android:textColor="@drawable/text_color_selector"
android:text="item"/>
<RadioButton
android:id="@+id/rb_item02"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:drawableTop="@drawable/item02"
android:textColor="@drawable/text_color_selector"
android:text="item"/>
<RadioButton
android:id="@+id/rb_item03"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:drawableTop="@drawable/item03"
android:textColor="@drawable/text_color_selector"
android:text="item"/>
<RadioButton
android:id="@+id/rb_item04"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
android:button="@null"
android:gravity="center"
android:drawableTop="@drawable/item04"
android:textColor="@drawable/text_color_selector"
android:text="item"/>
</RadioGroup>
</LinearLayout></span>
NoScrollViewPager是一个继承自ViewPager的自定义控件,这个控件改变了ViewPager的滑动性质,它重写了以下两个方法:
<span style="font-size:18px;">@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return false;//自己不拦截事件
}
@Override
public boolean onTouchEvent(MotionEvent arg0) {
return false;//自己不处理事件
}</span>
然后在NoScrollViewPager中填充不同的界面,这里只实现了第一个界面(仿照新闻APP的首页),其他几个界面没实现。那么介绍下第一个界面的实现。
第一个界面的布局文件:
<span style="font-size:18px;"><?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" >
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:padding="10dp"
android:background="#6699">
<ImageButton
android:id="@+id/ib_switch"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@null"
android:layout_centerVertical="true"
android:src="@drawable/btn_switch"/>
<TextView
android:id="@+id/tv_title"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:textSize="22sp"
android:textColor="#000"
android:text="item"/>
</RelativeLayout>
<FrameLayout
android:id="@+id/fl_content"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1">
</FrameLayout>
</LinearLayout></span>
这里面上下分别是一个相对布局(显示title和一个ImageButton)和FrameLayout,使用FrameLayout是因为要填充的布局比较复杂,希望通过addView方法动态添加进去。
将做好的View(通过inflate获得的)直接fl_content.addView(view)进帧布局。
添加至帧布局fl_content中的布局又是一个比较复杂的结构,它是由一个ViewPager实现的,实现从pager1-->pager4的切换,同时还加了一个Indicator用于指示哪一个页面。布局文件如下:
<span style="font-size:18px;"><?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:background="@android:color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"
android:orientation="horizontal">
<com.viewpagerindicator.TabPageIndicator
android:id="@+id/tb_indicator"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_width="0dp">
</com.viewpagerindicator.TabPageIndicator>
<ImageButton
android:id="@+id/ib_next_item"
android:src="@drawable/btn_next"
android:background="@android:color/transparent"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vp_detail"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
</android.support.v4.view.ViewPager>
</LinearLayout>
</span>
vp_detail里面填充的又是很多页面,这些页面是由一个实现了下拉刷新功能的RefreshView组成的,它继承至ListView,重写了里面的public boolean onTouchEvent(MotionEvent ev)方法,并且为其添加了HeadView和FootView。这个RefreshView的头部又加了一个ViewPager,用于实现多个图片的展示。
到了最后总结下:
1、动态将Fragment加入帧布局的方法。
2、ViewPager控件的使用,特别是在多个ViewPager叠加在一起的时候,需要处理事件传递的过程,一般通过重写以下几个方法:
dispatchTouchEvent(MotionEvent event):事件分发
onInterceptTouchEvent(MotionEvent arg0) :事件拦截
onTouchEvent(MotionEvent arg0) :事件处理
这个APP只是一个框架,可以通过修改布局文件的方式修改它的样式。使用的时候可以连接到网络,获取json数据,然后解析填充到界面上。以下是该APP框架的效果,只是实现了item的第一个页面,仿照的是新闻客户端的界面。
整体框架的基本布局如下:
MainActivity管理左右两套Fragment
点击RadioGroup的图标可以切换ViewPager显示的页面,这是第二页未实现
这是自己实现的第一页(仿照新闻客户端)