您的位置:首页 > 移动开发 > Android开发

Android studio RecyclerView实现炫酷吸顶效果

2017-01-18 15:05 543 查看
这个例子是我看到一篇博客写的,自己在写的过程中发现代码没有给全,于是自己摸索了把代码补全,实现了炫酷的效果并且上传了代码如个有需要的同学请自取,看代码



首先主布局里面一个recyclerview

MinaActivity中逻辑代码

RecyclerView recyclerView;
WaitMVBean waitMVBean;
List<WaitMVBean.DataBean.ComingBean> list;
List<NameBean> beanList;
/**
* 联网请求所需的url
*/
public String url="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";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_main);
intoView();
getDataFromNet();
}

/**
* 初始化视图
*/
private void intoView(){
recyclerView= (RecyclerView) findViewById(R.id.recyclerview);
GridLayoutManager gridLayoutManager=new GridLayoutManager(this,1);
recyclerView.setLayoutManager(gridLayoutManager);

}

private void setPullAction(List<WaitMVBean.DataBean.ComingBean> list){
beanList=new ArrayList<>();
for (int i=0;i<list.size();i++){
NameBean nameBean=new NameBean();
String name=list.get(i).getComingTitle();
nameBean.setName(name);
beanList.add(nameBean);
}
}

/**
* 请求数据
*/
private void getDataFromNet(){
RequestQueue requestQueue= Volley.newRequestQueue(this);

StringRequest stringRequest=new StringRequest(com.android.volley.Request.Method.GET, url, new com.android.volley.Response.Listener<String>() {
@Override
public void onResponse(String s) {
Log.e("数据",s);
processData(s);

}
}, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(MainActivity.this,"请求失败",Toast.LENGTH_LONG).show();
}
});
requestQueue.add(stringRequest);
}

/**
* 解析数据
* @param s
*/
private void processData(String s){
final Gson gson=new Gson();
waitMVBean=gson.fromJson(s,WaitMVBean.class);
list=waitMVBean.getData().getComing();
setPullAction(list);

recyclerView.addItemDecoration(new SectionDecoration(beanList, this, new SectionDecoration.DecorationCallback() {
@Override
public String getGroupId(int position) {
if (beanList.get(position).getName()!=null){
return beanList.get(position).getName();
}
return "-1";
}

//获取同一组的内容
@Override
public String getGroupFirstLine(int position) {
if (beanList.get(position).getName()!=null){
return beanList.get(position).getName();
}
return "";
}
}));
MyRecyclerAdapter myRecyclerAdapter=new MyRecyclerAdapter(MainActivity.this,list);
recyclerView.setAdapter(myRecyclerAdapter);
}


适配器代码

ublic class MyRecyclerAdapter extends RecyclerView.Adapter {
private final List<WaitMVBean.DataBean.ComingBean> list;
private final Context context;
private final LayoutInflater inflater;

public MyRecyclerAdapter(Context context, List<WaitMVBean.DataBean.ComingBean> list) {
this.context = context;
this.list = list;
inflater = LayoutInflater.from(context);

}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(inflater.inflate(R.layout.data_item,null));
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
MyViewHolder holder1= (MyViewHolder) holder;
holder1.setDate(position);
}

@Override
public int getItemCount() {
return list.size();
}

class MyViewHolder extends RecyclerView.ViewHolder {
ImageView image;
TextView mvName;
TextView tvPeople;
TextView tvProfessional;
TextView mvDec;
TextView mvDate;

public MyViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.image);
mvName = (TextView) itemView.findViewById(R.id.mv_name);
tvPeople = (TextView) itemView.findViewById(R.id.tv_people);
tvProfessional = (TextView) itemView.findViewById(R.id.tv_professional);
mvDec = (TextView) itemView.findViewById(R.id.mv_dec);
mvDate = (TextView) itemView.findViewById(R.id.mv_date);
}

public void setDate(int position){
WaitMVBean.DataBean.ComingBean comingBean=list.get(position);
mvName.setText(comingBean.getNm());
mvDate.setText(comingBean.getShowInfo());
mvDec.setText(comingBean.getScm());
String url=comingBean.getImg();
String imageurl=url.replaceAll("w.h","50.80");//字符串替换
Log.e("图片路径",url);
Glide.with(context).load(imageurl).into(image);
}

}


布局懒得写的小朋友直接贴上

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:background="#ffffff"
android:gravity="center_vertical"
android:layout_height="match_parent"

>
<ImageView
android:id="@+id/image"
android:layout_width="70dp"
android:layout_height="110dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="8dp"
android:layout_marginTop="5dp" />

<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_weight="1"
android:orientation="vertical">

<TextView
android:id="@+id/mv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="神奇動物在哪裏"
android:textColor="#000000"
android:textSize="15sp" />

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="观众"
android:textColor="#55000000"
android:textSize="14sp" />

<TextView
android:id="@+id/tv_people"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9.0 "
android:textColor="#FFCE42"
android:textSize="18sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" | 专业"
android:textColor="#55000000"
android:textSize="14sp" />

<TextView
android:id="@+id/tv_professional"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="6.7"
android:textColor="#FFCE42"
android:textSize="18sp" />
</LinearLayout>

<TextView
android:id="@+id/mv_dec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="神奇動物城,法師顯超能"
android:textColor="#99000000"
android:textSize="11sp" />

<TextView
android:id="@+id/mv_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="今天165家影院放映2088场"
android:textColor="#99000000"
android:textSize="11sp" />

</LinearLayout>

</LinearLayout>


下面这个就是写悬浮栏的逻辑代码了

public class SectionDecoration extends RecyclerView.ItemDecoration {
private List<NameBean> beanList;
private TextPaint textPaint;
private Paint paint;
private int topGap;
private int alignBottom;
private DecorationCallback callback;
private Paint.FontMetrics fontMetrics;

interface DecorationCallback{
String getGroupId(int position);
String getGroupFirstLine(int position);
}
private boolean isFirstInGroup(int pos){
if (pos==0){
return  true;
}else {
//因为是根据字符串的内容的相同与否来判断是不是同意组的,所以此处的标记id要是String类型
//如果只做联系人列表悬浮框里面显示的是字母则标记id直接用int类型就行了
String prevGroupId=callback.getGroupId(pos-1);
String groupId=callback.getGroupId(pos);
//判断前一个字符串与当前字符串是否相同
if(prevGroupId.equals(groupId)){
return false;
}else {
return true;
}
}

}
public SectionDecoration(List<NameBean> beanList, Context context,DecorationCallback callback ){
Resources resources=context.getResources();
this.beanList=beanList;
this.callback=callback;
//设置悬浮栏的画笔
paint=new Paint();
paint.setColor(ContextCompat.getColor(context,R.color.colorPrimary));
//设置悬浮栏中文本的画笔
textPaint=new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setTextSize(DensityUtil.dip2px(context,12));
textPaint.setTextAlign(Paint.Align.LEFT);
textPaint.setColor(Color.WHITE);
fontMetrics=new Paint.FontMetrics();
//决定悬浮栏的高度等
topGap=resources.getDimensionPixelSize(R.dimen.sectioned_top);
//决定文本的显示位置等
alignBottom=resources.getDimensionPixelSize(R.dimen.sectioned_alignBottom);
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int pos=parent.getChildAdapterPosition(view);
String groupId=callback.getGroupId(pos);
if (groupId.equals("-1"))return;
//只有是同一组的第一个才显示悬浮栏
if(pos==0 || isFirstInGroup(pos)){
outRect.top=topGap;
if (beanList.get(pos).getName()==""){
outRect.top=0;
}
}else {
outRect.top=0;
}
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
int left=parent.getPaddingLeft();
int right=parent.getWidth()-parent.getPaddingRight();
int childCount=parent.getChildCount();
for (int i=0;i<childCount;i++){
View view=parent.getChildAt(i);
int position=parent.getChildAdapterPosition(view);
String groupId=callback.getGroupId(position);
if (groupId.equals("-1"))return;
String textLine=callback.getGroupFirstLine(position).toUpperCase();
if (textLine==""){
float top=view.getTop();
float bottom=view.getTop();
c.drawRect(left,top,right,bottom,paint);
return;
}else {
if (position==0|| isFirstInGroup(position)){
float top=view.getTop()-topGap;
float bottom=view.getTop();
//绘制悬浮栏
c.drawRect(left,top-topGap,right,bottom,paint);
//绘制文本
c.drawText(textLine,left,bottom,textPaint);
}

}
}
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
int itemCount=state.getItemCount();
int childCount=parent.getChildCount();
int left=parent.getPaddingLeft();
int right=parent.getWidth()-parent.getPaddingRight();
String preGroupId="";
String groupId="-1";
for (int i=0; i<childCount;i++){
View view=parent.getChildAt(i);
int position=parent.getChildAdapterPosition(view);
preGroupId=groupId;
groupId=callback.getGroupId(position);
if (groupId.equals("-1") || groupId.equals(preGroupId))continue;
String textLine=callback.getGroupFirstLine(position).toUpperCase();
if (TextUtils.isEmpty(textLine))continue;
int viewBottom=view.getBottom();
float textY=Math.max(topGap,view.getTop());
//下一个和当前不一样移动当前
if (position+1<itemCount){
String nextGroupId=callback.getGroupId(position+1);
//组内最后一个view进入了header
if (nextGroupId!=groupId&&viewBottom<textY){
textY=viewBottom;
}
}
//textY-toGap决定了悬浮栏绘制的高度和位置
c.drawRect(left,textY-topGap,right,textY,paint);
//left+2*alignbottom决定了文本往右偏移的多少
c.drawText(textLine,left+2*alignBottom,textY-alignBottom,textPaint);

}
}

}


NameBean实体类

public class NameBean {
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

String name;
}


WaitMVBean 这个可以根据返回的json数据设计使用GsonFrom工具


DensityUtil工具类

public class DensityUtil {
public static int dip2px(Context context,float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}

public static int px2dip(Context context,float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: