这个例子是我看到一篇博客写的,自己在写的过程中发现代码没有给全,于是自己摸索了把代码补全,实现了炫酷的效果并且上传了代码如个有需要的同学请自取,看代码
首先主布局里面一个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); } }