先看总体的导图
看ui图
************************************************先看整体布局开始********************************************************************
先实现下面的结构图
先看整体布局activity_main.xml--先放空白的framelayout然后进行替换
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fl_content"
android:background="#fff"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
在看侧栏的布局left_menu.xml--先放空白的framelayout然后进行替换
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fl_left_menu"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
MainActivity 入口代码
package com.itheima.zhbj52;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Window;
import com.itheima.zhbj52.fragment.ContentFragment;
import com.itheima.zhbj52.fragment.LeftMenuFragment;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity;
/**
* 主页面功能:
* 1、初始化加载主页面布局--该布局是一个framelayout布局, 目的地transaction.replace将主页布局直接进行替换即可!!!!
* 2、提供2个方法,用来获取左侧栏目、主页布局的方法
*/
public class MainActivity extends SlidingFragmentActivity {
private static final String FRAGMENT_LEFT_MENU = "fragment_left_menu";
private static final String FRAGMENT_CONTENT = "fragment_content";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
/**
* 初始化加载主页面布局--该布局是一个framelayout布局
* 目的地transaction.replace将主页布局直接进行替换即可!!!!
*/
setContentView(R.layout.activity_main);
/**
* 初始化设置侧栏--该布局也是一个framelayout布局
* 目的地transaction.replace将侧边布局直接进行替换即可!!!!
*/
setBehindContentView(R.layout.left_menu);
SlidingMenu slidingMenu = getSlidingMenu();// 获取侧边栏对象
slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);// 设置全屏触摸
slidingMenu.setBehindOffset(200);// 设置预留屏幕的宽度
initFragment();
}
/**
* 初始化fragment, 将fragment数据填充给布局文件
*/
private void initFragment() {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();// 开启事务
transaction.replace(R.id.fl_left_menu, new LeftMenuFragment(),
FRAGMENT_LEFT_MENU);// 用fragment替换framelayout
transaction.replace(R.id.fl_content, new ContentFragment(),
FRAGMENT_CONTENT);
transaction.commit();// 提交事务
}
/**
* 获取侧边栏fragment
* @return
*/
public LeftMenuFragment getLeftMenuFragment() {
FragmentManager fm = getSupportFragmentManager();
LeftMenuFragment fragment = (LeftMenuFragment) fm
.findFragmentByTag(FRAGMENT_LEFT_MENU);
return fragment;
}
/**
* 获取主页面fragment
* @return
*/
public ContentFragment getContentFragment() {
FragmentManager fm = getSupportFragmentManager();
ContentFragment fragment = (ContentFragment) fm
.findFragmentByTag(FRAGMENT_CONTENT);
return fragment;
}
}
左右两侧都是fragment,有必要将其抽取一个公共的基类
BaseFragment
package com.itheima.zhbj52.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;
/**
* 主页、侧栏的fragment基类
* 功能:
* 1、onCreate获取依托的activity
* 2、onCreateView返回展现页面的布局文件,并且提供抽象方法,让子类去具体实现
* 3、onActivityCreated进行初始数据用
*/
public abstract class BaseFragment extends Fragment {
public Activity mActivity;
/**
* 在 onCreate可以获取依附的mActivity
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = getActivity();
}
/**
* 处理fragment的布局
* 这里返回fragment的布局文件
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return initViews();
}
// 依附的activity创建完成
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initData();
}
// 子类必须实现初始化布局的方法
public abstract View initViews();
// 初始化数据, 可以不实现
public void initData() {
}
}
***********************************************接下来实现侧栏代码之前先看侧栏布局文件吧--侧栏是一个listview*********************************************************
fragment_left_menu.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000" >
<ListView
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:listSelector="@android:color/transparent"
android:divider="@android:color/transparent"
android:layout_marginTop="40dp" />
</RelativeLayout>
既然是listview,那么下来的布局就是每一个item的布局
list_menu_item.xml
<?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="wrap_content"
android:orientation="vertical"
android:padding="10dp" >
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/btn_menu_selector"
android:drawablePadding="5dp"
android:enabled="false"
android:text="新闻"
android:textColor="@drawable/text_menu_selector"
android:textSize="25sp" />
</LinearLayout>
btn_menu_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:drawable="@drawable/menu_arr_select"/>
<item android:drawable="@drawable/menu_arr_normal"/>
</selector>
text_menu_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:color="#f00"/>
<item android:color="@android:color/white"/>
</selector>
LeftMenuFragment
package com.itheima.zhbj52.fragment;
import java.util.ArrayList;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.itheima.zhbj52.MainActivity;
import com.itheima.zhbj52.R;
import com.itheima.zhbj52.base.impl.NewsCenterPager;
import com.itheima.zhbj52.domain.NewsData;
import com.itheima.zhbj52.domain.NewsData.NewsMenuData;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
/**
* 侧边栏
* 功能:
* 1、initViews中初始化自己的布局
* 2、setMenuData提供一个方法,获取网络数据,这个方法是在NewsCenterPager中进行回传填充的
* 刷新测边栏的数据
MainActivity mainUi = (MainActivity) mActivity;
LeftMenuFragment leftMenuFragment = mainUi.getLeftMenuFragment();
leftMenuFragment.setMenuData(mNewsData);
3、initData这里只是触发点击时间,去更新主页面的内容而已
*/
public class LeftMenuFragment extends BaseFragment {
//数据源--每个选项是一个NewsMenuData对象(通过json获取封装对象)
private ArrayList<NewsMenuData> mMenuList;
/**
* 获取控件--布局是一个listView展现--新闻、专题、组图、互动4个菜单选项
*/
@ViewInject(R.id.lv_list)
private ListView lvList;
private MenuAdapter mAdapter;//适配器
private int mCurrentPos;// 当前被点击的菜单项
/**
* 初始化侧栏的布局
*/
@Override
public View initViews() {
//布局里面是一个listView展现4个菜单选项
View view = View.inflate(mActivity, R.layout.fragment_left_menu, null);
ViewUtils.inject(this, view);
return view;
}
/**
* 初始化左边侧栏的数据--4个菜单选项
*/
@Override
public void initData() {
lvList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//点击任何一个菜单选项,赋值成为当前的postion
mCurrentPos = position;
//通知界面刷新
mAdapter.notifyDataSetChanged();
// 设置当前菜单详情页?????
setCurrentMenuDetailPager(position);
// 当点击任何一项,要求关闭侧栏
toggleSlidingMenu();
}
});
}
/***********************
* 切换SlidingMenu的状态
* 通过侧栏fragment可以获取依托的activity,在那里可以获取getSlidingMenu,进行左侧栏的操作
*/
protected void toggleSlidingMenu() {
MainActivity mainUi = (MainActivity) mActivity;
SlidingMenu slidingMenu = mainUi.getSlidingMenu();
slidingMenu.toggle();// 切换状态, 显示时隐藏, 隐藏时显示
}
/**
* 设置当前菜单详情页
*/
protected void setCurrentMenuDetailPager(int position) {
MainActivity mainUi = (MainActivity) mActivity;
ContentFragment fragment = mainUi.getContentFragment();// 获取主页面fragment
NewsCenterPager pager = fragment.getNewsCenterPager();// 获取新闻中心页面
pager.setCurrentMenuDetailPager(position);// 设置当前菜单详情页
}
/**************************************
* 设置网络数据
* 这个方法是在NewsCenterPager中进行回传填充的
* @param data
*/
public void setMenuData(NewsData data) {
mMenuList = data.data;
mAdapter = new MenuAdapter();
lvList.setAdapter(mAdapter);
}
/**
* 侧边栏数据适配器
*/
class MenuAdapter extends BaseAdapter {
@Override
public int getCount() {
return mMenuList.size();
}
@Override
public NewsMenuData getItem(int position) {
return mMenuList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(mActivity, R.layout.list_menu_item, null);
TextView tvTitle = (TextView) view.findViewById(R.id.tv_title);
NewsMenuData newsMenuData = getItem(position);
tvTitle.setText(newsMenuData.title);
/**
* 在初始化的时候,在没有点击选择菜单条目的时候,mCurrentPos为0
* 当view绘制到postion==0时候,就将新闻菜单选项,字体变为红色,其他变为白色
* 在进行点击操作时候mAdapter.notifyDataSetChanged();会通知界面刷新重新绘制界面
* 这样就会将点击的菜单选项绘制成红色
*/
if (mCurrentPos == position) {// 判断当前绘制的view是否被选中
// 显示红色
tvTitle.setEnabled(true);
} else {
// 显示白色
tvTitle.setEnabled(false);
}
return view;
}
}
}
*******************************************接下来实现ContentFragment代码之前先看布局文件吧,是一个自定义viewPager+Tab栏********************************************
fragment_content.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.itheima.zhbj52.view.NoScrollViewPager
android:id="@+id/vp_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<RadioGroup
android:id="@+id/rg_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bottom_tab_bg"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/rb_home"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_home_selector"
android:text="首页" />
<RadioButton
android:id="@+id/rb_news"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_news_selector"
android:text="新闻中心" />
<RadioButton
android:id="@+id/rb_smart"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_smart_selector"
android:text="智慧服务" />
<RadioButton
android:id="@+id/rb_gov"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_gov_selector"
android:text="政务" />
<RadioButton
android:id="@+id/rb_setting"
style="@style/BottomTabStyle"
android:drawableTop="@drawable/btn_tab_setting_selector"
android:text="设置" />
</RadioGroup>
</LinearLayout>
<!-- 低栏RadioButton的样式 -->
<style name="BottomTabStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center_vertical</item>
<item name="android:button">@null</item>
<item name="android:drawablePadding">3dp</item>
<item name="android:padding">5dp</item>
<item name="android:textColor">@drawable/btn_tab_text_selector</item>
<item name="android:layout_weight">1</item>
<item name="android:gravity">center</item>
</style>
btn_tab_text_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#f00" android:state_checked="true"/>
<item android:color="#fff"/>
</selector>
btn_tab_news_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/newscenter_press" android:state_checked="true"/>
<item android:drawable="@drawable/newscenter"/>
</selector>
NoScrollViewPager--自定义viewPager
package com.itheima.zhbj52.view;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* 不能左右划的ViewPager
* 对事件不拦截、不处理
*
*
*/
public class NoScrollViewPager extends ViewPager {
public NoScrollViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoScrollViewPager(Context context) {
super(context);
}
/**
* 表示事件是否拦截, 返回false表示不拦截--不处理
* 这个是针对,在新闻中心,滑动11个页面进行的不拦截操作,
* 默认是拦截的,只有返回false,对子事件不拦截,才对11个页面的滑动切换的事件才可以相应
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return false;
}
/**
* 重写onTouchEvent事件,什么都不用做
* 滑动屏幕-不会切换
*/
@Override
public boolean onTouchEvent(MotionEvent arg0) {
return false;
}
}
ContentFragment
package com.itheima.zhbj52.fragment;
import java.util.ArrayList;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import com.itheima.zhbj52.R;
import com.itheima.zhbj52.base.BasePager;
import com.itheima.zhbj52.base.impl.GovAffairsPager;
import com.itheima.zhbj52.base.impl.HomePager;
import com.itheima.zhbj52.base.impl.NewsCenterPager;
import com.itheima.zhbj52.base.impl.SettingPager;
import com.itheima.zhbj52.base.impl.SmartServicePager;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
/**
* 主页内容
* 1、initViews中初始化布局,初始化NoScrollViewPager、底部Tab栏视图
*
* 2、为NoScrollViewPager添加5个界面
* 3、初始化首页数据mPagerList.get(0).initData();// 初始化首页数据
* 4、setOnPageChangeListener在方法里,初始化对应页面的数据
*/
public class ContentFragment extends BaseFragment {
// 底部Tab栏目
@ViewInject(R.id.rg_group)
private RadioGroup rgGroup;
/**
* 主页的顶部的不能滑动的ViewPager视图控件
* onInterceptTouchEvent、onTouchEvent都返回false
*/
@ViewInject(R.id.vp_content)
private ViewPager mViewPager;
//数据源头--就是Tab栏目对应的5个界面
private ArrayList<BasePager> mPagerList;
@Override
public View initViews() {
View view = View.inflate(mActivity, R.layout.fragment_content, null);
ViewUtils.inject(this, view); // 注入view和事件
return view;
}
/**
* 初始化数据
*/
@Override
public void initData() {
// 默认勾选首页
rgGroup.check(R.id.rb_home);
// 初始化5个子页面
mPagerList = new ArrayList<BasePager>();
mPagerList.add(new HomePager(mActivity));
mPagerList.add(new NewsCenterPager(mActivity));
mPagerList.add(new SmartServicePager(mActivity));
mPagerList.add(new GovAffairsPager(mActivity));
mPagerList.add(new SettingPager(mActivity));
mViewPager.setAdapter(new ContentAdapter());
// 监听RadioGroup的选择事件
rgGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.rb_home:
// mViewPager.setCurrentItem(0);// 设置当前页面
mViewPager.setCurrentItem(0, false);// 去掉切换页面的动画
break;
case R.id.rb_news:
mViewPager.setCurrentItem(1, false);// 设置当前页面
break;
case R.id.rb_smart:
mViewPager.setCurrentItem(2, false);// 设置当前页面
break;
case R.id.rb_gov:
mViewPager.setCurrentItem(3, false);// 设置当前页面
break;
case R.id.rb_setting:
mViewPager.setCurrentItem(4, false);// 设置当前页面
break;
default:
break;
}
}
});
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
mPagerList.get(arg0).initData();// 获取当前被选中的页面, 初始化该页面数据
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
mPagerList.get(0).initData();// 初始化首页数据
}
/**
* 主界面的适配器
* @author Administrator
*
*/
class ContentAdapter extends PagerAdapter {
@Override
public int getCount() {
return mPagerList.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
BasePager pager = mPagerList.get(position);
container.addView(pager.mRootView);
// pager.initData();// 初始化数据.... 不要放在此处初始化数据, 否则会预加载下一个页面
return pager.mRootView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
/**
* 获取新闻中心页面
*
* @return
*/
public NewsCenterPager getNewsCenterPager() {
return (NewsCenterPager) mPagerList.get(1);
}
}