1,先来看一下今天实现的效果:

2,这次的效果是使用ItemDecoration来实践的,来看一看我们的实现吧

  第一步:首先添加依赖,由于我们这些数据是请求网络的,所以一下我们添加网络框架依赖、RecyclerView、Glide依赖

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.qianmo.stickyitemdecoration"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
//添加reccycleview
compile 'com.android.support:recyclerview-v7:25.1.1'
//添加glide,需要依赖V4包
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:25.1.1'
//添加水波纹效果
compile 'com.balysv:material-ripple:1.0.2'
//添加butter注解
compile 'com.jakewharton:butterknife:8.2.1'
apt 'com.jakewharton:butterknife-compiler:8.2.1'
//添加网络框架
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
compile 'com.google.code.gson:gson:2.6.2'
testCompile 'junit:junit:4.12'
}

  第二步:主界面的xml文件就只是一个简单的RecyclerView控件,首先来实例化我们的RecyclerView

recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

  第三步:获取网络请求数据,首先我们要创建MovieServiceApi接口,并使用GET请求访问目标接口

  请求地址

http://api.meituan.com/mmdb/movie/v2/list/rt/order/coming.json?ci=1&limit=12&token=&__vhost=api.maoyan.com&utm_campaign=AmovieBmovieCD-1&movieBundleVersion=6801&utm_source=xiaomi&utm_medium=android&utm_term=6.8.0&utm_content=868030022327462&net=255&dModel=MI%205&uuid=0894DE03C76F6045D55977B6D4E32B7F3C6AAB02F9CEA042987B380EC5687C43&lat=40.100673&lng=116.378619&__skck=6a375bce8c66a0dc293860dfa83833ef&__skts=1463704714271&__skua=7e01cf8dd30a179800a7a93979b430b2&__skno=1a0b4a9b-44ec-42fc-b110-ead68bcc2824&__skcy=sXcDKbGi20CGXQPPZvhCU3%2FkzdE%3D

  MovieServiceApi.java

package com.qianmo.stickyitemdecoration.api;
import com.qianmo.stickyitemdecoration.base.BaseResponse;
import com.qianmo.stickyitemdecoration.bean.MovieBean;
import retrofit2.http.GET;
import rx.Observable;
/**
* Created by wangjitao on 2017/3/3 0003.
* E-Mail:543441727@qq.com
* 电影网API
*/
public interface MovieApiService {
@GET("v2/list/rt/order/coming.json?ci=1&limit=12&token=&__vhost=api.maoyan.com&utm_campaign=AmovieBmovieCD-1&movieBundleVersion=6801&utm_source=xiaomi&utm_medium=android&utm_term=6.8.0&utm_content=868030022327462&net=255&dModel=MI%205&uuid=0894DE03C76F6045D55977B6D4E32B7F3C6AAB02F9CEA042987B380EC5687C43&lat=40.100673&lng=116.378619&__skck=6a375bce8c66a0dc293860dfa83833ef&__skts=1463704714271&__skua=7e01cf8dd30a179800a7a93979b430b2&__skno=1a0b4a9b-44ec-42fc-b110-ead68bcc2824&__skcy=sXcDKbGi20CGXQPPZvhCU3%2FkzdE%3D")
Observable<BaseResponse<MovieBean>> getMovieDatas();
}

  创建数据接口响应的Bean

  BaseResponse.java

package com.qianmo.stickyitemdecoration.base;
/**
* Created by wangjitao on 2017/3/3 0003.
* E-Mail:543441727@qq.com
* 数据返回体的基本接收类,由于本次接口没有code和message
*/
public class BaseResponse<T> {
//    private int code;
//    private String message;
private T data;
//    public String getMessage() {
//        return message;
//    }
//
//    public void setMessage(String message) {
//        this.message = message;
//    }
//
//    public int getCode() {
//        return code;
//    }
//
//    public void setCode(int code) {
//        this.code = code;
//    }
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

  MovieBean.java

package com.qianmo.stickyitemdecoration.bean;
import java.util.List;
/**
* Created by wangjitao on 2017/3/3 0003.
* E-Mail:543441727@qq.com
* 用于数据接收实体类
*/
public class MovieBean {
private List<ComingBean> coming ;
public List<ComingBean> getComing() {
return coming;
}
public void setComing(List<ComingBean> coming) {
this.coming = coming;
}
}

  ComingBean.java

package com.qianmo.stickyitemdecoration.bean;
import java.util.List;
/**
* Created by Administrator on 2017/3/3 0003.
* E-Mail:543441727@qq.com
*/
public class ComingBean {
/**
* boxInfo : 喵,即将上映
* cat : 动作,科幻
* civilPubSt : 0
* comingTitle : 3月10日 周五
* desc : 主演:亚伦·保尔,肖恩·宾,琳娜·海蒂
* dir : 野末武志
* dur : 116
* effectShowNum : 0
* fra : 日本
* frt : 2016-08-19
* globalReleased : false
* headLineShow : false
* headLinesVO : []
* id : 346383
* img : http://p0.meituan.net/w.h/movie/5be09f397d474988afaf930ac5346243715496.png
* late : false
* localPubSt : 0
* mk : 0
* nm : 最终幻想15:王者之剑
* pn : 98
* preShow : false
* proScore : 0
* proScoreNum : 0
* pubDate : 1489075200000
* pubDesc : 2017-03-10大陆上映
* pubShowNum : 0
* recentShowDate : 0
* recentShowNum : 0
* rt : 2017-03-10
* sc : 0
* scm : 法力渐微弱,勇士卫祖国
* showCinemaNum : 0
* showInfo : 2017-03-10 下周五上映
* showNum : 0
* showst : 4
* snum : 903
* star : 亚伦·保尔,肖恩·宾,琳娜·海蒂
* ver : 2D
* videoId : 83711
* videoName : 魔法机械版预告片
* videourl : http://maoyan.meituan.net/movie/videos/854x480df7f69dd367b4dd5829c98d1a5a07dfa.mp4
* vnum : 9
* weight : 1
* wish : 22799
* wishst : 0
*/
private String boxInfo;
private String cat;
private int civilPubSt;
private String comingTitle;
private String desc;
private String dir;
private int dur;
private int effectShowNum;
private String fra;
private String frt;
private boolean globalReleased;
private boolean headLineShow;
private int id;
private String img;
private boolean late;
private int localPubSt;
private int mk;
private String nm;
private int pn;
private boolean preShow;
private int proScore;
private int proScoreNum;
private long pubDate;
private String pubDesc;
private int pubShowNum;
private int recentShowDate;
private int recentShowNum;
private String rt;
private int sc;
private String scm;
private int showCinemaNum;
private String showInfo;
private int showNum;
private int showst;
private int snum;
private String star;
private String ver;
private int videoId;
private String videoName;
private String videourl;
private int vnum;
private int weight;
private int wish;
private int wishst;
private List<?> headLinesVO;
public String getBoxInfo() {
return boxInfo;
}
public void setBoxInfo(String boxInfo) {
this.boxInfo = boxInfo;
}
public String getCat() {
return cat;
}
public void setCat(String cat) {
this.cat = cat;
}
public int getCivilPubSt() {
return civilPubSt;
}
public void setCivilPubSt(int civilPubSt) {
this.civilPubSt = civilPubSt;
}
public String getComingTitle() {
return comingTitle;
}
public void setComingTitle(String comingTitle) {
this.comingTitle = comingTitle;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public int getDur() {
return dur;
}
public void setDur(int dur) {
this.dur = dur;
}
public int getEffectShowNum() {
return effectShowNum;
}
public void setEffectShowNum(int effectShowNum) {
this.effectShowNum = effectShowNum;
}
public String getFra() {
return fra;
}
public void setFra(String fra) {
this.fra = fra;
}
public String getFrt() {
return frt;
}
public void setFrt(String frt) {
this.frt = frt;
}
public boolean isGlobalReleased() {
return globalReleased;
}
public void setGlobalReleased(boolean globalReleased) {
this.globalReleased = globalReleased;
}
public boolean isHeadLineShow() {
return headLineShow;
}
public void setHeadLineShow(boolean headLineShow) {
this.headLineShow = headLineShow;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public boolean isLate() {
return late;
}
public void setLate(boolean late) {
this.late = late;
}
public int getLocalPubSt() {
return localPubSt;
}
public void setLocalPubSt(int localPubSt) {
this.localPubSt = localPubSt;
}
public int getMk() {
return mk;
}
public void setMk(int mk) {
this.mk = mk;
}
public String getNm() {
return nm;
}
public void setNm(String nm) {
this.nm = nm;
}
public int getPn() {
return pn;
}
public void setPn(int pn) {
this.pn = pn;
}
public boolean isPreShow() {
return preShow;
}
public void setPreShow(boolean preShow) {
this.preShow = preShow;
}
public int getProScore() {
return proScore;
}
public void setProScore(int proScore) {
this.proScore = proScore;
}
public int getProScoreNum() {
return proScoreNum;
}
public void setProScoreNum(int proScoreNum) {
this.proScoreNum = proScoreNum;
}
public long getPubDate() {
return pubDate;
}
public void setPubDate(long pubDate) {
this.pubDate = pubDate;
}
public String getPubDesc() {
return pubDesc;
}
public void setPubDesc(String pubDesc) {
this.pubDesc = pubDesc;
}
public int getPubShowNum() {
return pubShowNum;
}
public void setPubShowNum(int pubShowNum) {
this.pubShowNum = pubShowNum;
}
public int getRecentShowDate() {
return recentShowDate;
}
public void setRecentShowDate(int recentShowDate) {
this.recentShowDate = recentShowDate;
}
public int getRecentShowNum() {
return recentShowNum;
}
public void setRecentShowNum(int recentShowNum) {
this.recentShowNum = recentShowNum;
}
public String getRt() {
return rt;
}
public void setRt(String rt) {
this.rt = rt;
}
public int getSc() {
return sc;
}
public void setSc(int sc) {
this.sc = sc;
}
public String getScm() {
return scm;
}
public void setScm(String scm) {
this.scm = scm;
}
public int getShowCinemaNum() {
return showCinemaNum;
}
public void setShowCinemaNum(int showCinemaNum) {
this.showCinemaNum = showCinemaNum;
}
public String getShowInfo() {
return showInfo;
}
public void setShowInfo(String showInfo) {
this.showInfo = showInfo;
}
public int getShowNum() {
return showNum;
}
public void setShowNum(int showNum) {
this.showNum = showNum;
}
public int getShowst() {
return showst;
}
public void setShowst(int showst) {
this.showst = showst;
}
public int getSnum() {
return snum;
}
public void setSnum(int snum) {
this.snum = snum;
}
public String getStar() {
return star;
}
public void setStar(String star) {
this.star = star;
}
public String getVer() {
return ver;
}
public void setVer(String ver) {
this.ver = ver;
}
public int getVideoId() {
return videoId;
}
public void setVideoId(int videoId) {
this.videoId = videoId;
}
public String getVideoName() {
return videoName;
}
public void setVideoName(String videoName) {
this.videoName = videoName;
}
public String getVideourl() {
return videourl;
}
public void setVideourl(String videourl) {
this.videourl = videourl;
}
public int getVnum() {
return vnum;
}
public void setVnum(int vnum) {
this.vnum = vnum;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getWish() {
return wish;
}
public void setWish(int wish) {
this.wish = wish;
}
public int getWishst() {
return wishst;
}
public void setWishst(int wishst) {
this.wishst = wishst;
}
public List<?> getHeadLinesVO() {
return headLinesVO;
}
public void setHeadLinesVO(List<?> headLinesVO) {
this.headLinesVO = headLinesVO;
}
}

  第四部:创建适配器

  MyAdapter.java

package com.qianmo.stickyitemdecoration.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.qianmo.stickyitemdecoration.R;
import com.qianmo.stickyitemdecoration.bean.ComingBean;
import java.util.List;
import static java.lang.System.load;
/**
* Created by Administrator on 2017/3/3 0003.
* E-Mail:543441727@qq.com
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private Context context;
private List<ComingBean> datas;
public MyAdapter(Context context, List<ComingBean> datas) {
this.context = context;
this.datas = datas;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_recyclerview, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
String imagUrl = datas.get(position).getImg();
String newImagUrl = imagUrl.replaceAll("w.h", "50.80");
Glide
.with(context)
.load(newImagUrl)
.error(R.mipmap.ic_launcher)
.into(holder.img);
holder.tv_time.setText(datas.get(position).getPubDesc());
holder.tv_title.setText(datas.get(position).getNm());
holder.tv_introduce.setText(datas.get(position).getDesc());
holder.tv_score_major_real.setText(datas.get(position).getDur()+"");
holder.tv_score_people_real.setText(datas.get(position).getPn()+"");
}
@Override
public int getItemCount() {
return datas == null ? 0 : datas.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView img;
TextView tv_title;
TextView tv_introduce;
TextView tv_score_major_real;
TextView tv_score_people_real;
TextView tv_time;
public ViewHolder(View view) {
super(view);
img = (ImageView) view.findViewById(R.id.img);
tv_title = (TextView) view.findViewById(R.id.tv_title);
tv_introduce = (TextView) view.findViewById(R.id.tv_introduce);
tv_score_major_real = (TextView) view.findViewById(R.id.tv_score_major_real);
tv_score_people_real = (TextView) view.findViewById(R.id.tv_score_people_real);
tv_time = (TextView) view.findViewById(R.id.tv_time);
}
}
}

  第五步:自定义ItemDecoration,使头部悬浮,具体思路代码中有了,就不在分析了

  FloatingItemDecoration.java

package com.qianmo.stickyitemdecoration.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.Dimension;
import android.support.annotation.DrawableRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.View;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Administrator on 2017/3/3 0003.
* E-Mail:543441727@qq.com
*/
public class FloatingItemDecoration extends RecyclerView.ItemDecoration {
private static final String TAG = "FloatingItemDecoration";
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable mDivider;
private int dividerHeight;
private int dividerWidth;
private Map<Integer, String> keys = new HashMap<>();
private int mTitleHeight;
private Paint mTextPaint;
private Paint mBackgroundPaint;
private float mTextHeight;
private float mTextBaselineOffset;
private Context mContext;
/**
* 滚动列表的时候是否一直显示悬浮头部
*/
private boolean showFloatingHeaderOnScrolling = true;
public FloatingItemDecoration(Context context) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
this.dividerHeight = mDivider.getIntrinsicHeight();
this.dividerWidth = mDivider.getIntrinsicWidth();
init(context);
}
/**
* 自定义分割线
*
* @param context
* @param drawableId 分割线图片
*/
public FloatingItemDecoration(Context context, @DrawableRes int drawableId) {
mDivider = ContextCompat.getDrawable(context, drawableId);
this.dividerHeight = mDivider.getIntrinsicHeight();
this.dividerWidth = mDivider.getIntrinsicWidth();
init(context);
}
/**
* 自定义分割线
* 也可以使用{@link Canvas#drawRect(float, float, float, float, Paint)}或者{@link Canvas#drawText(String, float, float, Paint)}等等
* 结合{@link Paint}去绘制各式各样的分割线
*
* @param context
* @param color         整型颜色值,非资源id
* @param dividerWidth  单位为dp
* @param dividerHeight 单位为dp
*/
public FloatingItemDecoration(Context context, @ColorInt int color, @Dimension float dividerWidth, @Dimension float dividerHeight) {
mDivider = new ColorDrawable(color);
this.dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, context.getResources().getDisplayMetrics());
this.dividerHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerHeight, context.getResources().getDisplayMetrics());
init(context);
}
private void init(Context mContext) {
this.mContext = mContext;
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, mContext.getResources().getDisplayMetrics()));
mTextPaint.setColor(Color.WHITE);
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
mTextHeight = fm.bottom - fm.top;//计算文字高度
mTextBaselineOffset = fm.bottom;
mBackgroundPaint = new Paint();
mBackgroundPaint.setAntiAlias(true);
mBackgroundPaint.setColor(Color.MAGENTA);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
drawVertical(c, parent);
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
if (!showFloatingHeaderOnScrolling) {
return;
}
int firstVisiblePos = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
if (firstVisiblePos == RecyclerView.NO_POSITION) {
return;
}
String title = getTitle(firstVisiblePos);
if (TextUtils.isEmpty(title)) {
return;
}
boolean flag = false;
if (getTitle(firstVisiblePos + 1) != null && !title.equals(getTitle(firstVisiblePos + 1))) {
//说明是当前组最后一个元素,但不一定碰撞了
//            Log.e(TAG, "onDrawOver: "+"==============" +firstVisiblePos);
View child = parent.findViewHolderForAdapterPosition(firstVisiblePos).itemView;
if (child.getTop() + child.getMeasuredHeight() < mTitleHeight) {
//进一步检测碰撞
//                Log.e(TAG, "onDrawOver: "+child.getTop()+"$"+firstVisiblePos );
c.save();//保存画布当前的状态
flag = true;
c.translate(0, child.getTop() + child.getMeasuredHeight() - mTitleHeight);//负的代表向上
}
}
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int top = parent.getPaddingTop();
int bottom = top + mTitleHeight;
c.drawRect(left, top, right, bottom, mBackgroundPaint);
float x = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, mContext.getResources().getDisplayMetrics());
float y = bottom - (mTitleHeight - mTextHeight) / 2 - mTextBaselineOffset;//计算文字baseLine
c.drawText(title, x, y, mTextPaint);
if (flag) {
//还原画布为初始状态
c.restore();
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int pos = parent.getChildViewHolder(view).getAdapterPosition();
if (keys.containsKey(pos)) {//留出头部偏移
outRect.set(0, mTitleHeight, 0, 0);
} else {
outRect.set(0, dividerHeight, 0, 0);
}
}
/**
* *如果该位置没有,则往前循环去查找标题,找到说明该位置属于该分组
*
* @param position
* @return
*/
private String getTitle(int position) {
while (position >= 0) {
if (keys.containsKey(position)) {
return keys.get(position);
}
position--;
}
return null;
}
private void drawVertical(Canvas c, RecyclerView parent) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int top = 0;
int bottom = 0;
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (!keys.containsKey(params.getViewLayoutPosition())) {
//画普通分割线
top = child.getTop() - params.topMargin - dividerHeight;
bottom = top + dividerHeight;
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
} else {
//画头部
top = child.getTop() - params.topMargin - mTitleHeight;
bottom = top + mTitleHeight;
c.drawRect(left, top, right, bottom, mBackgroundPaint);
//                float x=child.getPaddingLeft()+params.leftMargin;
float x = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, mContext.getResources().getDisplayMetrics());
float y = bottom - (mTitleHeight - mTextHeight) / 2 - mTextBaselineOffset;//计算文字baseLine
//                Log.e(TAG, "drawVertical: "+bottom );
c.drawText(keys.get(params.getViewLayoutPosition()), x, y, mTextPaint);
}
}
}
public void setShowFloatingHeaderOnScrolling(boolean showFloatingHeaderOnScrolling) {
this.showFloatingHeaderOnScrolling = showFloatingHeaderOnScrolling;
}
public void setKeys(Map<Integer, String> keys) {
this.keys.clear();
this.keys.putAll(keys);
}
public void setmTitleHeight(int titleHeight) {
this.mTitleHeight = titleHeight;
}
}

  第六步:设置ItemDecoration,设置适配器

 final FloatingItemDecoration floatingItemDecoration=new FloatingItemDecoration(this, Color.GRAY,1,1);
floatingItemDecoration.setKeys(keys);
floatingItemDecoration.setmTitleHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50,getResources().getDisplayMetrics()));
recycleview.addItemDecoration(floatingItemDecoration);
adapter = new MyAdapter(mContext, datas);
recycleview.setHasFixedSize(true);
recycleview.setAdapter(adapter);

  完整的MainActivity代码如下:

package com.qianmo.stickyitemdecoration;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import com.qianmo.stickyitemdecoration.adapter.MyAdapter;
import com.qianmo.stickyitemdecoration.api.MovieApiService;
import com.qianmo.stickyitemdecoration.base.BaseResponse;
import com.qianmo.stickyitemdecoration.bean.ComingBean;
import com.qianmo.stickyitemdecoration.bean.MovieBean;
import com.qianmo.stickyitemdecoration.bean.NameBean;
import com.qianmo.stickyitemdecoration.utils.Constant;
import com.qianmo.stickyitemdecoration.view.FloatingItemDecoration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import butterknife.BindView;
import butterknife.ButterKnife;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.recycleview)
RecyclerView recycleview;
private List<ComingBean> datas;
private Map<Integer,String> keys=new HashMap<>();//存放所有key的位置和内容
private MyAdapter adapter;
private Context mContext = MainActivity.this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initData();
}
/**
* 请求数据
*/
private void initData() {
datas = new ArrayList<>();
requestNetwork();
}
/**
* 初始化UI
*/
private void initView() {
GridLayoutManager manager = new GridLayoutManager(this, 1);
recycleview.setLayoutManager(manager);
keys.put(0,"欧美大片");
keys.put(2,"国产剧透");
keys.put(4,"印度神剧");
final FloatingItemDecoration floatingItemDecoration=new FloatingItemDecoration(this, Color.GRAY,1,1);
floatingItemDecoration.setKeys(keys);
floatingItemDecoration.setmTitleHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50,getResources().getDisplayMetrics()));
recycleview.addItemDecoration(floatingItemDecoration);
adapter = new MyAdapter(mContext, datas);
recycleview.setHasFixedSize(true);
recycleview.setAdapter(adapter);
}
/**
* 请求网络
*/
private void requestNetwork() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
MovieApiService movieApiService = retrofit.create(MovieApiService.class);
movieApiService.getMovieDatas()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<BaseResponse<MovieBean>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(BaseResponse<MovieBean> movieBeanBaseResponse) {
datas.addAll(movieBeanBaseResponse.getData().getComing());
initView();
//                        adapter.notifyDataSetChanged();
}
});
}
}

  再上一些github下载地址:https://github.com/543441727/StickyItemDecoration.git

Android -- RecyclerView实现顶部吸附效果相关推荐

  1. Android实现支付宝AR功能,Android RecyclerView 实现支付宝首页效果

    Android RecyclerView 实现支付宝首页效果 [TOC] 虽然我本人不喜欢支付宝的,但是这个网格本身其实还是不错的,项目更新中更改了一个布局为网格模式,类似支付宝.(估计是产品抄袭的= ...

  2. 微信小程序tab导航+滚动顶部吸附效果(开发实例)

    具体思路如下,我们首先要拿到需要吸附元素的据顶部距离,然后再去判断,如果超过了,我们通过判断添加样式即可,如在有不理解的,可以私信小编. <view style="height:100 ...

  3. android吸附菜单,Android RecycleView实现滑动停止后自动吸附效果

    Android RecycleView实现滑动停止后自动吸附效果 发布时间:2020-11-02 16:01:42 来源:亿速云 阅读:124 作者:Leah 这篇文章将为大家详细讲解有关Androi ...

  4. Android Tv版嵌套滑动实现极光云视听顶部导航效果

    Android Tv版嵌套滑动实现极光云视听顶部导航效果 通过这篇文章您可以和小王一起: 了解嵌套滑动的流程,原理 自定义Behavior的原理. 简单的实现TV版的嵌套滑动 小王最近很开心,上次快速 ...

  5. android view显示隐藏动画效果,Android 根据手势顶部View自动展示与隐藏效果

    首先来看一下效果: 大体思路如下: 总体布局用了一个自定义的ViewGroup,里面包了两个View(top View,bottomView) 我在bottomView里放了ViewPager,里面又 ...

  6. Android RecyclerView实现类似于老虎机抽奖,数字滚动等动画效果

    1.RecyclerViewLoopScrollAnimation项目介绍 RecyclerViewLoopScrollAnimation 适用于Android RecyclerView的循环滚动动画 ...

  7. android RecyclerView一步步打造分组效果、类似QQ分组、折叠菜单、分组效果(一)

    第二篇文章链接: android RecyclerView一步步打造分组效果.类似QQ分组.折叠菜单.分组效果(二) 效果图: 前言 之前看到这种效果如果用recyclerview来实现没有一点思路, ...

  8. android横向滚轮特效,RecyclerView实现横向滚动效果

    本文实例为大家分享了RecyclerView实现横向滚动效果的具体代码,供大家参考,具体内容如下 布局文件 xmlns:android="http://schemas.android.com ...

  9. Android RecyclerView 吸顶效果(一)

    实现效果: 实现方案介绍 recyclerView实现吸顶效果有2种方案: 方案1: 通过ItemDecoration 并重写对应的getItemOffsets().onDraw().onDrawOv ...

最新文章

  1. 人民日报:中国 31 个省市区最好的大学
  2. Redis的高级特性哨兵
  3. java输出二进制数_Java打印整数的二进制表示(代码与解析)
  4. C语言学习之输入一个大于三的值判断是否为素数
  5. 安装Rational Enterprise Suite(Robot...)时遇到的问题及解决办法!
  6. nopCommerce的源代码结构和架构
  7. 【转】定位oops的具体代码行
  8. 【PAT - 甲级1094】The Largest Generation (25分)(dfs建树)
  9. springcloud 相同服务名_浅谈分布式与微服务
  10. linux pae内核安装,Linux 安装PAE内核
  11. Java 算法 矩阵乘法
  12. XML与java的应用
  13. shell解决服务器高可用
  14. 学单片机的动力是什么,学单片机来做什么,需要多长时间把它学会
  15. 基于51单片机GPS的导航系统设计(3)---毕设论文
  16. 一篇吃透前置加加和后置加加(附练习题)
  17. 什么是栈?栈的特点和应用场景
  18. 云存储服务OneDrive捆绑系统销售,30多家欧洲公司投诉微软垄断
  19. 迷茫的程序员和中国软件业
  20. Mac微信防撤回安装教程——已失效

热门文章

  1. 路由器网口1一直闪烁正常吗_网口1一直闪烁上不了网(图文)
  2. 计算机应用基础课程作业2016,2016浙大远程教育计算机应用基础作业
  3. win8.1系统在线安装VS2017出现Internet连接问题的解决办法
  4. 拦截召唤神龙云文件,运行本地文件(侵删)
  5. Aleo的PoSW共识
  6. 新浪微博开发平台基于php的sdk包(包含demo程序),新浪微博API开发教程(一)-体验篇...
  7. 纯干货!短视频脚本怎么写?零基础新手小白也能写好短视频脚本!【覃小龙课堂】
  8. vue集合离线百度地图
  9. the mid-autumn festival
  10. pygame-KidsCanCode系列jumpy-part12-platform图片