├── .gitattributes ├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── restoflife │ │ └── itemdecoration │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── restoflife │ │ │ └── itemdecoration │ │ │ ├── CustomDecorationActivity.java │ │ │ ├── HorizontalItemDecorationActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── MyAdapter.java │ │ │ ├── UniversalDecorationActivity.java │ │ │ ├── VerticalDecorationActivity.java │ │ │ └── lib │ │ │ └── UniversalItemDecoration.java │ └── res │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── item.xml │ │ └── item_horizontal.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── restoflife │ └── itemdecoration │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UniversalItemDecoration 2 | RecyclerView高度定制的“万能分割线” 3 | 4 | 详细内容查看博客 5 | http://blog.csdn.net/u013134391/article/details/64123337 6 | 7 | 8 | ![demo](http://img.blog.csdn.net/20170320131219116?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzEzNDM5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 9 | ![demo](http://img.blog.csdn.net/20170320131230835?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzEzNDM5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 10 | ![demo](http://img.blog.csdn.net/20170320131340070?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzEzNDM5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.restoflife.itemdecoration" 8 | minSdkVersion 15 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:25.2.0' 28 | compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha9' 29 | testCompile 'junit:junit:4.12' 30 | compile 'com.android.support:recyclerview-v7:25.2.0' 31 | } 32 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/restoflife/itemdecoration/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.restoflife.itemdecoration; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.restoflife.itemdecoration", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/restoflife/itemdecoration/CustomDecorationActivity.java: -------------------------------------------------------------------------------- 1 | package com.restoflife.itemdecoration; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.os.Bundle; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.support.v7.widget.LinearLayoutManager; 10 | import android.support.v7.widget.RecyclerView; 11 | import android.util.Log; 12 | 13 | import com.restoflife.itemdecoration.lib.UniversalItemDecoration; 14 | 15 | import java.util.ArrayList; 16 | 17 | /** 18 | * Created by 余俊魁 on 2017/3/23. 19 | * Version 1 20 | * Function 21 | * Tips 自定义示例 22 | */ 23 | 24 | public class CustomDecorationActivity extends AppCompatActivity { 25 | 26 | 27 | private ArrayList listData = new ArrayList<>(); 28 | 29 | private int drawCount = 0; 30 | 31 | private static final String TAG = "CustomDecorationActivit"; 32 | 33 | @Override 34 | protected void onCreate(Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | 37 | for (int i = 0; i < 100; i++) { 38 | listData.add("item " + i); 39 | } 40 | 41 | RecyclerView recyclerView = new RecyclerView(this); 42 | LinearLayoutManager layoutManager = new LinearLayoutManager(this); 43 | layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 44 | recyclerView.setLayoutManager(layoutManager); 45 | 46 | recyclerView.addItemDecoration(new UniversalItemDecoration() { 47 | @Override 48 | public Decoration getItemOffsets(final int position) { 49 | 50 | if (position == 3) { 51 | Decoration decoration = new Decoration() { 52 | @Override 53 | public void drawItemOffsets(Canvas c, int leftZ, int topZ, int rightZ, int bottomZ) { 54 | 55 | drawCount++; 56 | Log.d(TAG, "drawItemOffsets: drawCount=" + drawCount); 57 | //拿着Canvas 随便玩啦(不要在这搞复杂的东西,因为不会缓存,而且你每一次滑动 都会调用一次这里) leftZ是线在屏幕中的实际位置 其他同上 58 | Paint paint = new Paint(); 59 | paint.setAntiAlias(true); 60 | paint.setTextSize(50); 61 | paint.setColor(Color.parseColor("#000000")); 62 | c.drawText("啦啦啦啦 我是自定义的分割线标题", 20, bottomZ, paint); 63 | } 64 | }; 65 | 66 | decoration.top = 100; 67 | return decoration; 68 | } 69 | return null; 70 | } 71 | }); 72 | 73 | recyclerView.setAdapter(new MyAdapter(listData, R.layout.item_horizontal)); 74 | setContentView(recyclerView); 75 | 76 | } 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/restoflife/itemdecoration/HorizontalItemDecorationActivity.java: -------------------------------------------------------------------------------- 1 | package com.restoflife.itemdecoration; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | 9 | import com.restoflife.itemdecoration.lib.UniversalItemDecoration; 10 | 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * Created by 余俊魁 on 2017/3/20. 15 | * Version 1 16 | * Function 17 | * Tips 横向 18 | */ 19 | 20 | public class HorizontalItemDecorationActivity extends AppCompatActivity { 21 | 22 | private ArrayList listData = new ArrayList<>(); 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | 28 | for (int i = 0; i < 100; i++) { 29 | listData.add("item " + i); 30 | } 31 | 32 | RecyclerView recyclerView = new RecyclerView(this); 33 | LinearLayoutManager layoutManager = new LinearLayoutManager(this); 34 | layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); 35 | recyclerView.setLayoutManager(layoutManager); 36 | 37 | recyclerView.addItemDecoration(new UniversalItemDecoration() { 38 | @Override 39 | public Decoration getItemOffsets(int position) { 40 | 41 | //直接不理position 设置右边分割线 2个px 42 | ColorDecoration decoration = new ColorDecoration(); 43 | decoration.right = 2; 44 | decoration.decorationColor = position % 2 == 0 ? Color.GREEN : Color.BLUE; 45 | return decoration; 46 | } 47 | }); 48 | 49 | recyclerView.setAdapter(new MyAdapter(listData, R.layout.item_horizontal)); 50 | setContentView(recyclerView); 51 | 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/restoflife/itemdecoration/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.restoflife.itemdecoration; 2 | 3 | import android.content.Intent; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | 8 | public class MainActivity extends AppCompatActivity implements View.OnClickListener { 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_main); 14 | 15 | findViewById(R.id.bt_horizontal).setOnClickListener(this); 16 | findViewById(R.id.bt_vertical).setOnClickListener(this); 17 | findViewById(R.id.bt_universal).setOnClickListener(this); 18 | findViewById(R.id.bt_custom).setOnClickListener(this); 19 | 20 | } 21 | 22 | @Override 23 | public void onClick(View v) { 24 | 25 | switch (v.getId()) { 26 | 27 | case R.id.bt_horizontal: 28 | startActivity(new Intent(this, HorizontalItemDecorationActivity.class)); 29 | break; 30 | 31 | case R.id.bt_vertical: 32 | startActivity(new Intent(this, VerticalDecorationActivity.class)); 33 | break; 34 | 35 | case R.id.bt_universal: 36 | startActivity(new Intent(this, UniversalDecorationActivity.class)); 37 | break; 38 | 39 | case R.id.bt_custom: 40 | startActivity(new Intent(this, CustomDecorationActivity.class)); 41 | break; 42 | } 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/restoflife/itemdecoration/MyAdapter.java: -------------------------------------------------------------------------------- 1 | package com.restoflife.itemdecoration; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by 余俊魁 on 2017/3/20. 13 | * Version 1 14 | * Function 15 | */ 16 | public class MyAdapter extends RecyclerView.Adapter { 17 | 18 | public ArrayList datas = null; 19 | 20 | private int itemLayoutId; 21 | 22 | public MyAdapter(ArrayList datas) { 23 | this.datas = datas; 24 | itemLayoutId = R.layout.item; 25 | } 26 | 27 | public MyAdapter(ArrayList datas, int itemLayoutId) { 28 | this.datas = datas; 29 | this.itemLayoutId = itemLayoutId; 30 | } 31 | 32 | @Override 33 | public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 34 | View view = LayoutInflater.from(viewGroup.getContext()).inflate(itemLayoutId, viewGroup, false); 35 | return new ViewHolder(view); 36 | } 37 | 38 | 39 | @Override 40 | public void onBindViewHolder(ViewHolder viewHolder, int position) { 41 | viewHolder.tv.setText(datas.get(position)); 42 | } 43 | 44 | @Override 45 | public int getItemCount() { 46 | return datas.size(); 47 | } 48 | 49 | public static class ViewHolder extends RecyclerView.ViewHolder { 50 | public TextView tv; 51 | 52 | public ViewHolder(View view) { 53 | super(view); 54 | tv = (TextView) view.findViewById(R.id.tv); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/restoflife/itemdecoration/UniversalDecorationActivity.java: -------------------------------------------------------------------------------- 1 | package com.restoflife.itemdecoration; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.GridLayoutManager; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | 10 | import com.restoflife.itemdecoration.lib.UniversalItemDecoration; 11 | 12 | import java.util.ArrayList; 13 | 14 | /** 15 | * Created by 余俊魁 on 2017/3/20. 16 | * Version 1 17 | * Function 18 | * 万能分割线 翱翔 19 | */ 20 | 21 | public class UniversalDecorationActivity extends AppCompatActivity { 22 | 23 | private ArrayList listData = new ArrayList<>(); 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | 29 | for (int i = 0; i < 100; i++) { 30 | listData.add("item " + i); 31 | } 32 | 33 | RecyclerView recyclerView = new RecyclerView(this); 34 | GridLayoutManager layoutManager = new GridLayoutManager(this, 6); 35 | 36 | //总的6列 控制每个item占据的列数 37 | layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 38 | @Override 39 | public int getSpanSize(int position) { 40 | 41 | //设定position2-6为 两个一行的 42 | if (1 < position && position < 7) { 43 | return 3;//3代表 当前(position)item占据3列 总6列 所以一行可以放2个 44 | } else if (9 < position && position < 19) {//设定position10-18为 三个一行的 45 | return 2; 46 | } else { 47 | return 6; 48 | } 49 | } 50 | }); 51 | 52 | recyclerView.setLayoutManager(layoutManager); 53 | 54 | recyclerView.addItemDecoration(new UniversalItemDecoration() { 55 | @Override 56 | public Decoration getItemOffsets(int position) { 57 | 58 | ColorDecoration decoration = new ColorDecoration(); 59 | 60 | //这里应该是你的判断逻辑 判断当前position 需要上下左右的分割线到底是多少 以及颜色 61 | 62 | //这是一个示例代码 这里要根据你自己的逻辑判断当前item需要上下左右的分割线到底是多少 以及颜色 63 | if (1 < position && position < 7) { 64 | 65 | //本组占据不同的列数的 中的position 66 | int index = position - 2; 67 | 68 | if (isLeft(2, index)) {//是左边 69 | decoration.left = 10; 70 | decoration.right = 10; 71 | } else if (isRight(2, index)) { //是右边 72 | decoration.right = 10; 73 | } else { 74 | //中间 75 | decoration.right = 10; 76 | } 77 | 78 | //前两个是第一行额外加上上边据 79 | if (index < 2) { 80 | decoration.top = 10; 81 | decoration.bottom = 10; 82 | } else { 83 | decoration.bottom = 10; 84 | } 85 | 86 | decoration.decorationColor = Color.BLUE; 87 | 88 | } else if (9 < position && position < 19) { 89 | 90 | int index = position - 10; 91 | 92 | if (isLeft(3, index)) { 93 | decoration.left = 10; 94 | decoration.right = 10; 95 | } else if (isRight(3, index)) { 96 | decoration.right = 10; 97 | } else { 98 | decoration.right = 10; 99 | } 100 | 101 | if (index < 3) { 102 | decoration.top = 10; 103 | decoration.bottom = 10; 104 | } else { 105 | decoration.bottom = 10; 106 | } 107 | 108 | } else { 109 | 110 | //普通一个item占据6列 一行一个 111 | decoration.bottom = 2; 112 | decoration.decorationColor = Color.GREEN; 113 | } 114 | 115 | return decoration; 116 | } 117 | }); 118 | 119 | recyclerView.setAdapter(new MyAdapter(listData)); 120 | setContentView(recyclerView); 121 | 122 | } 123 | 124 | // /** 125 | // * 是否是边上 126 | // * 127 | // * @param index 当前index 128 | // * @param rowNum 当前一行几列 129 | // * @return 130 | // */ 131 | // public static boolean isEdge(int rowNum, int index) { 132 | // 133 | // return isLeft(rowNum, index) || isRight(rowNum, index); 134 | // } 135 | 136 | public static boolean isLeft(int rowNum, int index) { 137 | 138 | return index % rowNum == 0; 139 | } 140 | 141 | public static boolean isRight(int rowNum, int index) { 142 | 143 | return index % rowNum == rowNum - 1; 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /app/src/main/java/com/restoflife/itemdecoration/VerticalDecorationActivity.java: -------------------------------------------------------------------------------- 1 | package com.restoflife.itemdecoration; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | 9 | import com.restoflife.itemdecoration.lib.UniversalItemDecoration; 10 | 11 | import java.util.ArrayList; 12 | 13 | import static android.icu.lang.UCharacter.GraphemeClusterBreak.V; 14 | 15 | /** 16 | * Created by 余俊魁 on 2017/3/20. 17 | * Version 1 18 | * Function 19 | * 纵向 20 | */ 21 | 22 | public class VerticalDecorationActivity extends AppCompatActivity { 23 | 24 | private ArrayList listData = new ArrayList<>(); 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | 30 | for (int i = 0; i < 100; i++) { 31 | listData.add("item " + i); 32 | } 33 | 34 | RecyclerView recyclerView = new RecyclerView(this); 35 | LinearLayoutManager layoutManager = new LinearLayoutManager(this); 36 | layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 37 | recyclerView.setLayoutManager(layoutManager); 38 | 39 | recyclerView.addItemDecoration(new UniversalItemDecoration() { 40 | @Override 41 | public Decoration getItemOffsets(int position) { 42 | 43 | //直接不理position 设置下面分割线 2个px 颜色BLACK 44 | ColorDecoration decoration = new ColorDecoration(); 45 | decoration.bottom = 2; 46 | decoration.decorationColor = position % 2 == 0 ? Color.GREEN : Color.BLUE; 47 | return decoration; 48 | } 49 | }); 50 | 51 | recyclerView.setAdapter(new MyAdapter(listData)); 52 | setContentView(recyclerView); 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/restoflife/itemdecoration/lib/UniversalItemDecoration.java: -------------------------------------------------------------------------------- 1 | package com.restoflife.itemdecoration.lib; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Color; 5 | import android.graphics.Paint; 6 | import android.graphics.Rect; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.View; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | /** 14 | * Created by yu on 2017/3/19. 15 | * 万能分割 16 | * 使用此类 item的tag会被占用 如果外部使用会造成乱 17 | * 外部可以使用 item.setTag(key,obj) 18 | */ 19 | 20 | public abstract class UniversalItemDecoration extends RecyclerView.ItemDecoration { 21 | 22 | private Map decorations = new HashMap<>(); 23 | 24 | private static final String TAG = "UniversalItemDecoration"; 25 | 26 | @Override 27 | public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { 28 | super.onDraw(c, parent, state); 29 | 30 | final int childSize = parent.getChildCount(); 31 | for (int i = 0; i < childSize; i++) { 32 | 33 | final View child = parent.getChildAt(i); 34 | //获取在getItemOffsets存起来的position 35 | int position = string2Int(child.getTag().toString(), 0); 36 | Decoration decoration = decorations.get(position); 37 | 38 | if (decoration == null) continue; 39 | RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); 40 | 41 | //view的上下左右包括 Margin 42 | int bottom = child.getBottom() + layoutParams.bottomMargin; 43 | int left = child.getLeft() - layoutParams.leftMargin; 44 | int right = child.getRight() + layoutParams.rightMargin; 45 | int top = child.getTop() - layoutParams.topMargin; 46 | 47 | //下面的 48 | if (decoration.bottom != 0) 49 | decoration.drawItemOffsets(c, left - decoration.left, bottom, right + decoration.right, bottom + decoration.bottom); 50 | //上面的 51 | if (decoration.top != 0) 52 | decoration.drawItemOffsets(c, left - decoration.left, top - decoration.top, right + decoration.right, top); 53 | //左边的 54 | if (decoration.left != 0) 55 | decoration.drawItemOffsets(c, left - decoration.left, top, left, bottom); 56 | //右边的 57 | if (decoration.right != 0) 58 | decoration.drawItemOffsets(c, right, top, right + decoration.right, bottom); 59 | 60 | } 61 | 62 | } 63 | 64 | @Override 65 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 66 | super.getItemOffsets(outRect, view, parent, state); 67 | 68 | //获取position 69 | int position = parent.getChildAdapterPosition(view); 70 | view.setTag(position); 71 | 72 | //获取调用者返回的Decoration 73 | Decoration decoration = getItemOffsets(position); 74 | 75 | if (decoration != null) { 76 | //偏移量设置给item 77 | outRect.set(decoration.left, decoration.top, decoration.right, decoration.bottom); 78 | 79 | } 80 | //存起来在onDraw用 81 | decorations.put(position, decoration); 82 | 83 | } 84 | 85 | 86 | /*** 87 | * 需调用者返回分割线对象 上下左右 和颜色值 88 | * @param position 89 | * @return 90 | */ 91 | public abstract Decoration getItemOffsets(int position); 92 | 93 | /** 94 | * 分割线 95 | */ 96 | public abstract static class Decoration { 97 | 98 | public int left, right, top, bottom; 99 | 100 | /** 101 | * 根据偏移量设定的 当前的线在界面中的坐标 102 | * 103 | * @param leftZ 104 | * @param topZ 105 | * @param rightZ 106 | * @param bottomZ 107 | */ 108 | public abstract void drawItemOffsets(Canvas c, int leftZ, int topZ, int rightZ, int bottomZ); 109 | 110 | } 111 | 112 | public static class ColorDecoration extends Decoration { 113 | 114 | private Paint mPaint; 115 | public int decorationColor = Color.BLACK; 116 | 117 | public ColorDecoration() { 118 | mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 119 | mPaint.setStyle(Paint.Style.FILL); 120 | } 121 | 122 | @Override 123 | public void drawItemOffsets(Canvas c, int leftZ, int topZ, int rightZ, int bottomZ) { 124 | 125 | mPaint.setColor(decorationColor); 126 | c.drawRect(leftZ, topZ, rightZ, bottomZ, mPaint); 127 | } 128 | 129 | } 130 | 131 | 132 | public static int string2Int(String s, int defValue) { 133 | try { 134 | return Integer.parseInt(s); 135 | } catch (Exception e) { 136 | return defValue; 137 | } 138 | 139 | 140 | } 141 | 142 | 143 | 144 | } 145 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 |