安卓当下最流行的吸顶效果的实现

开始逐渐领略到ItemDecoration的美~

今天让我 使用 ItemDecoration 来完成 可推动的悬浮导航栏的效果,最终实现的效果如下图:

20161204135240604

具体实现步骤如下:

根据我前面的文章所讲的RecyclerView的基本使用,我们先来完成基本的recyclerView

第一步:布局里写一个RecyclerView

第二步:实例化

Java

 

1

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

第三步:获取所需的数据 (这里我们来个真实点的情景,去联网请求数据)

Java

 

1

2

3

4

/**

    * 联网请求所需的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";

 

Java

想要更多   加qq群私聊群主:584508688

1

2

//联网获取数据  

       getDataFromNet();

 

Java

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

/**

     * 使用okhttpUtils进行联网请求数据

     */  

    private void getDataFromNet() {  

        OkHttpUtils.  

                get()  

                .url(url)  

                .build()  

                .execute(new StringCallback() {  

                    @Override  

                    public void onError(okhttp3.Call call, Exception e, int id) {  

                        Log.e("TAG", "联网失败" + e.getMessage());  

                    }  

  

                    @Override  

                    public void onResponse(String response, int id) {  

                        Log.e("TAG", "联网成功==" + response);  

  

                        //联网成功后使用fastjson解析  

                        processData(response);  

                    }  

                });  

    }

 

Java

想要更多   加qq群私聊群主:584508688

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/**

     * 使用fastjson进行解析

     *

     * @param json

     */  

    private void processData(String json) {  

        //这里使用GsonFormat生成对应的bean类  

       JSONObject jsonObject = parseObject(json);  

  

        String data = jsonObject.getString("data");  

        JSONObject dataObj = JSON.parseObject(data);  

  

        String coming = dataObj.getString("coming");  

        List<WaitMVBean.DataBean.ComingBean> comingslist = parseArray(coming, WaitMVBean.DataBean.ComingBean.class);  

  

        //测试是否解析数据成功  

//        String strTest = comingslist.get(0).getCat();  

//        Log.e("TAG", strTest + "222");  

  

         //解析数据成功,设置适配器-->  

        

        }  

  

    }

第四步:解析数据成功后,创建并设置适配器,并传递相关数据

Java

 

1

2

3

//解析数据成功,设置适配器  

           MyRecyclerAdapter adapter = new MyRecyclerAdapter( mContext,comingslist);  

           recyclerView.setAdapter(adapter);

适配器:

Java

想要更多   加qq群私聊群主:584508688

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

public class MyRecyclerAdapter extends RecyclerView.Adapter {  

  

    private final List<WaitMVBean.DataBean.ComingBean> comingslist;  

    private final Context mContext;  

    private final LayoutInflater mLayoutInflater;  

  

  

    public MyRecyclerAdapter(Context mContext, List<WaitMVBean.DataBean.ComingBean> comingslist) {  

        this.mContext = mContext;  

        this.comingslist = comingslist;  

        mLayoutInflater = LayoutInflater.from(mContext);  

    }  

  

    @Override  

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  

        return new MyViewHolder(mLayoutInflater.inflate(R.layout.date_item, null));  

    }  

  

    @Override  

    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  

        MyViewHolder myholder = (MyViewHolder) holder;  

        myholder.setData(position);  

    }  

  

    @Override  

    public int getItemCount() {  

        return comingslist.size();  

    }  

  

    class MyViewHolder extends RecyclerView.ViewHolder {  

        private TextView mv_name;  

        private TextView mv_dec;  

        private TextView mv_date;  

        private ImageView imageView;  

  

        public MyViewHolder(View itemView) {  

            super(itemView);  

            mv_name = (TextView) itemView.findViewById(R.id.mv_name);  

            mv_dec = (TextView) itemView.findViewById(R.id.mv_dec);  

            mv_date = (TextView) itemView.findViewById(R.id.mv_date);  

            imageView = (ImageView) itemView.findViewById(R.id.image);  

        }  

  

        public void setData(int position) {  

            WaitMVBean.DataBean.ComingBean coming = comingslist.get(position);  

  

            String name = coming.getNm();  

            mv_name.setText(name);  

  

            String date = coming.getShowInfo();  

            mv_date.setText(date);  

  

            String dec = coming.getScm();  

            mv_dec.setText(dec);  

  

            //注:当你发下图片无法打开是,做个字符串替换即可  

            String imagUrl = coming.getImg();  

            String newImagUrl = imagUrl.replaceAll("w.h", "50.80");  

  

            //使用Glide加载图片  

            Glide.with(mContext)  

                    .load(newImagUrl)  

                    .into(imageView);  

        }  

    }  

}

item的布局:

Java

想要更多   加qq群私聊群主:584508688

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

<?xml version="1.0" encoding="utf-8"?>  

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

    android:layout_width="wrap_content"  

    android:layout_height="wrap_content"  

    android:background="#ffffff"  

    android:gravity="center_vertical"  

    android:orientation="horizontal">  

  

    <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>

第五步:一定不能忘!!!

recycleView不仅要设置适配器还要设置布局管理者,否则图片不显示

Java

想要更多   加qq群私聊群主:584508688

1

2

GridLayoutManager manager = new GridLayoutManager(this, 1);  

            recyclerView.setLayoutManager(manager);

此时RecyclerView简单的完成效果如下:

20161204141955135

下面开始做 可推动的 悬浮导航栏:

第一步:首先我们来写一个类,它起标记的作用,来放每一个item的对应的悬浮栏的字符串

Java

想要更多   加qq群私聊群主:584508688

1

2

3

4

5

6

7

8

9

10

11

public class NameBean {  

    String name;  

  

    public String getName() {  

        return name;  

    }  

  

    public void setName(String name) {  

        this.name = name;  

    }  

}

第二步:自定义一个SectionDecoration 类 继承 RecyclerView的ItemDecoration

Java

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

public class SectionDecoration extends RecyclerView.ItemDecoration {  

    private static final String TAG = "SectionDecoration";  

  

    private List<NameBean> dataList;  

  

    private DecorationCallback callback;  

    private TextPaint textPaint;  

    private Paint paint;  

    private int topGap;  

    private int alignBottom;  

    private Paint.FontMetrics fontMetrics;  

  

  

    public SectionDecoration(List<NameBean> dataList, Context context, DecorationCallback decorationCallback) {  

        Resources res = context.getResources();  

        this.dataList = dataList;  

        this.callback = decorationCallback;  

        //设置悬浮栏的画笔---paint  

        paint = new Paint();  

        paint.setColor(res.getColor(R.color.colorGray));  

  

        //设置悬浮栏中文本的画笔  

        textPaint = new TextPaint();  

        textPaint.setAntiAlias(true);  

        textPaint.setTextSize(DensityUtil.dip2px(context, 14));  

        textPaint.setColor(Color.DKGRAY);  

        textPaint.setTextAlign(Paint.Align.LEFT);  

        fontMetrics = new Paint.FontMetrics();  

        //决定悬浮栏的高度等  

        topGap = res.getDimensionPixelSize(R.dimen.sectioned_top);  

        //决定文本的显示位置等  

        alignBottom = res.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);  

        Log.i(TAG, "getItemOffsets:" + pos);  

        String groupId = callback.getGroupId(pos);  

        if (groupId.equals("-1")) return;  

        //只有是同一组的第一个才显示悬浮栏  

        if (pos == 0 || isFirstInGroup(pos)) {  

            outRect.top = topGap;  

            if (dataList.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();  

        float lineHeight = textPaint.getTextSize() + fontMetrics.descent;  

  

        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 - topGap决定了悬浮栏绘制的高度和位置  

            c.drawRect(left, textY - topGap, right, textY, paint);  

            //left+2*alignBottom 决定了文本往左偏移的多少(加-->向左移)  

            //textY-alignBottom  决定了文本往右偏移的多少  (减-->向上移)  

            c.drawText(textLine, left + 2 * alignBottom, textY - alignBottom, textPaint);  

        }  

    }  

  

  

    /**

     * 判断是不是组中的第一个位置

     *

     * @param pos

     * @return

     */  

    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;  

            }  

        }  

    }  

  

    //定义一个借口方便外界的调用  

    interface DecorationCallback {  

        String getGroupId(int position);  

  

        String getGroupFirstLine(int position);  

    }  

}

第三步:在向list集合中先把每一个item的 起“标记”作用的字符串都加进去

Java

想要更多   加qq群私聊群主:584508688

1

setPullAction(comingslist);

 

Java

 

1

2

3

4

5

6

7

8

9

10

private void setPullAction(List<WaitMVBean.DataBean.ComingBean> comingslist) {  

        dataList = new ArrayList<>();  

  

        for (int i = 0; i < comingslist.size(); i++) {  

            NameBean nameBean = new NameBean();  

            String name0 = comingslist.get(i).getComingTitle();  

            nameBean.setName(name0);  

            dataList.add(nameBean);  

        }  

    }

第四步:在setAdapter() 前,为RecyclerView添加ItemDecoration:

Java

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

recyclerView.addItemDecoration(new SectionDecoration(dataList,mContext, new SectionDecoration.DecorationCallback() {  

               //返回标记id (即每一项对应的标志性的字符串)  

                @Override  

                public String getGroupId(int position) {  

                    if(dataList.get(position).getName()!=null) {  

                        return dataList.get(position).getName();  

                    }  

                    return "-1";  

                }  

  

                //获取同组中的第一个内容  

                @Override  

                public String getGroupFirstLine(int position) {  

                    if(dataList.get(position).getName()!=null) {  

                        return dataList.get(position).getName();  

                    }  

                    return "";  

                }  

            }));

这样就完成了~

再看一眼最终效果感受一下:

20161204135240604

转载于:https://my.oschina.net/u/3732404/blog/1583950

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值