黑马北京新闻项目连载(2)--->侧滑菜单栏、主页面Fragment搭建

项目Json数据下载地址。。。

北京新闻框架代码

侧滑开源库下载。。。

xutil库下载,,,


先看总体的导图


看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);
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值