├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── jack │ │ └── hive │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── jack │ │ │ └── hive │ │ │ ├── BitmapCache.java │ │ │ ├── HiveAdapter.java │ │ │ ├── ImageViewHolder.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable │ │ ├── img_0.jpg │ │ ├── img_1.jpeg │ │ ├── img_10.jpg │ │ ├── img_11.jpg │ │ ├── img_12.jpeg │ │ ├── img_2.jpg │ │ ├── img_3.jpg │ │ ├── img_4.jpg │ │ ├── img_5.jpg │ │ ├── img_6.jpeg │ │ ├── img_7.jpg │ │ ├── img_8.jpg │ │ └── img_9.jpeg │ │ ├── layout │ │ ├── activity_main.xml │ │ └── vh_img.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.jpg │ │ ├── mipmap-mdpi │ │ └── ic_launcher.jpg │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.jpg │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.jpg │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.jpg │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── jack │ └── hive │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hivelayoutmanager-library ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── jack │ │ └── hivelayoutmanager_library │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── jack │ │ │ └── hive │ │ │ ├── HiveBucket.java │ │ │ ├── HiveConstants.java │ │ │ ├── HiveDrawable.java │ │ │ ├── HiveLayoutHelper.java │ │ │ ├── HiveLayoutManager.java │ │ │ ├── HiveMathUtils.java │ │ │ ├── HivePositionInfo.java │ │ │ └── IHiveMathUtils.java │ └── res │ │ └── values │ │ ├── attrs.xml │ │ └── strings.xml │ └── test │ └── java │ └── jack │ └── hivelayoutmanager_library │ └── ExampleUnitTest.java ├── maven-push.gradle └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .idea/ 10 | upload_maven.gradle -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/HiveLayoutManager/Lobby) 2 | 3 | # HiveLayoutManager 4 | 5 | 这是一个蜂巢布局管理器,它可以在RecyclerView中实现像蜂巢一样的布局。 6 | 7 | ## 1 效果展示 8 | 9 | **横向布局:** 10 | 11 | ![](https://chacojack.github.io/2016/09/29/RecyclerView的一个马蜂窝布局/horizontal.png) 12 | 13 | **纵向布局:** 14 | 15 | ![](https://chacojack.github.io/2016/09/29/RecyclerView的一个马蜂窝布局/vertical.png) 16 | 17 | **随机添加:** 18 | 19 | ![](https://chacojack.github.io/2016/09/29/RecyclerView的一个马蜂窝布局/add.gif) 20 | 21 | **随机删除:** 22 | 23 | ![](https://chacojack.github.io/2016/09/29/RecyclerView的一个马蜂窝布局/remove.gif) 24 | 25 | **随机移动:** 26 | 27 | ![](https://chacojack.github.io/2016/09/29/RecyclerView的一个马蜂窝布局/move.gif) 28 | 29 | **滚动:** 30 | 31 | ![](https://chacojack.github.io/2016/09/29/RecyclerView的一个马蜂窝布局/scroll.gif) 32 | 33 | ## 2 使用方法 34 | 35 | ### 2.1 加入依赖 36 | 37 | ``` 38 | compile 'com.github.chacojack:hivelayoutmanager:1.0.1' 39 | ``` 40 | 41 | ### 2.2 使用HiveLayoutManager 42 | 43 | 44 | 为RecyclerView设置HiveLayoutManager即可。其中包含横向和纵向两种方向。暂时只支持在初始化的时候设置方向,不支持后期改变。 45 | 46 | ``` 47 | recyclerView.setLayoutManager(new HiveLayoutManager(HiveLayoutManager.VERTICAL)); 48 | ``` 49 | 50 | 51 | ### 2.3 正六边形ViewHolder 52 | 53 | ViewHolder使用的时候建议使用固定边长的正方形,这样比较好看。可以通过提供的`HiveDrawable`,将图片裁切为正六边形。`HiveDrawable`继承自`Drawable`,我们使用的所有视图都是`View`,使用`View`中的`setBackground(Drawable background)`即可为一个`View`设置正六边形背景。但是这种方法会让图片保持原有的大小,不会根据`View`的大小自动调整。所以建议使用一个`ImageView`来显示图片。 54 | 55 | ``` 56 | HiveDrawable drawable = new HiveDrawable(HiveLayoutManager.VERTICAL,bitmap); 57 | imageView.setImageDrawable(drawable); 58 | ``` 59 | 60 | ViewHolder显示纯色背景: 61 | 62 | ``` 63 | drawable.setColor(resources.getColor(getRandomColor())); 64 | ``` 65 | 66 | 纯色配文字的一个简单示例: 67 | 68 | ![](https://chacojack.github.io/2016/09/29/RecyclerView的一个马蜂窝布局/color.png) 69 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "24.0.2" 6 | 7 | defaultConfig { 8 | applicationId "jack.hive" 9 | minSdkVersion 19 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | lintOptions { 21 | abortOnError false 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | testCompile 'junit:junit:4.12' 28 | // compile project(':hivelayoutmanager-library') 29 | compile 'com.android.support:appcompat-v7:24.2.0' 30 | compile 'com.github.chacojack:hivelayoutmanager:1.0.3' 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 /Users/zjchai/Library/Android/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 | -------------------------------------------------------------------------------- /app/src/androidTest/java/jack/hive/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package jack.hive; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/java/jack/hive/BitmapCache.java: -------------------------------------------------------------------------------- 1 | package jack.hive; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.util.LruCache; 7 | 8 | /** 9 | * Created by zjchai on 16/9/29. 10 | */ 11 | 12 | public enum BitmapCache { 13 | 14 | INSTANCE; 15 | 16 | LruCache mCache; 17 | Context mContext; 18 | 19 | public void init(Context context, int size) { 20 | mCache = new LruCache<>(size); 21 | mContext = context.getApplicationContext(); 22 | } 23 | 24 | public Bitmap getBitmap(int resId) { 25 | Bitmap bitmap = mCache.get(resId); 26 | if (bitmap == null) { 27 | bitmap = BitmapFactory.decodeResource(mContext.getResources(),resId) ; 28 | mCache.put(resId,bitmap) ; 29 | } 30 | return bitmap; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/jack/hive/HiveAdapter.java: -------------------------------------------------------------------------------- 1 | package jack.hive; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by zjchai on 16/9/10. 13 | */ 14 | public class HiveAdapter extends RecyclerView.Adapter{ 15 | 16 | 17 | List resId = new ArrayList<>() ; 18 | 19 | @Override 20 | public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 21 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.vh_img, parent,false); 22 | return new ImageViewHolder(view); 23 | } 24 | 25 | @Override 26 | public void onBindViewHolder(ImageViewHolder holder, int position) { 27 | holder.bind(resId.get(position),position) ; 28 | } 29 | 30 | @Override 31 | public int getItemCount() { 32 | return resId.size(); 33 | } 34 | 35 | public void addData(Integer data,int index) { 36 | resId.add(index,data) ; 37 | } 38 | 39 | public void addData(Integer data) { 40 | resId.add(data) ; 41 | } 42 | 43 | public void remove(int index){ 44 | resId.remove(index) ; 45 | } 46 | 47 | public void move(int r, int r2) { 48 | Integer id = resId.remove(r); 49 | resId.add(r2,id) ; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/jack/hive/ImageViewHolder.java: -------------------------------------------------------------------------------- 1 | package jack.hive; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | import android.graphics.Color; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.view.View; 8 | import android.widget.ImageView; 9 | import android.widget.ProgressBar; 10 | import android.widget.TextView; 11 | 12 | /** 13 | * Created by zjchai on 16/9/10. 14 | */ 15 | public class ImageViewHolder extends RecyclerView.ViewHolder { 16 | 17 | ImageView imageView; 18 | TextView textView ; 19 | 20 | public ImageViewHolder(View itemView) { 21 | super(itemView); 22 | imageView = (ImageView) itemView.findViewById(R.id.img_img); 23 | textView = (TextView) itemView.findViewById(R.id.number); 24 | } 25 | 26 | public void bind(Integer resId,int position) { 27 | Bitmap bitmap = BitmapCache.INSTANCE.getBitmap(resId); 28 | HiveDrawable drawable = new HiveDrawable(HiveLayoutManager.HORIZONTAL,bitmap); 29 | imageView.setImageDrawable(drawable); 30 | textView.setText(String.valueOf(position)); 31 | textView.setVisibility(View.GONE); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/jack/hive/MainActivity.java: -------------------------------------------------------------------------------- 1 | package jack.hive; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.util.Log; 7 | import android.view.View; 8 | 9 | import java.util.Random; 10 | 11 | public class MainActivity extends AppCompatActivity { 12 | 13 | public static final int[] resIds = new int[]{ 14 | R.drawable.img_0 15 | , R.drawable.img_1 16 | , R.drawable.img_2 17 | , R.drawable.img_3 18 | , R.drawable.img_4 19 | , R.drawable.img_5 20 | , R.drawable.img_6 21 | , R.drawable.img_7 22 | , R.drawable.img_8 23 | , R.drawable.img_9 24 | , R.drawable.img_10 25 | , R.drawable.img_11 26 | , R.drawable.img_12 27 | }; 28 | private static final String TAG = MainActivity.class.getSimpleName(); 29 | 30 | RecyclerView recyclerView; 31 | HiveLayoutManager layoutManager; 32 | HiveAdapter adapter; 33 | int index = 39; 34 | 35 | @Override 36 | protected void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | setContentView(R.layout.activity_main); 39 | initObjects(); 40 | 41 | initViews(); 42 | afterViews(); 43 | 44 | } 45 | 46 | private void initObjects() { 47 | BitmapCache.INSTANCE.init(this, 200 * 200 * 4 * 13); 48 | adapter = new HiveAdapter(); 49 | } 50 | 51 | private void initViews() { 52 | recyclerView = (RecyclerView) findViewById(R.id.list); 53 | findViewById(R.id.add).setOnClickListener(new View.OnClickListener() { 54 | @Override 55 | public void onClick(View v) { 56 | int r = getRandomPosition(); 57 | Log.d(TAG, "onClick: r" + r); 58 | adapter.addData(resIds[index % resIds.length], r); 59 | adapter.notifyItemInserted(r); 60 | index++; 61 | } 62 | }); 63 | findViewById(R.id.remove).setOnClickListener(new View.OnClickListener() { 64 | @Override 65 | public void onClick(View v) { 66 | if (adapter.getItemCount() != 0) { 67 | int r = getRandomPosition(); 68 | Log.d(TAG, "onClick: r" + r); 69 | adapter.remove(r); 70 | adapter.notifyItemRemoved(r); 71 | index--; 72 | } 73 | } 74 | }); 75 | findViewById(R.id.move).setOnClickListener(new View.OnClickListener() { 76 | @Override 77 | public void onClick(View v) { 78 | int r = getRandomPosition(); 79 | int r2 = getRandomPosition(); 80 | Log.d(TAG, "onClick: r" + r); 81 | adapter.move(r, r2); 82 | adapter.notifyItemMoved(r, r2); 83 | } 84 | }); 85 | } 86 | 87 | private int getRandomPosition() { 88 | int count = adapter.getItemCount(); 89 | if (count > 0) { 90 | return new Random().nextInt(count); 91 | } else { 92 | return 0; 93 | } 94 | } 95 | 96 | private void afterViews() { 97 | recyclerView.setLayoutManager(layoutManager = new HiveLayoutManager(HiveLayoutManager.HORIZONTAL)); 98 | recyclerView.setAdapter(adapter); 99 | for (int i = 0; i < index; i++) { 100 | adapter.addData(resIds[i % resIds.length]); 101 | } 102 | // layoutManager.setGravity(HiveLayoutManager.CENTER); 103 | layoutManager.setGravity(HiveLayoutManager.ALIGN_LEFT); 104 | // layoutManager.setGravity(HiveLayoutManager.ALIGN_RIGHT); 105 | // layoutManager.setGravity(HiveLayoutManager.ALIGN_TOP); 106 | // layoutManager.setGravity(HiveLayoutManager.ALIGN_BOTTOM); 107 | // layoutManager.setGravity(HiveLayoutManager.ALIGN_LEFT | HiveLayoutManager.ALIGN_TOP); 108 | // layoutManager.setGravity(HiveLayoutManager.ALIGN_LEFT | HiveLayoutManager.ALIGN_BOTTOM); 109 | // layoutManager.setGravity(HiveLayoutManager.ALIGN_RIGHT | HiveLayoutManager.ALIGN_TOP); 110 | // layoutManager.setGravity(HiveLayoutManager.ALIGN_RIGHT | HiveLayoutManager.ALIGN_BOTTOM); 111 | layoutManager.setPadding(300, 400, 500, 600); 112 | 113 | } 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_0.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_1.jpeg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_10.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_11.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_12.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_12.jpeg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_2.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_3.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_4.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_5.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_6.jpeg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_7.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_8.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/img_9.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chacojack/HiveLayoutManager/657a0445528f4cf1eec8f9f3eddb310f7961dbdc/app/src/main/res/drawable/img_9.jpeg -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 |