本帖最后由 小鲁哥哥 于 2017-5-28 11:06 编辑
【济南中心】Android课程同步笔记智慧北京:Day04(下)
手指弹起后处理头布局的状态当我们手指抬起后,是有两种状态进行切换的: 当前状态为下拉刷新状态: 隐藏头布局 当前状态为释放刷新状态: 把状态切换为正在加载 把头布局回置本身高度 清除动画,隐藏箭头,显示进度条 实现步骤手指抬起时,切换头布局状态 在【RefreshRecyclerView.java】文件中,添加以下片段代码
刷新加载最新的数据
当我们的recycleView正在加载时,是不是应该通知我们的NewsCenterContentTabPager界面,从联网获取最新数据! 那么recycleView需要持有NewsCenterContentTabPager的对象引用才可以通知NewsCenterContentTabPager界面加载数据吧! 为了使recycleView在各个模块都能够实现刷新数据,这里我们可以提供一个刷新的监听接口OnRefreshListener。 让NewsCenterContentTabPager去实现该OnRefreshListener。让recycleView持有该OnRefreshListener的引用。当recycleView处于正在刷新时,通过调用OnRefreshListener监听的回调方法,让NewsCenterContentTabPager界面获取最新数据。 这样做的好处: 降低了recycleView和NewsCenterContentTabPager模块之间的耦合度。 实现原理刷新数据的原理分析当我们的recycleView正在加载时,为了使其他模式能够实现刷新数据的逻辑。 这里我们需要recycleView提供一个刷新的监听接口OnRefreshListener 让recycleView持有该OnRefreshListener的引用,并且提供注册OnRefreshListener接口的方法。 如果需要刷新数据模块,实现了OnRefreshListener,并且注册了OnRefreshListener接口。 那么该模块就拥有了刷新数据的能力。 实现步骤第一步:刷新接口定义 第二步:提供注册刷新接口方法
第三步:RecycleView正在加载状态,调用刷新方法
第四步:NewsCenterContentTabPager注册OnRefreshListener接口
第五步:NewsCenterContentTabPager界面实现OnRefreshListener接口
第六步:实现OnRefreshListener接口的刷新方法
第七步:数据刷新完成,隐藏头布局
处理轮播没有完全展示往下滑出时,轮播图出现回缩
实现思路计算recyclerView在屏幕上的y坐标值 计算轮播图在屏幕上的y坐标值 比较两个y标点: 如果轮播图Y值 < recyclerView 的y值,说明轮播图没有完全显示处理,不处理头布局的高度。 实现步骤l 计算recyclerView在屏幕上的y坐标值 l 计算轮播图在屏幕上的y坐标值 l 比较两个y标点: 如果轮播图Y值 < recyclerView 的y值,说明轮播图没有完全显示处理,不处理头布局的高度。 在【RefreshRecyclerView.java】文件中,添加以下代码片段
快速拖动头的状态不切换bug修复 当头布局为下拉刷新并且top>=0(头布局完全显示出来)更改头布局状为:释放刷新状态 实现步骤在【RefreshRecyclerView.java】文件中,修改判断条件
处理RecyclerView的滑动状态控制脚布局的显示和隐藏监听RecyclerView的滑动状态改变的方法: onScrollStateChanged(int state) SCROLL_STATE_DRAGGING – 拖曳 SCROLL_STATE_SETTLING – 惯性滑动 SCROLL_STATE_IDLE – 停止滑动 在该方法中,来处理显示和隐藏头布局的逻辑 实现步骤处理RecyclerView显示脚
显示脚布局的逻辑在静止的状态下并且必须是最后显示的条目(RecyclerView的最后一个条目),显示脚滑动到显示的脚的位置在【RefreshRecyclerView.java】文件中,添加如下代码片段
处理加载脚数据、隐藏脚 实现步骤第一步:定义加载更多监听接口[Java] 纯文本查看 复制代码 //加载更多的接口
public interface OnLoadMoreListener{
void onLoadMore();
[align=left]} 第二步:提供注册加载更多的接口方法
[Java] 纯文本查看 复制代码 private OnLoadMoreListener mOnLoadMoreListener;
public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener){
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
第三步:加载更多数据脚布局处于加载更多的状态,通过接口调用加载更多数据的方法 [Java] 纯文本查看 复制代码 //滑动状态改变
@Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
switch (state){
case RecyclerView.SCROLL_STATE_DRAGGING://滑动|拖拽
MyLogger.i(TAG,"DRAGGING");
break;
case RecyclerView.SCROLL_STATE_SETTLING://惯性滑动|飞行
MyLogger.i(TAG,"SETTLING");
break;
case RecyclerView.SCROLL_STATE_IDLE://静止
MyLogger.i(TAG,"IDLE");
break;
}
//在静止的状态下 && 必须是最后显示的条目就是RecyclerView的最后一个条目 && 没有在加载更多的数据
boolean isState = state == RecyclerView.SCROLL_STATE_IDLE;
//最后一个条目显示的下标
int lastVisibleItemPosition = lm.findLastVisibleItemPosition();
boolean isLastVisibleItem = lastVisibleItemPosition == getAdapter().getItemCount() - 1;
if(isState && isLastVisibleItem && !hasLoadMoreData && mOnLoadMoreListener != null){
hasLoadMoreData = true;
//显示脚
mFooterView.setPadding(0,0,0,0);
//滑动到显示的脚的位置
smoothScrollToPosition(lastVisibleItemPosition);
//加载数据
mOnLoadMoreListener.onLoadMore();
}
} 注意:在显示脚布局,加载更多时,添加了两个判断条件。 只有在静止的状态下 && 必须是最后显示的条目就是RecyclerView的最后一个条目 && 没有在加载更多的数据 情况,才显示脚布局,并加载更多数据。 第四步:在NewsCenterContentTabPager中注册上拉加载更多的监听 第五步:NewsCenterContentTabPager中实现加载更多数据的方法
第六步:隐藏脚布局当加载更多数据完成以后,隐藏脚布局 [Java] 纯文本查看 复制代码 //隐藏脚
public void hideFooterView(){
hasLoadMoreData = false;
mFooterView.setPadding(0,-mFooterMeasuredHeight,0,0);
//刷新数据
getAdapter().notifyDataSetChanged();
} 点击侧滑菜单切换新闻中心页的内容
完成了新闻中心功能模块,接下来我们来完成点击侧滑菜单中的新闻时, 切换到新闻中心页的内容。 注意:点击新闻,专题,组图,互动,都切换到新闻中心页面,只是更改新闻中心页中的内容。 当我们点击侧滑菜单中的新闻模块,切换到新闻中心页。 此时,需要我们找到MenuAdapter的每个条目的点击事件 第一步:处理条目的点击事件打开【MenuAdapter.java】文件,处理条目的点击实现。点击事件的处理逻辑如下: l 通过MainActivity得到当前被选中的BaseFragemnt l 修改新闻中心页标题 l 判断当前选中的fragment 是NewsCenterFragment新闻中心页面 l 在新闻中心页面切换内容 当我们点击侧滑菜单中的新闻模块,切换到新闻中心页。 此时,需要我们找到MenuAdapter的每个条目的点击事件。
第二步:新闻中心切换内容的方法实现在新闻中心界面【NewsCenterFragment.java】的switchContent()方法中进行切换页面注意:在切换的界面,首先从缓存中找,是否存在,如果存在,直接取出,添加到布局容器中,如果没有,创建布局,先缓存到map,再添加到布局容器中。 [Java] 纯文本查看 复制代码 //切换内容
public void switchContent(int position){
//标题右边的切换menu
if(position == 2){
//显示
ibPicType.setVisibility(View.VISIBLE);
}else{
//隐藏
ibPicType.setVisibility(View.GONE);
}
//先从缓存的容器里面去获取
View view = cacheViews.get(position);
//缓存中没有,创建新的布局,缓存起来
if(view == null){
//创建里面的内容
container.removeAllViews();
} else if(view != null){
//添加布局
addView(view);
}
} 第三步:缓存新闻中心页内容打开新闻中心界面【NewsCenterFragment.java】,创建缓存容器全局变量private Map<Integer,View> cacheViews = new HashMap<>(); 其次,在新闻中心界面的processData方法中,内容完成以后,缓存界面到cacheViews中
初始化组图布局、缓存布局
实现步骤点击侧滑菜单的组图模块,进行切换组图内容。切换的逻辑是在NewsCenterFragment界面的switchContent方法中进行切换的。 实现思路:根据点击的组图模块的position,进行判断:Position==2: 切换标题右边的图标为显示状态,从缓存中取出缓存的组图布局,如果缓存中存在组图布局,添加到新闻中心页中,如果没有,初始化组图布局,将组图布局添加到新闻中心页中,缓存组图布局,加载组图数据 第一步:创建组图布局组图布局UI结构【newscenter_group_imageview.xml】UI结构代码实现: [XML] 纯文本查看 复制代码 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_group_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</LinearLayout> 第二步:初始化组图布局逻辑实现 [Java] 纯文本查看 复制代码 //加载组图的布局
private View createGroupImageViewLayout() {
View view = LayoutInflater.from(getContext()).inflate(R.layout.newscenter_group_imageview,(ViewGroup) getActivity().getWindow().getDecorView(),false);
rvGroupImageView = (RecyclerView) view.findViewById(R.id.rv_group_imageview);
//有的时候是列表,有的时候是网格
//线性布局管理器
llm = new LinearLayoutManager(getContext());
//网格布局管理器
glm = new GridLayoutManager(getContext(),2);
rvGroupImageView.setLayoutManager(llm);
//添加分割线
rvGroupImageView.addItemDecoration(new RecycleViewDivider(getContext(),LinearLayoutManager.HORIZONTAL,1, Color.BLACK));
return view;
}
加载组图数据逻辑实现:
//加载组图数据
private void loadGroupImageViewData(int position) {
//获取路径
final String url = Constant.HOST + newsCenterBean.data.get(position).url;
OkHttpUtils
.get()
.url(url)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
MyToast.show(getContext(),"获取组图失败");
}
@Override
public void onResponse(String response, int id) {
MyLogger.i(TAG,response);
}
});
} 第三步:切换组图:
[Java] 纯文本查看 复制代码 //切换内容
public void switchContent(int position){
//标题右边的切换menu
if(position == 2){
//显示
ibPicType.setVisibility(View.VISIBLE);
}else{
//隐藏
ibPicType.setVisibility(View.GONE);
}
//先从缓存的容器里面去获取
View view = cacheViews.get(position);
if(view == null){
//创建里面的内容
container.removeAllViews();
if(position == 2){
//组图
//初始化组图布局
view = createGroupImageViewLayout();
//将组图布局添加到新闻中心页中的FramenLayout容器中
addView(view);
//放入缓存中,如果缓存中有数据,直接取出
cacheViews.put(position,view);
//加载组图数据
loadGroupImageViewData(position);
}
} else if(view != null){
//添加布局
addView(view);
}
}
第四步:加载组图数据组图布局初始化完成以后,加载组图数据 [Java] 纯文本查看 复制代码 //加载组图数据
private void loadGroupImageViewData(int position) {
//获取路径
final String url = Constant.HOST + newsCenterBean.data.get(position).url;
OkHttpUtils
.get()
.url(url)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
MyToast.show(getContext(),"获取组图失败");
}
@Override
public void onResponse(String response, int id) {
MyLogger.i(TAG,response);
}
});
};
}
|