代码已同步至码云上,有兴趣的小伙伴可以去看下:
https://git.oschina.net/joy_yuan/ShoppingMall
前面第二天的博文里,讲了利用radiogroup的状态切换的回调方法,来实现fragment的切换,下面讲第一个页面,即homeFragment的导航图片的切换功能。
具体效果图如下: 上面的图片是几个远程图片,需要实现几张图片的循环切换
一、主页面的布局
主页面布局,整体上分三块:
1、头部的搜索框
2、头部下面的主题部分,是一个recycleview构成的内容展示区域
3、右下角的一个图片,实现点击一下后,直接跳转到顶部的功能
a 头部搜索框布局
是在2个textview的基础上做的更改:
搜索框那个textview实现了背景图就是搜索框的效果,drawableleft放一个搜索图片即可实现
消息那块,是在textview的 drawabletop放一个图片即可
b 、主页面布局
二 主页面的功能
1、继承自baseFragment,实现里面的方法,即inITview和inItdata().
在inITview里,返回要展示给首页显示的布局,即
View view=View.inflate(context,R.layout.fragment_home,null);
最后return view; 展示这个fragment_home.xml布局给页面显示。
/** * 强制子类实现他,让在oncreateview里显示这个布局。 * * @return */ @Override public View initview() { View view=View.inflate(context, R.layout.fragement_home,null); tv_search_home= (TextView) view.findViewById(R.id.tv_search_home); tv_message_home= (TextView) view.findViewById(R.id.tv_message_home); rv_home= (RecyclerView) view.findViewById(R.id.rv_home); ib_top= (ImageButton) view.findViewById(R.id.ib_top); //设置监听 initListener(); return view; } private void initListener() { //设置置顶按钮监听 ib_top.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { rv_home.scrollToPosition(0); } }); tv_search_home.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context,"点击了搜索",Toast.LENGTH_SHORT).show(); } }); tv_message_home.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context,"点击了消息",Toast.LENGTH_SHORT).show(); } }); }
2、利用fragment的生命周期,在创建完homeFragment,这个fragment开始展示时,即homefragment回调onActivityCreated()方法时,加载数据。具体可看看我写的父类,BaseFragment。
3、加载数据时,即调用initData()方法时,去联网获取数据,在这里利用了okhttpUtils,去获取数据
@Override public void initData() { super.initData(); System.out.println("开始加载数据--------------------------"); getDataFromNet(); } private void getDataFromNet() { String url = Constants.HOME_URL; OkHttpUtils .get() .url(url) .build() .execute(new StringCallback() { /** * 联网失败,调用此方法 * @param call * @param e * @param id */ @Override public void onError(Call call, Exception e, int id) { Log.e(TAG, "onError: 首页失败时返回错误=="+e.getMessage()); } /** * 联网成功,调用此方法 * @param response * @param id */ @Override public void onResponse(String response, int id) { Log.d(TAG, "onResponse: "+response); /** * 解析json字符串 */ processData(response); } }); }
4、获取到网络上的数据json字符串后,利用阿里巴巴的fastjson去解析字符串,将字符串解析为实体类对象。 在解析为实体类对象前,我们需要知道实体类有哪些属性,根据json返回的数据,利用gson,将返回的字符串,反向生成实体类。步骤如下:
a、打开Android studio的setting
b、找到plugins,在右侧搜索框输入gson,找到gsonformat,点击安装,安装后,需要重启Androidstudio。
c 、在homeFragment类的任何一个位置,放置光标,然后点击Androidstudio上方工具栏里的code,选择generate,然后选择Gsonformat,在弹出的框内,将返回的json字符串全部复制粘贴到这个框内,点击OK
d、上步中点ok后,会自动分析json字符串构成,然后会预生成实体类的属性给用户,如果确认,点击OK即可生成该json字符串对应的实体类,ResultDataBean.java类。
5、开始解析json字符串,利用fastjson时,需要在build.glide里加入
compile 'com.alibaba:fastjson:1.1.61.android' 引用fastjson的jar包到项目
6、解析完字符串后,就像给listview设置适配器一样,需要给recycleview也设置适配器,然后设置它的布局管理者来显示这个recycleview里的图片轮播
/** * 解析字符串 * @param json */ private void processData(String json) { ResultBeanData result = (ResultBeanData) JSON.parseObject(json,ResultBeanData.class); resultBean = result.getResult(); if (resultBean!=null){ //将数据传给适配器 adapter=new HomeFragmentAdapter(context,resultBean); rv_home.setAdapter(adapter); //给recycleview设置布局管理者 rv_home.setLayoutManager(new GridLayoutManager(context,1)); } }
三、recycleview的适配器
1、自定义HomeFragmentAdapter必须继承extends RecycleView.Adapter,然后必须重写它的三个方法
2、重写构造方法,接收上面6里面传给适配器里的数据
public HomeFragmentAdapter(Context context, ResultBeanData.ResultBean resultBean) { this.context=context; this.resultBean=resultBean; /** * 加载布局文件的类对象 */ layoutInflater = LayoutInflater.from(context); }
3、在适配器里,定义内部类BannerViewHolder 必须extends RecycleView.ViewHolder,在里面写了一个方法,setData(),往banner里加载图片,用到了Glide
/** * 所有类型的viewholder都要继承recycleview的viewholder */ class BannerViewHolder extends RecyclerView.ViewHolder{ private Context context; private View view; private Banner banner; //banner_viewpager里的banner控件id /** * 构造方法,实例化其中的参数 * @param context * @param inflate */ public BannerViewHolder(Context context, View inflate) { super(inflate); this.context=context; this.view=inflate; banner= (Banner) view.findViewById(R.id.banner); } /** * 往banner里加载数据,根据第三方框架Banner的方法 **/ public void setData(Listbanner_info) { List p_w_picpathsUrl=new ArrayList<>(); for (ResultBeanData.ResultBean.BannerInfoBean bannerInfoBean:banner_info){ String p_w_picpathurl=bannerInfoBean.getImage(); //这个路径是例如: /14782094.jpg这样子的路径,需要在前面加上图片的根路径 p_w_picpathsUrl.add(Constants.IMG_URL+p_w_picpathurl); } //利用glide加载远程图片,这里的path,就是setImages传过来的参数p_w_picpathsUrl的每个具体路径 banner.setImageLoader(new ImageLoader() { @Override public void displayImage(Context context, Object path, ImageView p_w_picpathView) { Glide.with(context).load(path).into(p_w_picpathView); //使用glide来加载远程图片 } }); //通过banner的setp_w_picpaths来绑定数据 banner.setImages(p_w_picpathsUrl); banner.setDelayTime(1000); banner.start(); } }
至此,主页面的banner轮播图片功能完成,具体代码可以参看上传到码云上的代码。
在网上找到了一些关于Banner的一些资料,一起放到下面。
常量
常量名称 | 描述 | 所属方法 |
BannerConfig.NOT_INDICATOR | 不显示指示器和标题 | setBannerStyle |
BannerConfig.CIRCLE_INDICATOR | 显示圆形指示器 |
setBannerStyle |
BannerConfig.NUM_INDICATOR | 显示数字指示器 | setBannerStyle |
BannerConfig.NUM_INDICATOR_TITLE | 显示数字指示器和标题 | setBannerStyle |
BannerConfig.CIRCLE_INDICATOR_TITLE | 显示圆形指示器和标题(垂直显示) | setBannerStyle |
BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE | 显示圆形指示器和标题(水平显示) | setBannerStyle |
BannerConfig.LEFT | 指示器居左 | setIndicatorGravity |
BannerConfig.CENTER | 指示器居中 | setIndicatorGravity |
BannerConfig.RIGHT | 指示器居右 | setIndicatorGravity |
动画常量类(setBannerAnimation方法调用)
常量类名 |
Transformer.Default |
Transformer.Accordion |
Transformer.BackgroundToForeground |
Transformer.ForegroundToBackground |
Transformer.CubeIn |
Transformer.CubeOut |
Transformer.DepthPage |
Transformer.FlipHorizontal |
Transformer.FlipVertical |
Transformer.RotateDown |
Transformer.RotateUp |
Transformer.ScaleInOut |
Transformer.Stack |
Transformer.Tablet |
Transformer.ZoomIn |
Transformer.ZoomOut |
Transformer.ZoomOutSlide |
方法
方法名 | 描述 | 版本限制 |
setBannerStyle(int bannerStyle) | 设置轮播样式(默认为CIRCLE_INDICATOR) | 无 |
setIndicatorGravity(int type) | 设置指示器位置(没有标题默认为右边,有标题时默认左边) | 无 |
isAutoPlay(boolean isAutoPlay) | 设置是否自动轮播(默认自动) | 无 |
startAutoPlay() | 开始轮播 | 1.4开始,此方法只作用于banner加载完毕-->需要在start()后执行 |
stopAutoPlay() | 结束轮播 |
1.4开始,此方法只作用于banner加载完毕-->需要在start()后执行 |
start() | 开始进行banner渲染 | 1.4开始 |
setOffscreenPageLimit(int limit) | 同viewpager的方法作用一样 | 1.4.2开始 |
setBannerTitle(String[] titles) | 设置轮播要显示的标题和图片对应(如果不传默认不显示标题) | 1.3.3结束 |
setBannerTitleList(List titles) | 设置轮播要显示的标题和图片对应(如果不传默认不显示标题) | 1.3.3结束 |
setBannerTitles(List titles) | 设置轮播要显示的标题和图片对应(如果不传默认不显示标题) | 1.4开始 |
setDelayTime(int time) | 设置轮播图片间隔时间(单位毫秒,默认为2000) | 无 |
setImages(Object[]/List> p_w_picpathsUrl) | 设置轮播图片(所有设置参数方法都放在此方法之前执行) | 1.4后去掉数组传参 |
setImages(Object[]/List> p_w_picpathsUrl,OnLoadImageListener listener) | 设置轮播图片,并且自定义图片加载方式 | 1.3.3结束 |
setOnBannerClickListener(this) | 设置点击事件,下标是从1开始 | 无 |
setOnLoadImageListener(this) | 设置图片加载事件,可以自定义图片加载方式 | 1.3.3结束 |
setImageLoader(Object implements ImageLoader) | 设置图片加载器 | 1.4开始 |
setOnPageChangeListener(this) | 设置viewpager的滑动监听 | 无 |
setBannerAnimation(Class extends PageTransformer> transformer) | 设置viewpager的默认动画,传值见动画表 | 无 |
setPageTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer) | 设置viewpager的自定义动画 | 无 |
Attributes属性(banner布局文件中调用)
Attributes | forma | describe |
delay_time | integer | 轮播执行时间,默认2000 |
is_auto_play | boolean | 是否自动轮播,默认true |
title_background | color | reference |
title_textcolor | color | 标题字体颜色 |
title_textsize | dimension | 标题字体大小 |
title_height | dimension | 标题栏高度 |
indicator_width | dimension | 指示器圆形按钮的宽度 |
indicator_height | dimension | 指示器圆形按钮的高度 |
indicator_margin | dimension | 指示器之间的间距 |
indicator_drawable_selected | reference | 指示器选中效果 |
indicator_drawable_unselected | reference | 指示器未选中效果 |
p_w_picpath_scale_type | enum(fit_xy/center_crop) | 和p_w_picpathview的ScaleType作用一样 |