自定义NoScrollViewPager
继承ViewPager, 实现onTouchEvent, return true; /** * 拦截ViewPager的触摸事件, 不做任何处理 */ @Override public boolean onTouchEvent(MotionEvent arg0) { return true; }
RadioGroup处理
监听RadioGroup选择事件, 对ViewPager的当前页面进行切换 mRadioGroup.check(R.id.rb_home);// 设置默认选项为首页 mRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_home: mViewPager.setCurrentItem(0);// 让ViewPager切换到第一个页面 setSlidingMenuEnable(false); break; } } });
性能优化
为了节省流量, 只有用户切换到该页面时,才加载当前页面的数据. ViewPager会默认预加载下一页数据. // 监听ViewPager的选中事件 mViewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { mPagerList.get(position).initData();// 当该页面选中时,才开始初始化当前页面的数据 } );
设置”首页”和”设置”页面SlidingMenu不可用
private void setSlidingMenuEnable(boolean enable) { MainActivity mainUI = (MainActivity) mActivity; SlidingMenu slidingMenu = mainUI.getSlidingMenu(); if(enable) { slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); }else { slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE); } }
新闻中心页面UI框架搭建
新闻中心页面布局分析
服务器环境搭建
将服务器相关代码和文件(zhbj)拷贝到”apache-tomcat-7.0.57\webapps\ROOT”目录下
访问链接http://10.0.2.2:8080/zhbj/categories.json, 获取json数据
使用工具格式化json, 方便查看.(HiJson,JsonView,在线网站等)
使用xUtils访问网络数据
HttpUtils utils = new HttpUtils(); // RequestCallBack的泛型表示返回的数据类型, 在此我们只需要json的字符串文本, 所以传递String就可以 utils.send(HttpMethod.GET, GlobalContants.NEWS_URL, new RequestCallBack<String>() { // 请求成功 @Override public void onSuccess(ResponseInfo<String> responseInfo) { String result = responseInfo.result; Log.d(TAG, "result-->" + result); processData(result); } // 请求失败 @Override public void onFailure(HttpException error, String msg) { Log.e(TAG, "请求失败:" + msg); } });
使用gson解析
Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。 Gson gson = new Gson(); NewsBean news = gson.fromJson(result, NewsBean.class);
新闻中心对象的创建
/** * 封装新闻中心的对象 * * 注意: 参数起名一定要和json中的命名一致, 否则gson无法解析 * * @author Kevin * */ public class NewsBean { public ArrayList<NewsMenuBean> data; public ArrayList<String> extend; public int retcode; public class NewsMenuBean { public ArrayList<NewsMenuTab> children; public String id; public String title; public int type; public String url; public String url1; @Override public String toString() { return "NewsMenuBean [children=" + children + ", title=" + title + "]"; } } public class NewsMenuTab { public String id; public String title; public int type; public String url; @Override public String toString() { return "NewsMenuTab [id=" + id + ", title=" + title + "]"; } } @Override public String toString() { return "NewsBean [data=" + data + ", retcode=" + retcode + "]"; } }
侧边栏数据填充
初始化ListView
mListView = new ListView(mActivity); mListView.setBackgroundColor(Color.BLACK);//设置背景色 mListView.setDividerHeight(0);//分割线高度设置为0(去掉分割线) mListView.setSelector(android.R.color.transparent);//将点击效果设置为透明(去掉点击效果) mListView.setPadding(0, 40, 0, 0);//设置边距
ListView的item布局:
left_menu_item.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="新闻" android:textColor="@drawable/txt_left_menu_selector" android:padding="20dp" android:drawablePadding="10dp" android:textSize="23sp" android:enabled="false" android:drawableLeft="@drawable/btn_left_menu_selector" > </TextView>
txt_left_menu_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true" android:color="#ff0000"/> <item android:color="#ffffff" android:state_enabled="false"/> </selector>
btn_left_menu_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/menu_arr_select" android:state_enabled="true"/> <item android:drawable="@drawable/menu_arr_normal"/> </selector>
侧边栏菜单点击事件处理
点击item, 切换颜色
记录选中item的位置, 点击后刷新listview,更新item状态
点击item, 隐藏侧边栏
MainActivity mainUI = (MainActivity) mActivity; SlidingMenu slidingMenu = mainUI.getSlidingMenu(); slidingMenu.toggle();// 如果侧边栏打开,则关闭;如果关闭,则打开
点击标题栏的菜单按钮,显示侧边栏
侧边栏对应的4个详情页面 *
分析UI框架结构, 抽取菜单详情页基类
基类: BaseMenuDetailPager public abstract class BaseMenuDetailPager { public Activity mActivity; public View mRootView; public BaseMenuDetailPager(Activity activity) { this.mActivity = activity; mRootView = initView(); } /** * 初始化界面 * @return */ public abstract View initView(); /** * 初始化数据 */ public void initData() { }; } NewsMenuDetailPager//新闻 TopicMenuDetailPager//专题 PhotosMenuDetailPager//组图 InteractMenuDetailPager//互动
NewsCenterPager中, 维护菜单详情页面的集合
- 点击侧边栏item, 切换不同页面, 标题也要发生相应变化
缓存处理
将json数据保存在SharedPreference中, 每次读取网络数据前,先从SP从获取数据, 然后继续访问网络,加载最新数据 // 先从缓存中读取数据并展示 String cache = CacheUtils.getCache(mActivity, GlobalContants.NEWS_URL); if (!TextUtils.isEmpty(cache)) { processData(cache); } // 请求成功 @Override public void onSuccess(ResponseInfo<String> responseInfo) { String result = responseInfo.result; Log.d(TAG, "网络Json数据: " + result); CacheUtils.setCache(mActivity, GlobalContants.NEWS_URL, result); processData(result); }
新闻详情页开发
定义TabDetailPager
继承BaseMenuDetailPager, 表示每一个页签的对象, 填充ViewPager数据
滑动事件处理
/** * 表示不对事件进行拦截, 从而可以使嵌套在ViewPager内部的ViewPager可以响应滑动动作 * * @param arg0 * @return */ @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { return false; } /** * 拦截ViewPager的触摸事件, 不做任何处理 */ @Override public boolean onTouchEvent(MotionEvent arg0) { return false; }
ViewPagerIndicator
ViewPager指针项目,在使用ViewPager的时候能够指示ViewPager所在的位置,就像Google Play中切换的效果一样,还能使用在应用初始化的介绍页面 下载开源项目, 演示Demo 下载地址: https://github.com/JakeWharton/Android-ViewPagerIndicator
NewsMenuDetailPager
菜单新闻详情页 TabPageIndicator mIndicator; @Override public void initData() { mTabDetailPagers = new ArrayList<TabDetailPager>(); // 初始化页签数据 for (NewsMenuTab tab : mNewsMenuTabs) { TabDetailPager pager = new TabDetailPager(mActivity, tab); mTabDetailPagers.add(pager); } mTabAdapter = new TabDetailPagerAdapter(); mViewPager.setAdapter(mTabAdapter); mIndicator.setViewPager(mViewPager); }
ViewPagerIndicator使用流程
引入library库
布局文件
在布局文件中声明TabPageIndicator控件, 必须和ViewPager搭配使用 <com.viewpagerindicator.TabPageIndicator android:id="@+id/tpi_news_menu" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <android.support.v4.view.ViewPager android:id="@+id/vp_news_menu" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" />
初始化
1. 将指针和ViewPager关联起来, ViewPager页面发生变化时, 指针也会跟随变化 mIndicator.setViewPager(mViewPager); mAdapter = new NewsMenuAdapter(); mViewPager.setAdapter(mAdapter); 2. 在ViewPager的Adapter中,重写该方法: /** * 返回页面标题, 用于在指针中显示 */ @Override public CharSequence getPageTitle(int position) { return mNewsTabDataList.get(position).title; }
样式修改
参照Demo, 给Activity设置主题样式 <activity android:name=".MainActivity" android:theme="@style/Theme.PageIndicatorDefaults" /> 修改样式中的图片, 文字颜色等 <style name="Theme.PageIndicatorDefaults" parent="android:Theme"> <item name="vpiIconPageIndicatorStyle">@style/Widget.IconPageIndicator</item> <item name="vpiTabPageIndicatorStyle">@style/Widget.TabPageIndicator</item> </style> //页签样式修改 <style name="Widget.TabPageIndicator" parent="Widget"> <item name="android:gravity">center</item> <item name="android:background">@drawable/vpi__tab_indicator</item>//修改页签背景 <item name="android:paddingLeft">22dip</item> <item name="android:paddingRight">22dip</item> <item name="android:paddingTop">12dp</item> <item name="android:paddingBottom">12dp</item> <item name="android:textAppearance">@style/TextAppearance.TabPageIndicator</item> <item name="android:textSize">16sp</item> <item name="android:textColor">@drawable/vpi__tab_text_color</item>//修改页签字体颜色 <item name="android:maxLines">1</item> </style> vpi__tab_indicator.xml 将默认图片改为透明: @android:color/transparent 将选中图片改为自定义图片 vpi__tab_textcolor.xml 将vpi__tab_indicator.xml代码拷贝一份,重命名为vpi__tab_textcolor.xml, 其中的drawable改为color, 默认颜色为黑色,选中颜色为红色