安卓仿手机网易新闻app项目开发系列之(四)数据分离与填充界面 下

来源:互联网 发布:centos虚拟机安装vbox 编辑:程序博客网 时间:2024/06/11 05:31

一.项目简介和流程

  接着上次讲的,今天实现的是上拉刷新和下拉加载,让页面数据进行更新,下面来结合代码来讲解。


二。项目流程

2.上拉和下拉刷新功能

1)下拉加载

   在fragment.layout里添加swipe的布局文件,因为是在recycleview里实现,所以把布局添加在其中。

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.v4.widget.SwipeRefreshLayout        android:id="@+id/swipe"        android:layout_width="match_parent"        android:layout_height="wrap_content">   <android.support.v7.widget.RecyclerView     android:id="@+id/recycle_view"     android:layout_width="match_parent"     android:layout_height="match_parent"/>    </android.support.v4.widget.SwipeRefreshLayout>    </LinearLayout>

  

    设置下拉图形颜色和监听事件

public class FirstpageFragment extends Fragment implements JsonUtils.CallBackListener,SwipeRefreshLayout.OnRefreshListener {private SwipeRefreshLayout swipe;    private int lastVisibleItem;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {                    View v=getActivity().getLayoutInflater().inflate(R.layout.fragment_layout,                                 (ViewGroup)getActivity().findViewById(R.id.view_pager),false);          getData();        mRecyclerView= (RecyclerView) v.findViewById(R.id.recycle_view);        adapter=new FirstPageAdapter(getActivity(),item_list,mBannerBean);        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));        mRecyclerView.setAdapter(adapter);        //新加代码-----------》》        swipe= (SwipeRefreshLayout) v.findViewById(R.id.swipe);        swipe.setColorSchemeResources(android.R.color.holo_blue_bright,android.R.color.holo_green_light);        swipe.setOnRefreshListener(this); // 注册本类监听,下拉后通知本类进行更新数据      // new JsonUtils().getResult();         initListener();        return v;    }
    下拉后刷新回调方法(监听触发事件),下拉后数据+4条,然后重写初始化数据,最后把下拉图标关闭。这里的loadnum=4
 public void onRefresh() {        now_num+=LOADNUM;//刷新后多显示几条数据        initData();        swipe.setRefreshing(false);    }

   这里有点要注意,就是需要在初始化数据里在加载数据时先清空缓存,否则会出现下拉刷新数据时发现重复数据

 public void initData(){          if(msg_list!=null){              String[] img=new String[3];              String[] title=new String[3];              String[] toUrl=new String[3];              item_list.clear();//清空缓存          List<Data> data=msg_list[mPosition];          for (int i=0;i<3;i++){              img[i]=data.get(i).getThumbnail();              title[i]=data.get(i).getTitle();              toUrl[i]=data.get(i).getUrl();          }              mBannerBean.setTitle(title);              mBannerBean.setImg_url(img);              mBannerBean.setTourl(toUrl);           for(int i=3;i<now_num;i++){                item_list.add(data.get(i));           }              adapter.notifyDataSetChanged();      }

  2)上拉刷新

上拉刷新就是在上拉到最后一条数据的时候底部有个加载图标,然后实现数据刷新,首先要添加一个底部刷新样式的布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal"    android:gravity="center"    android:layout_width="match_parent"    android:layout_height="wrap_content">    <ProgressBar        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="loading....."/></LinearLayout>

    接着需要在firstpageadapter.java中更改下代码:

 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        RecyclerView.ViewHolder holder=null;        if(viewType==TYPE_HEAD){          //此处创建顶部banner的viewholder            holder=new BannerViewHolder(LayoutInflater.from(mcontext).inflate(R.layout.itemheader_banner,parent,false));           //把最外层布局加载然后传到构造函数BannerViewHolder(); 此句语句等同于://            View view=LayoutInflater.from(mcontext).inflate(R.layout.itemheader_banner,parent,false);//            RecyclerView.ViewHolder holder=new BannerViewHolder(view) ;     }else if(viewType==TYPE_NORMAL) {            holder=new ItemViewHolder(LayoutInflater.from(mcontext).inflate(R.layout.item_firstfragment,parent,false));    } //新增加--- else if (viewType==TYPE_FOOT){            holder=new FootViewHolder(LayoutInflater.from(mcontext).inflate(R.layout.itemfooter,parent,false));        }          return holder;    }

这里和之前的类似,也就是创建一个新类型的holder;

 class FootViewHolder extends  RecyclerView.ViewHolder {        public FootViewHolder(View itemView) {            super(itemView);        }    }

   如标备注新加代码部分所示,position是当前item总数的位置下标,也就是说当position+1=getitemcount的时候,就表示有最底部有个刷新视图出现,开始刷新数据---------------------------------------

 public int getItemCount() {        return item_data.size()+1+1;        //item_data.size()+1+1;    }    //告诉创建什么类型viewholder    public int getItemViewType(int position) {        if(position==0){            return TYPE_HEAD;         //新加代码---------》        }else if(position+1==getItemCount()){              return TYPE_FOOT;           }        else {            return  TYPE_NORMAL;        }    }


给上拉刷新添加实现事件监听listener()方法:

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {                    View v=getActivity().getLayoutInflater().inflate(R.layout.fragment_layout,                                 (ViewGroup)getActivity().findViewById(R.id.view_pager),false);          getData();        mRecyclerView= (RecyclerView) v.findViewById(R.id.recycle_view);        adapter=new FirstPageAdapter(getActivity(),item_list,mBannerBean);        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));        mRecyclerView.setAdapter(adapter);        swipe= (SwipeRefreshLayout) v.findViewById(R.id.swipe);        swipe.setColorSchemeResources(android.R.color.holo_blue_bright,android.R.color.holo_green_light);        swipe.setOnRefreshListener(this); // 注册本类监听,下拉后通知本类进行更新数据      // new JsonUtils().getResult();         initListener();        return v;    }
private void initListener() {           mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){               @Override               //状态发生变化是触发               public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                   super.onScrollStateChanged(recyclerView, newState);                   if(newState==RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem+1==adapter.getItemCount()){                      mhandler.postDelayed(new Runnable() {                          @Override                          public void run() {                              now_num+=LOADNUM;                              initData();                          }                      },1500);                   }               }               @Override//滚动时监听               public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                   super.onScrolled(recyclerView, dx, dy);                   LinearLayoutManager Lm= (LinearLayoutManager) recyclerView.getLayoutManager();                   lastVisibleItem=Lm.findLastVisibleItemPosition();               }           });
private Handler mhandler=new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);        }    };

这里事件监听使用的是内部类的方式来实现的,原理和swipe通过实现接口来写是一样的。因为onscrolistener是抽象类,内部类里重写了两个方法,一个是滚动时监听,一个是状态发生变化是监听,这两个的区别是:滚动监听就是发生上下或左右滑动时事件就触发;而状态变化的方法是当以下三种状态发之间变化时才触发:1.静止没有滚动 2.外部拖拽滑动 3. 自动滚动   在滚动监听判断是否到最后底部一个位置 lastvisibleitem,然后在状态变化方法里再判断,是否状态已经不在变化&&已经到最底部位置,然后通过开启一个子线程延迟1.5s后执行更新4条数据。

   最后放两张今天的效果图 :


  

   

  下拉加载


上拉刷新


阅读全文
0 0