A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 小鲁哥哥 于 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);
                 }
            });
};
}




1 个回复

倒序浏览
多谢分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马