【0081】【项目实战】-【智慧北京】-【03】【新闻菜单详情页】-【页签滑动事件处理.】-【ViewPagerIndicator开源框架的使用】-【指示器事件处理】-【去掉listview分割线】-【页签点击按钮跳转下一页】-【页签详情页结构分析】-【头条新闻】
1.新闻菜单详情页-初始化页签页面
1.1【效果及分析】


1.2 Viewpager框架
【布局】

【说明】ViewPager的内容的填充


1.3【页签基类的生成】
【说明】页面都一致:使用一个对象完成所有页面;不用使用父类和子类;



1.4 页签的初始化

【初始化的时刻】:在新闻详情页面

【初始化的数量】初始化的数量是服务器中的数量,根据服务器的数据数量来决定的;


【标签页的网络数据的传入】在数据构造初始化的时候顺便将网络的初始化数据传递进来;



【数据的初始化显示】



1.5 Data数据的传入
【说明】child标签下的数据的传入



【说明】文本设置的位置发生了变化,注意出现空指针异常(父类会调用未初始化的子类的方法);

【效果及bug】边界滑动不了,因为Viewpager嵌套了ViewPager;问题比较复杂。参考下节内容;


2.页签滑动事件处理.
【事件的拦截机制】外部控件首先会拦截事件,然后再依次传递给子控件;
【修改外部的Viewpager的拦截机制】


【效果】可以直接滑动了,不会再拦截了;

3.ViewPagerIndicator开源框架的使用
3.1【效果】使用开源框架

3.2【开源框架的认识】此开源框架的效果有很多种,可以选择


3.3【源码的搜索认识】





3.4 开源框架的使用
【说明】步骤

【关联库】

【报错】添加之后发现了两个版本的库;

【解决方法】将两个版本保留一个版本即可;此处保留了SlideMenu的v4库,将SlideMenu的v4库给ViewPagerIndicator复制一份;

【bug2】例子和库中的jar包发生冲突;

【删除例子程序中的v4-jar包】

3.5 开源框架的使用-【布局文件的修改及绑定】


【指示器的绑定】指示器和ViewPager的绑定;


【标题的填充】

【参考源码】

【移植使用】

【效果】可以滑动和点击,但是样式发生了原来的变化;

3.6 样式的修正
【源码】源码给样式设置了一个主题;

【增加主题】


【修改背景为白色】


【待修正的问题】指示条的颜色修改为红色,文字具有红黑切换;

[样式源码中修改]



[效果]



[效果]

4.指示器事件处理
4.1 出现的问题1
【说明】在滑动标签的时候如果滚动过快会出现将侧边栏拉出来的情况;
【原因】侧边栏属于是MainActivity,标签的事件被拦截了;

【解决的办法】标签通知侧边栏不要拦截事件;

[效果] 即使到了最左边的栏也不会出现侧边栏出现的情况;

4.2 出现的问题2
【问题说明】在中间滑动的时候,仍然会出现侧边栏跳出的情形;
但是:在北京的页面是需要侧边栏弹出的,在其他的页面不需要;

【解决办法】照着之前的思路:不采用完全通知父类禁用事件拦截机制(因为北京页面需要自动弹出),而是使用侧边栏的开关进行控制判断;
【ViewPager进行监听】--不可取



[效果]此刻在滑动的时候Indicator与Viewpager不同步了;因为Indicator的权限高于Viewpager;

【修改】

[效果]

【侧边栏的禁用监听】

[效果]只有滑动到北京才可以滑动出来侧边栏;

5.去掉listview分割线



6.页签点击按钮跳转下一页
【效果】

【布局】



【设置按钮的点击事件】XUtils开源框架,除了可以绑定View,也可以绑定事件;


7.页签详情页结构分析
7.1 详情页的结构
【说明】是分层的结构,逐渐递进;
存在三层ViewPager嵌套,比较复杂;


7.2 布局文件的完成




7.3 新闻详情数据分析及解析
【说明】在解析的categories.json的child节点下。包含有url地址;




【已经解析到单个标签的数据】


【小技巧】快速查看当前类中的方法

【解析数据】

【javaBean对象的封装】


【javaBean源码】
1 package com.itheima.zhbj74.domain; 2 3 import java.util.ArrayList; 4 5 /** 6 * 页签详情数据对象 7 * 8 * @author Kevin 9 * @date 2015-10-20 10 */ 11 public class NewsTabBean { 12 13 public NewsTab data; 14 15 public class NewsTab { 16 public String more; 17 public ArrayList<NewsData> news; 18 public ArrayList<TopNews> topnews; 19 } 20 21 // 新闻列表对象 22 public class NewsData { 23 public int id; 24 public String listimage; 25 public String pubdate; 26 public String title; 27 public String type; 28 public String url; 29 } 30 31 // 头条新闻 32 public class TopNews { 33 public int id; 34 public String topimage; 35 public String pubdate; 36 public String title; 37 public String type; 38 public String url; 39 } 40 }

8.头条新闻加载
8.1 默认图片的加载
【数据存在与javaBean的集合中】




[效果]默认图片加载出来了

8.2 网络图片的加载
【网络图片】存在于一个地址中;


【说明】使用工具类:下载图片,加载图片,考虑内存溢出,缓存;


[效果-网络图片加载]存在的问题:图片没有完全加载到ViewPager中,图片的上下存在间隙;

【解决方法】


【增加缓存机制】json文件的缓存,只缓存了图片的链接,并非是图片的缓存(在BitmapUtils类中进行图片缓存);


【测试】将服务器关掉,重新打开app,图片仍然存在;

9. 头条新闻图片的滑动
9.1【问题】滑动图片,indicator也随着滑动;图片的Viewpager被父控件的Viewpager拦截






[效果]完成了图片的滑动,可以滑动四张图片,服务器本身也具有四张图片;滑动到最后一张图片的位置则无法再滑动;

9.2 滑动到最后一张图片时标签的切换
【效果】
【向下滑动】滑动结束到当前标签的所有图片的结束会自动下滑到下一个标签;

【向上滑动】返回的效果也是一致的,滑动到最后到北京标签的时候会滑出侧边栏;


【源码】/zhbj74/src/com/itheima/zhbj74/view/TopNewsViewPager.java
1 package com.itheima.zhbj74.view; 2 3 import android.content.Context; 4 import android.support.v4.view.ViewPager; 5 import android.util.AttributeSet; 6 import android.view.MotionEvent; 7 8 /** 9 * 头条新闻自定义viewpager 10 * 11 * @author Kevin 12 * @date 2015-10-20 13 */ 14 public class TopNewsViewPager extends ViewPager { 15 16 private int startX; 17 private int startY; 18 19 public TopNewsViewPager(Context context, AttributeSet attrs) { 20 super(context, attrs); 21 } 22 23 public TopNewsViewPager(Context context) { 24 super(context); 25 } 26 27 /** 28 * 1. 上下滑动需要拦截 2. 向右滑动并且当前是第一个页面,需要拦截 3. 向左滑动并且当前是最后一个页面,需要拦截 29 */ 30 @Override 31 public boolean dispatchTouchEvent(MotionEvent ev) { 32 getParent().requestDisallowInterceptTouchEvent(true); //刚开始需要保留 33 34 switch (ev.getAction()) { 35 case MotionEvent.ACTION_DOWN: 36 startX = (int) ev.getX(); 37 startY = (int) ev.getY(); 38 break; 39 case MotionEvent.ACTION_MOVE: 40 41 int endX = (int) ev.getX(); 42 int endY = (int) ev.getY(); 43 44 int dx = endX - startX; 45 int dy = endY - startY; 46 47 if (Math.abs(dy) < Math.abs(dx)) { 48 int currentItem = getCurrentItem(); 49 // 左右滑动 50 if (dx > 0) { 51 // 向右划 52 if (currentItem == 0) { 53 // 第一个页面,需要拦截 54 getParent().requestDisallowInterceptTouchEvent(false); 55 } 56 } else { 57 // 向左划 58 int count = getAdapter().getCount();// item总数 59 if (currentItem == count - 1) { 60 // 最后一个页面,需要拦截 61 getParent().requestDisallowInterceptTouchEvent(false); 62 } 63 } 64 65 } else { 66 // 上下滑动,需要拦截 67 getParent().requestDisallowInterceptTouchEvent(false); 68 } 69 70 break; 71 72 default: 73 break; 74 } 75 76 return super.dispatchTouchEvent(ev); 77 } 78 79 }
【效果】


10.用户体验优化
【说明】在开始图片无法加载的时候,首先需要出现一张默认的图片,改善用户的体验;否则,用户看到无内容,体验会变差;


【效果】会加载默认的“智慧北京”的图片;

11. 头条新闻标题
【效果】增加左下角的文字,使用相对布局,因为还存在指示器;外部的大布局使用帧布局;







12. 头条新闻页面指示器(开源框架)
12.1 使用开源框架指示器
【指示器效果】

【开源框架的效果】有两种效果,可以使用Circles/Snap例子;

【参考源码】


【书写代码】



【效果】

12.2 修改样式
【样式的修改-源码参考】



【修改】

【效果】在指示器的左右两边存在点击的效果,可以点击左(右)向左(右)边滑动;

12.3 BUG
【说明】在北京的页面滑动到第三个页面(天空翱翔),切换到别的标签(中文、国际),在返回到北京的页面,虽然指示器是在第三个,但是图片的内容却是第一张;

【问题的原因及解决】原因是indicator自身存在的bug,他保存了位置,但是页面切换之后进行了初始化,需要重新拉回到第一个指示器的位置;


13.新闻列表加载&CenterCrop属性裁剪

13.1【布局的添加】增加listView模块;





13.2【新闻内容的小布局】

[裁剪属性]从图片的正中心进行裁剪的;


[增加图片的外边框]


[文字的显示]


[事件标签的添加]


[item四周围白边的添加]



[布局源码]
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:padding="10dp" 6 > 7 8 <ImageView 9 android:id="@+id/iv_icon" 10 android:layout_width="100dp" 11 android:layout_height="70dp" 12 android:background="#a000" 13 android:padding="1dp" 14 android:scaleType="fitXY" 15 android:layout_marginRight="5dp" 16 android:src="@drawable/image_demo" /> 17 18 <TextView 19 android:id="@+id/tv_title" 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content" 22 android:layout_alignParentTop="true" 23 android:layout_toRightOf="@+id/iv_icon" 24 android:ellipsize="end" 25 android:maxLines="2" 26 android:text="锋娟昆仑山大军阀昆仑山大军阀绿卡傻蛋家风口浪尖阿斯顿飞快乐四大可否接口乐山大佛就快啦束带结发" 27 android:textColor="#000" 28 android:textSize="18sp" /> 29 30 <TextView 31 android:id="@+id/tv_date" 32 android:layout_width="wrap_content" 33 android:layout_height="wrap_content" 34 android:layout_below="@id/tv_title" 35 android:layout_toRightOf="@+id/iv_icon" 36 android:text="2015-10-20 16:46" 37 android:textColor="#8000" 38 android:layout_marginTop="5dp" 39 android:textSize="16sp" /> 40 41 </RelativeLayout>
13.3 新闻内容的添加



[效果及BUG]【1】bug1:滑动的时候出现了黑色;【2】滑动的区域只有一小部分,应该将上面的头条新闻向上推,显示下面的listView的内容;

13.4 bug1:滑动的时候出现了黑色
【原因】在listView缓存数据的时候为了提高性能会显示黑色;
【解决方法】增加属性即可,可以在每个listView中增加此属性;

【效果】没有黑色了;

13.5 滑动的区域只有一小部分,应该将上面的头条新闻向上推,显示下面的listView的内容
【解决方法】将上面的ViewPager作为ListView的头布局;整块的内容作为listView;


[抽取之后的源码] /zhbj74/res/layout/pager_tab_detail.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <com.itheima.zhbj74.view.PullToRefreshListView 8 android:id="@+id/lv_list" 9 android:layout_width="match_parent" 10 android:layout_height="match_parent" 11 android:cacheColorHint="#fff" /> 12 13 </LinearLayout>


[抽取样式的源码]
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="wrap_content" 6 android:orientation="vertical" > 7 8 <FrameLayout 9 android:layout_width="match_parent" 10 android:layout_height="180dp" > 11 12 <com.itheima.zhbj74.view.TopNewsViewPager 13 android:id="@+id/vp_top_news" 14 android:layout_width="match_parent" 15 android:layout_height="match_parent" /> 16 17 <RelativeLayout 18 android:layout_width="match_parent" 19 android:layout_height="wrap_content" 20 android:layout_gravity="bottom" 21 android:background="#a000" 22 android:padding="5dp" > 23 24 <TextView 25 android:id="@+id/tv_title" 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 android:text="标题" 29 android:textColor="#fff" 30 android:textSize="16sp" /> 31 32 <com.viewpagerindicator.CirclePageIndicator 33 android:id="@+id/indicator" 34 android:layout_width="wrap_content" 35 android:layout_height="wrap_content" 36 android:layout_alignParentRight="true" 37 android:layout_centerVertical="true" 38 android:paddingLeft="5dp" 39 android:paddingRight="5dp" 40 app:fillColor="#f00" 41 app:pageColor="#cccccc" 42 app:radius="3dp" 43 app:strokeWidth="0dp" /> 44 </RelativeLayout> 45 </FrameLayout> 46 47 </LinearLayout>


[效果]头布局变得非常的小;

[解决办法] 在外层包裹一层线性布局,因为内部重新进行了计算,计算的结果不行;包括一层;listView在计算布局的会常出现的一个问题;

【效果】效果完成了;

浙公网安备 33010602011771号