├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── libraries │ ├── ComAndroidSupportAppcompatV71800_aar.xml │ └── support_v4_18_0_0.xml ├── misc.xml ├── modules.xml ├── scopes │ └── scope_settings.xml └── vcs.xml ├── README.md ├── StaggeredView.iml ├── StaggeredView ├── .gitignore ├── StaggeredView-StaggeredView.iml ├── build.gradle ├── proguard-rules.txt └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── fonts │ │ └── SignPainter_HouseScript.ttf │ ├── ic_launcher-web.png │ ├── java │ └── com │ │ └── jooik │ │ └── staggeredview │ │ ├── MainActivity.java │ │ ├── frags │ │ └── FragmentStaggeredView.java │ │ └── util │ │ ├── ISquareItem.java │ │ ├── ShadowProperties.java │ │ ├── SquareItem.java │ │ └── SquareType.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ ├── cheese_almkaese.jpg │ ├── cheese_appenzeller.jpg │ ├── cheese_aragon.jpg │ ├── cheese_asiago.jpg │ ├── cheese_banon.jpg │ ├── cheese_bavariablu.jpg │ ├── cheese_beaufort.png │ ├── cheese_belpaese.jpg │ ├── cheese_bergader_edelpilz.jpg │ ├── cheese_bergkaese.jpg │ └── ic_launcher.png │ ├── layout │ ├── activity_main.xml │ └── fragment_staggered_view.xml │ ├── menu │ └── main.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── android_staggered_view.iml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── android_staggeredview.png ├── android_staggeredview01.png ├── android_staggeredview02.png ├── android_staggeredview03.png └── twitter.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | StaggeredView -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/ComAndroidSupportAppcompatV71800_aar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/libraries/support_v4_18_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 1.6 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | StaggeredView 2 | ============= 3 | 4 | A simple staggered view for Android :-) 5 | 6 | Hint: StaggeredView has been created within Android Studio - this guide describes how to integrate StaggeredView into your Android Studio project. Unfortunately currently AS (0.3.6) does not provide a smooth way of library integration (except you have ten hours left and already 'Master-Of-The-Gradle-Crap') so we quickly describe a programmatic way of embedding this staggered view... 7 | 8 | ![ScreenShot](images/android_staggeredview.png) 9 | 10 | # Quick introduction 11 | 12 | In order to use StaggeredView you should be familar with the StaggeredView basic concepts, this enables you to easily extend the component to suit your needs…so let's get started! 13 | 14 | There are three different "row" combinations which can occur within the StaggeredView component. A row is one/several images grouped horizontally…see picture below: 15 | 16 | ![ScreenShot](images/android_staggeredview03.png) 17 | 18 | Within a row three different layouts might occurs: a large image only, two small images and a medium sized image (left) or a medium image followed by two small images, see image below: 19 | 20 | ![ScreenShot](images/android_staggeredview01.png) 21 | 22 | # Embed StaggeredView 23 | 24 | As already said, currently Android Studio and library/module usage is pain in the ass…so my recommendation: simply download this project from git, embed the project locally into your Android Studio and start copying the important parts to the project you wanna use StaggeredView. StaggeredView has been deisgned as a fragment component so there isn't that much copy pasting ;-) The nice thing about downloading the whole project: you have an "up&running" version in your workspace which you can use for experiments, modifications etc… 25 | 26 | ## Prepare your project 27 | 28 | As already said, StaggeredView is a fragment component - so all you need to copy into your project in a first step is the layout file (layout/fragment_staggered_view.xml, paste it into your layout folder…) and the corresponding Java class java/com.jooik.staggeredview.frags.FragmentStaggeredView.java). 29 | 30 | Copy these items to your project and Android will start complaining about missing class files etc., in order to fix these issues of course you need the fragment "business logic", therefore copy&paste the whole java/com.jooik.staggeredview.util package into your project. 31 | 32 | Nearly done. In case you wanna use our wonderful cheese images & sentico fonts you should copy main/assets and the drawable-xxhdpi cheese….png files to your project as well. 33 | 34 | Below I have pasted a screenie chalking out all required copy&paste parts: 35 | 36 | ![ScreenShot](images/android_staggeredview02.png) 37 | 38 | ## Embed StaggeredView 39 | 40 | We expect that you are familar with the concepts of embedding fragments into an application…StaggeredView is embedded programmatically, you can do this for example within the **onCreate** method of your MainActivity: 41 | 42 | ```java 43 | public class MainActivity extends ActionBarActivity { 44 | 45 | @Override 46 | protected void onCreate(Bundle savedInstanceState) { 47 | super.onCreate(savedInstanceState); 48 | setContentView(R.layout.activity_main); 49 | 50 | FragmentStaggeredView staggeredViewFragment = new FragmentStaggeredView(); 51 | staggeredViewFragment.setItems(initItems()); 52 | staggeredViewFragment.setPadding(15); 53 | staggeredViewFragment.setBackgroundColor("#000000"); 54 | staggeredViewFragment.setAvoidDuplicateRandomLayouts(true); 55 | 56 | if (savedInstanceState == null) { 57 | getSupportFragmentManager().beginTransaction() 58 | .add(R.id.container, staggeredViewFragment) 59 | .commit(); 60 | } 61 | } 62 | … 63 | ``` 64 | 65 | So what's happening here? Pretty simple…the FragmentStaggeredView is initialized and added to the activity window, there are several global parameters which can be passed to the staggered view in order to control it's look & feel. The *initItems()* method will be explained in a next steps as this is data generation for the StaggeredView. 66 | 67 | Of course there need to be certain rules enabling you to populate StaggeredView with your own data, StaggeredView items simply need to implement the ISquareItem interface which enables items to define their look and feel. So all you need to do in order to render your own items is passing a list of items implementing the ISquareItem interface…below there is a demo snippet of creating a list of items: 68 | 69 | ```java 70 | /** 71 | * Generate some demo items... 72 | * @return 73 | */ 74 | private List initItems() 75 | { 76 | Typeface face = Typeface.createFromAsset(getAssets(), 77 | "fonts/SignPainter_HouseScript.ttf"); 78 | 79 | int font_large = 35; 80 | int font_medium = 28; 81 | int font_small = 20; 82 | int font_color = Color.WHITE; 83 | ShadowProperties shadowProperties = new ShadowProperties(30,0,0,Color.BLACK); 84 | 85 | List items = new ArrayList(); 86 | SquareItem sq1 = new SquareItem("Alm-Käse",R.drawable.cheese_almkaese); 87 | sq1.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 88 | items.add(sq1); 89 | SquareItem sq2 = new SquareItem("Appenzeller",R.drawable.cheese_appenzeller); 90 | sq2.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 91 | items.add(sq2); 92 | SquareItem sq3 = new SquareItem("Aragon",R.drawable.cheese_aragon); 93 | sq3.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 94 | items.add(sq3); 95 | SquareItem sq4 = new SquareItem("Asiago",R.drawable.cheese_asiago); 96 | sq4.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 97 | items.add(sq4); 98 | SquareItem sq5 = new SquareItem("Banon",R.drawable.cheese_banon); 99 | sq5.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 100 | items.add(sq5); 101 | SquareItem sq6 = new SquareItem("Bavariablu",R.drawable.cheese_bavariablu); 102 | sq6.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 103 | items.add(sq6); 104 | SquareItem sq7 = new SquareItem("Beaufort",R.drawable.cheese_beaufort); 105 | sq7.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 106 | items.add(sq7); 107 | SquareItem sq8 = new SquareItem("Belpaese",R.drawable.cheese_belpaese); 108 | sq8.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 109 | items.add(sq8); 110 | SquareItem sq9 = new SquareItem("Bergader Edelpilz",R.drawable.cheese_bergader_edelpilz); 111 | sq9.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 112 | items.add(sq9); 113 | SquareItem sq10 = new SquareItem("Bergkäse",R.drawable.cheese_bergkaese); 114 | sq10.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 115 | items.add(sq10); 116 | 117 | return items; 118 | } 119 | ``` 120 | 121 | ## Go Code! 122 | 123 | Ok, basically that's all you need to know about StaggeredList - of course there is some more brain power behind StaggeredView, for example influencing random generation of row layouts etc. but that's documented pretty well in the Code so simply export JavaDoc and you should be able to dive into the magic of StaggeredView… ;-) 124 | 125 | Have Fun! 126 | 127 | [![Image](images/twitter.png "Image title") ](https://twitter.com/_flomueller "Twitter") 128 | -------------------------------------------------------------------------------- /StaggeredView.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 20 | 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 | -------------------------------------------------------------------------------- /StaggeredView/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /StaggeredView/StaggeredView-StaggeredView.iml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /StaggeredView/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:0.6.+' 7 | } 8 | } 9 | apply plugin: 'android' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | android { 16 | compileSdkVersion 18 17 | buildToolsVersion "18.1.1" 18 | 19 | defaultConfig { 20 | minSdkVersion 11 21 | targetSdkVersion 19 22 | } 23 | buildTypes { 24 | release { 25 | runProguard true 26 | proguardFile getDefaultProguardFile('proguard-android-optimize.txt') 27 | } 28 | } 29 | productFlavors { 30 | defaultFlavor { 31 | proguardFile 'proguard-rules.txt' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | compile 'com.android.support:appcompat-v7:+' 38 | } 39 | -------------------------------------------------------------------------------- /StaggeredView/proguard-rules.txt: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the ProGuard 5 | # include property in project.properties. 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 | #} -------------------------------------------------------------------------------- /StaggeredView/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /StaggeredView/src/main/assets/fonts/SignPainter_HouseScript.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/assets/fonts/SignPainter_HouseScript.ttf -------------------------------------------------------------------------------- /StaggeredView/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /StaggeredView/src/main/java/com/jooik/staggeredview/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.jooik.staggeredview; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.Typeface; 5 | import android.os.Bundle; 6 | import android.support.v7.app.ActionBarActivity; 7 | import android.view.Menu; 8 | import android.view.MenuItem; 9 | 10 | import com.jooik.staggeredview.frags.FragmentStaggeredView; 11 | import com.jooik.staggeredview.util.ISquareItem; 12 | import com.jooik.staggeredview.util.ShadowProperties; 13 | import com.jooik.staggeredview.util.SquareItem; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | public class MainActivity extends ActionBarActivity { 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_main); 24 | 25 | FragmentStaggeredView staggeredViewFragment = new FragmentStaggeredView(); 26 | staggeredViewFragment.setItems(initItems()); 27 | staggeredViewFragment.setPadding(15); 28 | staggeredViewFragment.setBackgroundColor("#000000"); 29 | staggeredViewFragment.setAvoidDuplicateRandomLayouts(true); 30 | 31 | if (savedInstanceState == null) { 32 | getSupportFragmentManager().beginTransaction() 33 | .add(R.id.container, staggeredViewFragment) 34 | .commit(); 35 | } 36 | } 37 | 38 | 39 | @Override 40 | public boolean onCreateOptionsMenu(Menu menu) { 41 | 42 | // Inflate the menu; this adds items to the action bar if it is present. 43 | getMenuInflater().inflate(R.menu.main, menu); 44 | return true; 45 | } 46 | 47 | @Override 48 | public boolean onOptionsItemSelected(MenuItem item) { 49 | // Handle action bar item clicks here. The action bar will 50 | // automatically handle clicks on the Home/Up button, so long 51 | // as you specify a parent activity in AndroidManifest.xml. 52 | switch (item.getItemId()) { 53 | case R.id.action_settings: 54 | return true; 55 | } 56 | return super.onOptionsItemSelected(item); 57 | } 58 | 59 | // ------------------------------------------------------------------------ 60 | // private usage 61 | // ------------------------------------------------------------------------ 62 | 63 | /** 64 | * Generate some demo items... 65 | * @return 66 | */ 67 | private List initItems() 68 | { 69 | Typeface face = Typeface.createFromAsset(getAssets(), 70 | "fonts/SignPainter_HouseScript.ttf"); 71 | 72 | int font_large = 35; 73 | int font_medium = 28; 74 | int font_small = 20; 75 | int font_color = Color.WHITE; 76 | ShadowProperties shadowProperties = new ShadowProperties(30,0,0,Color.BLACK); 77 | 78 | List items = new ArrayList(); 79 | SquareItem sq1 = new SquareItem("Alm-Käse",R.drawable.cheese_almkaese); 80 | sq1.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 81 | items.add(sq1); 82 | SquareItem sq2 = new SquareItem("Appenzeller",R.drawable.cheese_appenzeller); 83 | sq2.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 84 | items.add(sq2); 85 | SquareItem sq3 = new SquareItem("Aragon",R.drawable.cheese_aragon); 86 | sq3.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 87 | items.add(sq3); 88 | SquareItem sq4 = new SquareItem("Asiago",R.drawable.cheese_asiago); 89 | sq4.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 90 | items.add(sq4); 91 | SquareItem sq5 = new SquareItem("Banon",R.drawable.cheese_banon); 92 | sq5.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 93 | items.add(sq5); 94 | SquareItem sq6 = new SquareItem("Bavariablu",R.drawable.cheese_bavariablu); 95 | sq6.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 96 | items.add(sq6); 97 | SquareItem sq7 = new SquareItem("Beaufort",R.drawable.cheese_beaufort); 98 | sq7.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 99 | items.add(sq7); 100 | SquareItem sq8 = new SquareItem("Belpaese",R.drawable.cheese_belpaese); 101 | sq8.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 102 | items.add(sq8); 103 | SquareItem sq9 = new SquareItem("Bergader Edelpilz",R.drawable.cheese_bergader_edelpilz); 104 | sq9.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 105 | items.add(sq9); 106 | SquareItem sq10 = new SquareItem("Bergkäse",R.drawable.cheese_bergkaese); 107 | sq10.applyFontStyle(font_large,font_medium,font_small,face,font_color,shadowProperties); 108 | items.add(sq10); 109 | 110 | return items; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /StaggeredView/src/main/java/com/jooik/staggeredview/frags/FragmentStaggeredView.java: -------------------------------------------------------------------------------- 1 | package com.jooik.staggeredview.frags; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.util.DisplayMetrics; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.FrameLayout; 11 | import android.widget.ImageView; 12 | import android.widget.LinearLayout; 13 | import android.widget.RelativeLayout; 14 | import android.widget.TextView; 15 | 16 | import com.jooik.staggeredview.R; 17 | import com.jooik.staggeredview.util.ISquareItem; 18 | import com.jooik.staggeredview.util.SquareType; 19 | 20 | import java.util.List; 21 | import java.util.Random; 22 | 23 | /** 24 | * Setup staggered view... 25 | */ 26 | public class FragmentStaggeredView extends Fragment 27 | { 28 | // ------------------------------------------------------------------------ 29 | // members 30 | // ------------------------------------------------------------------------ 31 | 32 | // data 33 | private List items; 34 | 35 | // padding (="border frames" displayed between the items...) 36 | private int padding = 15; 37 | 38 | private String backgroundColor = "#000000"; 39 | 40 | // it might be necessary to get a really "mixed" view, random does not 41 | // guarantee so... 42 | private boolean avoidDuplicateRandomLayouts = false; 43 | 44 | // ------------------------------------------------------------------------ 45 | // interface implementation 46 | // ------------------------------------------------------------------------ 47 | 48 | @Override 49 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 50 | { 51 | View view = inflater.inflate(R.layout.fragment_staggered_view,container,false); 52 | LinearLayout llFrame = (LinearLayout)view.findViewById(R.id.ll_frame); 53 | 54 | // apply layout properties (color etc.) 55 | llFrame.setBackgroundColor(Color.parseColor(backgroundColor)); 56 | 57 | // required for dynamic width/height calculations 58 | DisplayMetrics metrics = new DisplayMetrics(); 59 | getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); 60 | int height = metrics.heightPixels; 61 | int width = metrics.widthPixels; 62 | 63 | // layout helper.... 64 | LinearLayout outerBox = null; 65 | LinearLayout innerBox = null; 66 | boolean doubleBoxInTheLeft = false; 67 | GridCreationState creationState = GridCreationState.START_NEW_ROW; 68 | RowStyle rowStyle = null; 69 | 70 | for (ISquareItem item : items) 71 | { 72 | // create new row in layout and randomly generate the first item 73 | // which the will be added to the row. The first tem determines all 74 | // further layout steps for this row... 75 | if (creationState == GridCreationState.START_NEW_ROW) 76 | { 77 | Random random = new Random(); 78 | int randomInt = random.nextInt(3-0); 79 | SquareType squareType = translateRandomIdToSquareType(randomInt); 80 | RowStyle newRowStyle = translateRandomIdToRowLayoutEnum(randomInt); 81 | 82 | // avoid row style series with the same layout... 83 | if (avoidDuplicateRandomLayouts && rowStyle != null) 84 | { 85 | while (newRowStyle == rowStyle) 86 | { 87 | randomInt = random.nextInt(3-0); 88 | squareType = translateRandomIdToSquareType(randomInt); 89 | newRowStyle = translateRandomIdToRowLayoutEnum(randomInt); 90 | } 91 | } 92 | 93 | // add outer layoutbox... 94 | outerBox = new LinearLayout(view.getContext()); 95 | outerBox.setOrientation(LinearLayout.HORIZONTAL); 96 | 97 | LinearLayout.LayoutParams boxParams = new LinearLayout.LayoutParams(width, height/3); 98 | outerBox.setLayoutParams(boxParams); 99 | 100 | // first box deserves "special" handling regarding padding... 101 | if (item.equals(items.get(0))) 102 | { 103 | outerBox.setPadding(padding,padding,padding,padding); 104 | } 105 | else 106 | { 107 | outerBox.setPadding(padding,0,padding,padding); 108 | } 109 | llFrame.addView(outerBox); 110 | 111 | switch (squareType) 112 | { 113 | case LARGE_ITEM: 114 | { 115 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, height/3); 116 | RelativeLayout rl = new RelativeLayout(view.getContext()); 117 | rl.setLayoutParams(layoutParams); 118 | 119 | ImageView iv = initImage(item); 120 | TextView tv = initText(SquareType.LARGE_ITEM,item); 121 | rl.addView(iv); 122 | rl.addView(tv); 123 | 124 | outerBox.addView(rl); 125 | creationState = GridCreationState.START_NEW_ROW; 126 | rowStyle = RowStyle.LARGE_ONLY; 127 | break; 128 | } 129 | case MEDIUM_ITEM: 130 | { 131 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width/3*2, height/3); 132 | RelativeLayout rl = new RelativeLayout(view.getContext()); 133 | rl.setLayoutParams(layoutParams); 134 | 135 | ImageView iv = initImage(item); 136 | TextView tv = initText(SquareType.MEDIUM_ITEM,item); 137 | rl.addView(iv); 138 | rl.addView(tv); 139 | 140 | outerBox.addView(rl); 141 | creationState = GridCreationState.ADDED_MEDIUM; 142 | rowStyle = RowStyle.MEDIUM_SMALL_SMALL; 143 | break; 144 | } 145 | case SMALL_ITEM: 146 | { 147 | doubleBoxInTheLeft = true; 148 | 149 | // add inner layoutbox... 150 | innerBox = new LinearLayout(view.getContext()); 151 | innerBox.setOrientation(LinearLayout.VERTICAL); 152 | innerBox.setPadding(0,0,padding,0); 153 | boxParams = new LinearLayout.LayoutParams(width/3, height/3); 154 | innerBox.setLayoutParams(boxParams); 155 | outerBox.addView(innerBox); 156 | 157 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width/3, height/3/2); 158 | RelativeLayout rl = new RelativeLayout(view.getContext()); 159 | rl.setLayoutParams(layoutParams); 160 | 161 | ImageView iv = initImage(item); 162 | TextView tv = initText(SquareType.SMALL_ITEM,item); 163 | rl.addView(iv); 164 | rl.addView(tv); 165 | innerBox.addView(rl); 166 | 167 | creationState = GridCreationState.ADDED_SMALL_TOP_LEFT; 168 | rowStyle = RowStyle.SMALL_SMALL_MEDIUM; 169 | break; 170 | } 171 | } 172 | } 173 | 174 | else 175 | { 176 | switch (creationState) 177 | { 178 | case ADDED_MEDIUM: 179 | { 180 | // add inner layoutbox... 181 | innerBox = new LinearLayout(view.getContext()); 182 | innerBox.setOrientation(LinearLayout.VERTICAL); 183 | innerBox.setPadding(padding,0,0,0); 184 | LinearLayout.LayoutParams boxParams = new LinearLayout.LayoutParams(width/3, height/3); 185 | innerBox.setLayoutParams(boxParams); 186 | outerBox.addView(innerBox); 187 | 188 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width/3, height/3/2); 189 | RelativeLayout rl = new RelativeLayout(view.getContext()); 190 | rl.setLayoutParams(layoutParams); 191 | 192 | ImageView iv = initImage(item); 193 | TextView tv = initText(SquareType.SMALL_ITEM,item); 194 | rl.addView(iv); 195 | rl.addView(tv); 196 | innerBox.addView(rl); 197 | 198 | creationState = GridCreationState.ADDED_SMALL_TOP_RIGHT; 199 | break; 200 | } 201 | case ADDED_SMALL_TOP_RIGHT: 202 | { 203 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width/3, height/3/2); 204 | RelativeLayout rl = new RelativeLayout(view.getContext()); 205 | rl.setLayoutParams(layoutParams); 206 | rl.setPadding(0,padding,0,0); 207 | 208 | ImageView iv = initImage(item); 209 | TextView tv = initText(SquareType.SMALL_ITEM,item); 210 | rl.addView(iv); 211 | rl.addView(tv); 212 | innerBox.addView(rl); 213 | 214 | creationState = GridCreationState.START_NEW_ROW; 215 | break; 216 | } 217 | case ADDED_SMALL_TOP_LEFT: 218 | { 219 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width/3, height/3/2); 220 | RelativeLayout rl = new RelativeLayout(view.getContext()); 221 | rl.setLayoutParams(layoutParams); 222 | rl.setPadding(0, padding, 0, 0); 223 | 224 | ImageView iv = initImage(item); 225 | TextView tv = initText(SquareType.SMALL_ITEM,item); 226 | rl.addView(iv); 227 | rl.addView(tv); 228 | innerBox.addView(rl); 229 | 230 | creationState = GridCreationState.ADDED_SMALL_BOTTOM_LEFT; 231 | break; 232 | } 233 | case ADDED_SMALL_BOTTOM_LEFT: 234 | { 235 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width/3*2, height/3); 236 | RelativeLayout rl = new RelativeLayout(view.getContext()); 237 | rl.setLayoutParams(layoutParams); 238 | 239 | ImageView iv = initImage(item); 240 | TextView tv = initText(SquareType.MEDIUM_ITEM,item); 241 | rl.addView(iv); 242 | rl.addView(tv); 243 | outerBox.addView(rl); 244 | 245 | creationState = GridCreationState.START_NEW_ROW; 246 | break; 247 | } 248 | } 249 | } 250 | } 251 | 252 | return view; 253 | } 254 | 255 | // ------------------------------------------------------------------------ 256 | // private usage 257 | // ------------------------------------------------------------------------ 258 | 259 | /** 260 | * Setup an image square which can be added to the layout in a central way...that's the reason 261 | * this method has been created. 262 | * @param item 263 | * @return 264 | */ 265 | private ImageView initImage(ISquareItem item) 266 | { 267 | FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 268 | FrameLayout.LayoutParams.MATCH_PARENT); 269 | ImageView iv = new ImageView(getActivity()); 270 | iv.setLayoutParams(params); 271 | iv.setImageResource(item.getImage()); 272 | iv.setScaleType(ImageView.ScaleType.CENTER_CROP); 273 | 274 | return iv; 275 | } 276 | 277 | private TextView initText(SquareType squareType, 278 | ISquareItem item) 279 | { 280 | // apply properties set within the square properties 281 | // (each square know how it should look like! approach) 282 | TextView tv = new TextView(getActivity()); 283 | tv.setText(item.getTitle()); 284 | tv.setTypeface(item.getFont(squareType)); 285 | tv.setTextColor(item.getFontColor(squareType)); 286 | tv.setShadowLayer(item.getShadowProperties(squareType).getRadius(), 287 | item.getShadowProperties(squareType).getDx(), 288 | item.getShadowProperties(squareType).getDy(), 289 | item.getShadowProperties(squareType).getColor()); 290 | tv.setTextSize(item.getFontSize(squareType)); 291 | 292 | LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 293 | LinearLayout.LayoutParams.WRAP_CONTENT); 294 | tv.setLayoutParams(param); 295 | tv.setPadding(10,10,10,10); 296 | 297 | return tv; 298 | } 299 | 300 | /** 301 | * Translate a random ID to the corresponding enum layout type...smarter reading... 302 | * @param randomID 303 | * @return 304 | */ 305 | private SquareType translateRandomIdToSquareType(int randomID) 306 | { 307 | switch (randomID) 308 | { 309 | case 0: return SquareType.LARGE_ITEM; 310 | case 1: return SquareType.MEDIUM_ITEM; 311 | case 2: return SquareType.SMALL_ITEM; 312 | } 313 | 314 | return null; 315 | } 316 | 317 | /** 318 | * Translate a random ID to the corresponding enum layout type...smarter reading... 319 | * @param randomID 320 | * @return 321 | */ 322 | private RowStyle translateRandomIdToRowLayoutEnum(int randomID) 323 | { 324 | switch (randomID) 325 | { 326 | case 0: return RowStyle.LARGE_ONLY; 327 | case 1: return RowStyle.MEDIUM_SMALL_SMALL; 328 | case 2: return RowStyle.SMALL_SMALL_MEDIUM; 329 | } 330 | 331 | return null; 332 | } 333 | 334 | // ------------------------------------------------------------------------ 335 | // GETTER & SETTER 336 | // ------------------------------------------------------------------------ 337 | 338 | public List getItems() 339 | { 340 | return items; 341 | } 342 | 343 | /** 344 | * Provide data items for the staggered list... 345 | * @param items 346 | */ 347 | public void setItems(List items) 348 | { 349 | this.items = items; 350 | } 351 | 352 | public int getPadding() 353 | { 354 | return padding; 355 | } 356 | 357 | /** 358 | * Set padding (default=15dp) 359 | * @param padding 360 | */ 361 | public void setPadding(int padding) 362 | { 363 | this.padding = padding; 364 | } 365 | 366 | public String getBackgroundColor() 367 | { 368 | return backgroundColor; 369 | } 370 | 371 | /** 372 | * Set background color as RGB (default=#000000=black). Passing 373 | * in color string ("red","green" etc.) will work as well in case 374 | * you dont wanna fire up a color hex translator ;-) 375 | * @param backgroundColor 376 | */ 377 | public void setBackgroundColor(String backgroundColor) 378 | { 379 | this.backgroundColor = backgroundColor; 380 | } 381 | 382 | public boolean getAvoidDuplicateRandomLayouts() 383 | { 384 | return avoidDuplicateRandomLayouts; 385 | } 386 | 387 | /** 388 | * Default = false => real random reuslt...the problem with 100% random results: 389 | * layouts might occure twice/tripple etc. so the layout look "regular" instead 390 | * of mixed. This flag can be used to avoid duplicate row types series, setting 391 | * this flag to true results in a check which ensures the next row looks 100%ly 392 | * different to the previous one... 393 | * @param avoidDuplicateRandomLayouts 394 | */ 395 | public void setAvoidDuplicateRandomLayouts(boolean avoidDuplicateRandomLayouts) 396 | { 397 | this.avoidDuplicateRandomLayouts = avoidDuplicateRandomLayouts; 398 | } 399 | // ------------------------------------------------------------------------ 400 | // others 401 | // ------------------------------------------------------------------------ 402 | 403 | /** 404 | * The different staggerd row layouts. 405 | */ 406 | public enum RowStyle 407 | { 408 | LARGE_ONLY,SMALL_SMALL_MEDIUM,MEDIUM_SMALL_SMALL; 409 | } 410 | 411 | /** 412 | * Different stages the UI might traverse while creating the UI programmatically. 413 | * Smarter than dealing with state 1,2,3.... 414 | */ 415 | public enum GridCreationState 416 | { 417 | ADDED_MEDIUM,ADDED_SMALL_TOP_RIGHT,ADDED_SMALL_TOP_LEFT,ADDED_SMALL_BOTTOM_LEFT, START_NEW_ROW; 418 | } 419 | } -------------------------------------------------------------------------------- /StaggeredView/src/main/java/com/jooik/staggeredview/util/ISquareItem.java: -------------------------------------------------------------------------------- 1 | package com.jooik.staggeredview.util; 2 | 3 | import android.graphics.Typeface; 4 | 5 | /** 6 | * An interface definition enabling us to program against while setting up 7 | * a staggered view - each view item within the staggered view NEEDS to implemt 8 | * this interface. 9 | * 10 | * Anything which should be applicable to all of your view items (for example a 11 | * label) will be defined within this definition. 12 | */ 13 | public interface ISquareItem 14 | { 15 | /** 16 | * Get image (R.drawable style...) for the item. 17 | * @return 18 | */ 19 | public int getImage(); 20 | 21 | /** 22 | * Get title for box which the will be displayed within the square image... 23 | * @return 24 | */ 25 | public String getTitle(); 26 | 27 | /** 28 | * Font size for image square...each square should define itself how it 29 | * looks like. As the item might look differently (small, large, medium...) 30 | * this method takes a parameter passing the rendering type into the method, so 31 | * you can finally decide within this method which font size should be used for 32 | * a large/medium/small square. 33 | * @return 34 | */ 35 | public int getFontSize(SquareType squareType); 36 | 37 | /** 38 | * Font used for the labeling within this item. As the item might look differently 39 | * (small, large, medium...) this method takes a parameter passing the rendering type 40 | * into the method, so you can finally decide within this method which font size 41 | * should be used for a large/medium/small square. 42 | * 43 | * Should return -1 in case of unknown SquareType. 44 | * @return 45 | */ 46 | public Typeface getFont(SquareType squareType); 47 | 48 | /** 49 | * Font color used within this item. 50 | * @param squareType 51 | * @return 52 | */ 53 | public int getFontColor(SquareType squareType); 54 | 55 | /** 56 | * Shadow properties for the given item... 57 | * @param squareType 58 | * @return 59 | */ 60 | public ShadowProperties getShadowProperties(SquareType squareType); 61 | } 62 | -------------------------------------------------------------------------------- /StaggeredView/src/main/java/com/jooik/staggeredview/util/ShadowProperties.java: -------------------------------------------------------------------------------- 1 | package com.jooik.staggeredview.util; 2 | 3 | /** 4 | * Contains necessary properties in order to generate a shadow for a 5 | * font. This is just a simple property aggregator... 6 | */ 7 | public class ShadowProperties 8 | { 9 | // ------------------------------------------------------------------------ 10 | // members 11 | // ------------------------------------------------------------------------ 12 | 13 | float radius; 14 | int dx; 15 | int dy; 16 | int color; 17 | 18 | // ------------------------------------------------------------------------ 19 | // constructors 20 | // ------------------------------------------------------------------------ 21 | 22 | public ShadowProperties(float radius,int dx,int dy,int color) 23 | { 24 | this.radius = radius; 25 | this.dx = dx; 26 | this.dy = dy; 27 | this.color = color; 28 | } 29 | 30 | // ------------------------------------------------------------------------ 31 | // GETTER & SETTER 32 | // ------------------------------------------------------------------------ 33 | 34 | public float getRadius() 35 | { 36 | return radius; 37 | } 38 | 39 | public void setRadius(float radius) 40 | { 41 | this.radius = radius; 42 | } 43 | 44 | public int getDx() 45 | { 46 | return dx; 47 | } 48 | 49 | public void setDx(int dx) 50 | { 51 | this.dx = dx; 52 | } 53 | 54 | public int getDy() 55 | { 56 | return dy; 57 | } 58 | 59 | public void setDy(int dy) 60 | { 61 | this.dy = dy; 62 | } 63 | 64 | public int getColor() 65 | { 66 | return color; 67 | } 68 | 69 | public void setColor(int color) 70 | { 71 | this.color = color; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /StaggeredView/src/main/java/com/jooik/staggeredview/util/SquareItem.java: -------------------------------------------------------------------------------- 1 | package com.jooik.staggeredview.util; 2 | 3 | import android.graphics.Typeface; 4 | 5 | /** 6 | * Demo implememtation for a square item which is used within a szaggered 7 | * view... 8 | */ 9 | public class SquareItem 10 | implements ISquareItem 11 | { 12 | // ------------------------------------------------------------------------ 13 | // members 14 | // ------------------------------------------------------------------------ 15 | 16 | private String title; 17 | private int image; 18 | 19 | private Typeface font; 20 | private int fontsize_small; 21 | private int fontsize_medium; 22 | private int fontsize_large; 23 | private int fontColor; 24 | private ShadowProperties shadowProperties; 25 | 26 | // ------------------------------------------------------------------------ 27 | // constructors 28 | // ------------------------------------------------------------------------ 29 | 30 | public SquareItem(String label,int image) 31 | { 32 | this.title = label; 33 | this.image = image; 34 | } 35 | 36 | // ------------------------------------------------------------------------ 37 | // public usage & helpers... 38 | // ------------------------------------------------------------------------ 39 | 40 | public void applyFontStyle(int fontsize_large,int fontsize_medium, 41 | int fontsize_small, Typeface font, int fontColor, 42 | ShadowProperties shadowProperties) 43 | { 44 | this.fontsize_large = fontsize_large; 45 | this.fontsize_medium = fontsize_medium; 46 | this.fontsize_small = fontsize_small; 47 | 48 | this.font = font; 49 | this.fontColor = fontColor; 50 | this.shadowProperties = shadowProperties; 51 | } 52 | 53 | // ------------------------------------------------------------------------ 54 | // GETTER & SETTER 55 | // ------------------------------------------------------------------------ 56 | 57 | @Override 58 | public int getImage() 59 | { 60 | return this.image; 61 | } 62 | 63 | public void setImage(int image) 64 | { 65 | this.image = image; 66 | } 67 | 68 | @Override 69 | public String getTitle() 70 | { 71 | return this.title; 72 | } 73 | 74 | public void setTitle(String title) 75 | { 76 | this.title = title; 77 | } 78 | 79 | @Override 80 | public int getFontSize(SquareType squareType) 81 | { 82 | switch (squareType) 83 | { 84 | case LARGE_ITEM: 85 | return fontsize_large; 86 | case MEDIUM_ITEM: 87 | return fontsize_medium; 88 | case SMALL_ITEM: 89 | return fontsize_small; 90 | } 91 | 92 | return -1; 93 | } 94 | 95 | @Override 96 | public Typeface getFont(SquareType squareType) 97 | { 98 | return this.font; 99 | } 100 | 101 | @Override 102 | public int getFontColor(SquareType squareType) 103 | { 104 | return this.fontColor; 105 | } 106 | 107 | @Override 108 | public ShadowProperties getShadowProperties(SquareType squareType) 109 | { 110 | return this.shadowProperties; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /StaggeredView/src/main/java/com/jooik/staggeredview/util/SquareType.java: -------------------------------------------------------------------------------- 1 | package com.jooik.staggeredview.util; 2 | 3 | /** 4 | * Different "square types" which can occur within a staggered view... 5 | */ 6 | public enum SquareType 7 | { 8 | SMALL_ITEM,MEDIUM_ITEM,LARGE_ITEM; 9 | } 10 | -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_almkaese.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_almkaese.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_appenzeller.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_appenzeller.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_aragon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_aragon.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_asiago.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_asiago.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_banon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_banon.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_bavariablu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_bavariablu.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_beaufort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_beaufort.png -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_belpaese.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_belpaese.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_bergader_edelpilz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_bergader_edelpilz.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/cheese_bergkaese.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/cheese_bergkaese.jpg -------------------------------------------------------------------------------- /StaggeredView/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/StaggeredView/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /StaggeredView/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /StaggeredView/src/main/res/layout/fragment_staggered_view.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 | -------------------------------------------------------------------------------- /StaggeredView/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /StaggeredView/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /StaggeredView/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 7 | -------------------------------------------------------------------------------- /StaggeredView/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | StaggeredView 5 | Hello world! 6 | Settings 7 | 8 | 9 | -------------------------------------------------------------------------------- /StaggeredView/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android_staggered_view.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Set Gradle settings which apply to all modules here. -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 10 15:27:10 PDT 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /images/android_staggeredview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/images/android_staggeredview.png -------------------------------------------------------------------------------- /images/android_staggeredview01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/images/android_staggeredview01.png -------------------------------------------------------------------------------- /images/android_staggeredview02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/images/android_staggeredview02.png -------------------------------------------------------------------------------- /images/android_staggeredview03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/images/android_staggeredview03.png -------------------------------------------------------------------------------- /images/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiteflo/Android_StaggeredView/51f81f1fc5dc3a73992e7d733399ac0a0aacbbe3/images/twitter.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':StaggeredView' 2 | --------------------------------------------------------------------------------