├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── randomlytyping
│ │ └── ccl
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── fonts
│ │ │ └── LeagueGothicRegular.otf
│ ├── java
│ │ ├── com
│ │ │ └── randomlytyping
│ │ │ │ └── ccl
│ │ │ │ ├── AlignmentActivity.kt
│ │ │ │ ├── CCLApplication.kt
│ │ │ │ ├── ChainsActivity.kt
│ │ │ │ ├── CircularConstraintActivity.kt
│ │ │ │ ├── ConstraintSetActivity.kt
│ │ │ │ ├── DimensionRatioActivity.kt
│ │ │ │ ├── DynamicConstraintLayoutActivity.kt
│ │ │ │ ├── ListItemActivity.kt
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── util
│ │ │ │ └── ActivityExtensions.kt
│ │ │ │ └── view
│ │ │ │ └── SquareImageView.kt
│ │ └── rt
│ │ │ └── randamu
│ │ │ ├── ConstraintSetExtensions.kt
│ │ │ ├── ResourcesExtensions.kt
│ │ │ └── ViewDrawableExtensions.kt
│ └── res
│ │ ├── drawable-xxhdpi
│ │ ├── lina_dragon_slave.png
│ │ ├── lina_fiery_soul.png
│ │ ├── lina_laguna_blade.png
│ │ ├── lina_light_strike_array.png
│ │ ├── lina_mcbeamish.jpg
│ │ ├── overviewicon_agi.png
│ │ ├── overviewicon_int.png
│ │ └── overviewicon_str.png
│ │ ├── drawable-xxxhdpi
│ │ ├── unsplash_caspar_rubin_macbook_sql.jpg
│ │ ├── unsplash_cory_seward_eggs.jpg
│ │ ├── unsplash_danielle_macinnes_artichokes.jpg
│ │ ├── unsplash_julia_d_alkmin_ice_tea.jpg
│ │ ├── unsplash_maria_fernanda_gonzalez_coffee.jpg
│ │ ├── unsplash_michal_grosicki_glitter.jpg
│ │ ├── unsplash_mike_kenneally_green_beans.jpg
│ │ ├── unsplash_neven_krcmarek_grapes.jpg
│ │ ├── unsplash_nousnou_iwasaki_coffee_beans.jpg
│ │ ├── unsplash_oreo_cream.jpg
│ │ ├── unsplash_roberta_sorge_honey.jpg
│ │ ├── unsplash_roberta_sorge_pineapple.jpg
│ │ ├── unsplash_roberta_sorge_pomegranate.jpg
│ │ ├── unsplash_shumilov_ludmila_pears.jpg
│ │ ├── unsplash_tamarcus_brown_ruler.jpg
│ │ └── unsplash_tatiana_lapina_macaroon.jpg
│ │ ├── drawable
│ │ ├── ic_android_black_24dp.xml
│ │ ├── ic_arrow_back_black_24dp.xml
│ │ ├── ic_arrow_downward_black_24dp.xml
│ │ ├── ic_arrow_forward_black_24dp.xml
│ │ ├── ic_arrow_upward_black_24dp.xml
│ │ ├── ic_circle_black_24dp.xml
│ │ ├── ic_dot_black_24dp.xml
│ │ ├── ic_favorite_black_24dp.xml
│ │ ├── ic_fire_black_24dp.xml
│ │ ├── ic_format_align_left_black_24dp.xml
│ │ ├── ic_image_aspect_ratio_black_24dp.xml
│ │ ├── ic_link_black_24dp.xml
│ │ ├── ic_list_black_24dp.xml
│ │ ├── ic_snowflake_black_24dp.xml
│ │ ├── ic_spa_black_24dp.xml
│ │ ├── ic_stop_black_24dp.xml
│ │ ├── ic_swap_horiz_black_24dp.xml
│ │ ├── ic_view_list_black_24dp.xml
│ │ ├── ic_widgets_black_24dp.xml
│ │ └── rect_stroke_grey.xml
│ │ ├── layout
│ │ ├── activity_container_linear_layout.xml
│ │ ├── activity_container_scroll_view.xml
│ │ ├── activity_main.xml
│ │ ├── content_alignment.xml
│ │ ├── content_chains.xml
│ │ ├── content_circular_constraint.xml
│ │ ├── content_constraintset_01.xml
│ │ ├── content_constraintset_02.xml
│ │ ├── content_constraintset_02_buggy.xml
│ │ ├── content_dimension_ratio.xml
│ │ ├── content_dynamic_constraint_layout.xml
│ │ ├── content_recycler_view.xml
│ │ ├── layout_constraints_basic.xml
│ │ ├── layout_dynamic_image.xml
│ │ ├── layout_dynamic_text.xml
│ │ ├── layout_guidelines.xml
│ │ ├── list_item_example.xml
│ │ ├── list_item_unsplash.xml
│ │ └── list_item_unsplash_expanded.xml
│ │ ├── menu
│ │ └── constraint_set.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-land
│ │ └── dimens.xml
│ │ ├── values-sw600dp
│ │ └── dimens.xml
│ │ ├── values-v21
│ │ └── styles.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── examples.xml
│ │ ├── ids.xml
│ │ ├── items.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── themes.xml
│ └── test
│ └── java
│ └── com
│ └── randomlytyping
│ └── ccl
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/README.md:
--------------------------------------------------------------------------------
1 | ## Cool ConstraintLayout
2 | Examples from my talk "Cool ConstraintLayout" which gives examples of interesting things to do with `ConstraintLayout` using its unique features.
3 |
4 | ## Examples
5 |
6 | ### Dimension Ratio
7 |
8 | ### Alignment
9 |
10 | ### Chains
11 |
12 | ### ConstraintSet
13 |
14 | ### ConstraintLayout List Item
15 |
16 | ### Dynamic ConstraintLayout
17 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 |
5 | ext.versions = [
6 | // Android
7 | targetSdkVersion : 26,
8 | minSdkVersion : 21,
9 | buildtools : "26.0.2",
10 | support : "27.0.0",
11 |
12 | // Components
13 | constraintlayout : "1.1.0-beta3",
14 |
15 | // Logging
16 | timber : "4.5.1",
17 |
18 | // UI
19 | calligraphy : "2.3.0",
20 |
21 | // Utility
22 | butterknife : "8.8.1",
23 | kotterknife : "0.1.0-SNAPSHOT"
24 | ]
25 |
26 | def versionMajor = 0
27 | def versionMinor = 1
28 | def versionPatch = 0
29 | def versionBuild = 0
30 |
31 |
32 | android {
33 | compileSdkVersion versions.targetSdkVersion
34 | buildToolsVersion versions.buildtools
35 | defaultConfig {
36 | applicationId "com.randomlytyping.ccl"
37 | minSdkVersion versions.minSdkVersion
38 | targetSdkVersion versions.targetSdkVersion
39 | versionCode versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
40 | versionName "${versionMajor}.${versionMinor}.${versionPatch}"
41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
42 |
43 | vectorDrawables.useSupportLibrary = true
44 | }
45 | buildTypes {
46 | release {
47 | minifyEnabled false
48 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
49 | }
50 | }
51 | }
52 |
53 | dependencies {
54 | implementation fileTree(dir: 'libs', include: ['*.jar'])
55 |
56 | // Android
57 | implementation "com.android.support:support-v4:$versions.support"
58 | implementation "com.android.support:appcompat-v7:$versions.support"
59 | implementation "com.android.support:design:$versions.support"
60 | implementation "com.android.support:support-annotations:$versions.support"
61 |
62 | // Components
63 | implementation "com.android.support.constraint:constraint-layout:$versions.constraintlayout"
64 | implementation "com.android.support:cardview-v7:$versions.support"
65 |
66 | // Kotlin
67 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
68 |
69 | // Logging
70 | implementation "com.jakewharton.timber:timber:$versions.timber"
71 |
72 | // UI
73 | implementation "uk.co.chrisjenx:calligraphy:$versions.calligraphy"
74 |
75 | // Utility
76 | implementation "com.jakewharton:kotterknife:$versions.kotterknife"
77 |
78 | // Testing
79 | androidTestImplementation ('com.android.support.test.espresso:espresso-core:2.2.2', {
80 | exclude group: 'com.android.support', module: 'support-annotations'
81 | })
82 | testImplementation 'junit:junit:4.12'
83 | }
84 |
--------------------------------------------------------------------------------
/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/huyen/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 |
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/randomlytyping/ccl/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl;
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.randomlytyping.ccl", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
27 |
31 |
35 |
39 |
43 |
47 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/LeagueGothicRegular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/assets/fonts/LeagueGothicRegular.otf
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/AlignmentActivity.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.os.Bundle
4 | import android.support.annotation.IdRes
5 | import android.support.constraint.ConstraintLayout
6 | import android.support.v4.content.ContextCompat
7 | import android.support.v7.app.AppCompatActivity
8 | import android.transition.TransitionManager
9 | import android.view.LayoutInflater
10 | import android.view.View
11 | import android.view.ViewGroup
12 | import android.widget.RadioButton
13 | import android.widget.RadioGroup
14 | import android.widget.SeekBar
15 | import com.randomlytyping.ccl.util.setUpAppBar
16 | import kotterknife.bindView
17 | import kotterknife.bindViews
18 | import rt.randamu.tintBackground
19 | import rt.randamu.toConstraintSet
20 | import rt.randamu.update
21 |
22 | /**
23 | * Examples of ways to leverage edge constraints to do interesting/useful component alignment.
24 | */
25 | class AlignmentActivity : AppCompatActivity() {
26 |
27 | //region // Properties
28 | private val anchorViewIds =
29 | arrayOf(R.id.anchor_top, R.id.anchor_bottom, R.id.anchor_start, R.id.anchor_end)
30 |
31 | // Views
32 | private val constraintLayout by bindView(R.id.constraint_layout)
33 | private val ratioGroup by bindView(R.id.ratio_group)
34 | private val seekBar by bindView(R.id.seek_bar)
35 | private val allAnchors by bindViews(
36 | R.id.anchor_top, R.id.anchor_bottom,
37 | R.id.anchor_start, R.id.anchor_end,
38 | R.id.manual_anchor_top, R.id.manual_anchor_bottom,
39 | R.id.manual_anchor_start, R.id.manual_anchor_end
40 | )
41 | private val manualAnchorTop by bindView(R.id.manual_anchor_top)
42 | private val manualAnchorBottom by bindView(R.id.manual_anchor_bottom)
43 | private val manualAnchorStart by bindView(R.id.manual_anchor_start)
44 | private val manualAnchorEnd by bindView(R.id.manual_anchor_end)
45 |
46 | // Resources
47 | private val anchorMinSize by lazy { resources.getDimensionPixelSize(R.dimen.alignment_anchor_min_size) }
48 | private val anchorMarginHorizontal by lazy { resources.getDimensionPixelSize(R.dimen.content_margin_horizontal) }
49 | private val anchorMarginVertical by lazy { resources.getDimensionPixelSize(R.dimen.alignment_rectangle_margin_vertical) }
50 |
51 | // Constraints
52 |
53 | // A ConstraintSet that can be updated and applied to the current layout.
54 | private val constraintSet by lazy { constraintLayout.toConstraintSet() }
55 |
56 | //endregion
57 |
58 | //region // Activity lifecycle
59 |
60 | override fun onCreate(savedInstanceState: Bundle?) {
61 | super.onCreate(savedInstanceState)
62 | setContentView(R.layout.activity_container_scroll_view)
63 |
64 | // Inflate content and bind views.
65 | LayoutInflater.from(this@AlignmentActivity).inflate(R.layout.content_alignment, findViewById(R.id.scroll_view))
66 |
67 | setUpAppBar()
68 |
69 | // Set up anchor views.
70 | for (i in 0 until allAnchors.size) {
71 | allAnchors[i].tintBackground(ContextCompat.getColor(this, R.color.colorAccent))
72 | }
73 | updateManualAnchors()
74 |
75 | // Set up seek bar to scale up/down size of the anchors.
76 | seekBar.run {
77 | max = resources.getDimensionPixelSize(R.dimen.alignment_anchor_max_size) - anchorMinSize
78 | setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
79 | override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
80 | updateConstraintAnchors()
81 | updateManualAnchors()
82 | }
83 |
84 | override fun onStartTrackingTouch(seekBar: SeekBar) = Unit
85 | override fun onStopTrackingTouch(seekBar: SeekBar) = Unit
86 | })
87 | }
88 |
89 | // Set up ratio radio group and add listener to change dimension ratio of hero image
90 | // when clicked.
91 | ratioGroup.run {
92 | // Set the label text for each RadioButton.
93 | for (i in 0 until childCount) {
94 | (getChildAt(i) as? RadioButton)?.run { text = getDimensionRatio(id) }
95 | }
96 |
97 | // Apply ConstraintSet for each ratio as the radio buttons are checked.
98 | setOnCheckedChangeListener { _, _ -> updateConstraintAnchors(true) }
99 |
100 | // Initialize ConstraintSet.
101 | check(R.id.ratio_01)
102 | }
103 | }
104 |
105 | //endregion
106 |
107 | //region // ConstraintSet updating
108 |
109 | /**
110 | * Updates the size of constraint-positioned anchors.
111 | */
112 | private fun updateConstraintAnchors(transition: Boolean = false) {
113 | if (transition) {
114 | TransitionManager.beginDelayedTransition(constraintLayout)
115 | }
116 |
117 | // Calculate anchor size based on seek bar position.
118 | val anchorSize = anchorMinSize + seekBar.progress
119 |
120 | // Update ConstraintSet and apply to layout.
121 | constraintSet.update(constraintLayout) {
122 | setDimensionRatio(R.id.hero, getDimensionRatio(ratioGroup.checkedRadioButtonId))
123 | for (i in 0 until anchorViewIds.size) {
124 | constrainWidth(anchorViewIds[i], anchorSize)
125 | constrainHeight(anchorViewIds[i], anchorSize)
126 | }
127 | }
128 | }
129 |
130 | /**
131 | * Translate the view ID of a ratio radio button to its corresponding label string.
132 | */
133 | private fun getDimensionRatio(@IdRes id: Int) = getString(when (id) {
134 | R.id.ratio_01 -> R.string.ratio_3_1
135 | R.id.ratio_02 -> R.string.ratio_16_9
136 | R.id.ratio_03 -> R.string.ratio_4_3
137 | else -> R.string.ratio_3_1
138 | })
139 |
140 | //endregion
141 |
142 | //region // Manual anchor updates
143 |
144 | /**
145 | * Update the sizes and margins of all the manually-positioned anchors via layout parameters.
146 | */
147 | private fun updateManualAnchors() {
148 | val size = anchorMinSize + seekBar.progress
149 | val halfSize = Math.round(size * 0.5f)
150 | val horizontalMargin = anchorMarginHorizontal - halfSize
151 | val verticalMargin = anchorMarginVertical - halfSize
152 | updateManualAnchor(manualAnchorTop, size, top = verticalMargin)
153 | updateManualAnchor(manualAnchorBottom, size, bottom = verticalMargin)
154 | updateManualAnchor(manualAnchorStart, size, start = horizontalMargin)
155 | updateManualAnchor(manualAnchorEnd, size, end = horizontalMargin)
156 | }
157 |
158 | /**
159 | * Sets the size and margins for a single manually-positioned anchor.
160 | */
161 | private fun updateManualAnchor(
162 | anchor: View,
163 | size: Int,
164 | top: Int = 0,
165 | bottom: Int = 0,
166 | start: Int = 0,
167 | end: Int = 0
168 | ) {
169 | anchor.layoutParams = (anchor.layoutParams as ViewGroup.MarginLayoutParams).apply {
170 | width = size
171 | height = size
172 | topMargin = top
173 | bottomMargin = bottom
174 | marginStart = start
175 | marginEnd = end
176 | }
177 | }
178 |
179 | // endregion
180 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/CCLApplication.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.app.Application
4 | import timber.log.Timber
5 |
6 | /**
7 | * Custom application class for bootstrapping/setup.
8 | */
9 | class CCLApplication : Application() {
10 | override fun onCreate() {
11 | super.onCreate()
12 |
13 | Timber.plant(Timber.DebugTree())
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/ChainsActivity.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.os.Bundle
4 | import android.support.constraint.ConstraintLayout
5 | import android.support.constraint.ConstraintLayout.LayoutParams.*
6 | import android.support.v7.app.AppCompatActivity
7 | import android.view.LayoutInflater
8 | import android.view.View
9 | import com.randomlytyping.ccl.util.setUpAppBar
10 | import kotterknife.bindView
11 | import rt.randamu.toConstraintSet
12 | import rt.randamu.update
13 |
14 | /**
15 | * Examples of chains including interwoven and chained chains.
16 | */
17 | class ChainsActivity : AppCompatActivity() {
18 |
19 | //region // Properties
20 |
21 | private val constraintLayout by bindView(R.id.constraint_layout)
22 | private val constraintSet by lazy { constraintLayout.toConstraintSet() }
23 |
24 | private var indexVertical = 0
25 | private var indexD = 0
26 |
27 | //endregion
28 |
29 | //region // Activity lifecycle
30 |
31 | override fun onCreate(savedInstanceState: Bundle?) {
32 | super.onCreate(savedInstanceState)
33 | setContentView(R.layout.activity_container_linear_layout)
34 |
35 | // Inflate content and bind views.
36 | LayoutInflater.from(this).inflate(R.layout.content_chains, findViewById(R.id.linear_layout))
37 |
38 | setUpAppBar()
39 |
40 | findViewById(R.id.toggle_vertical).setOnClickListener {
41 | indexVertical = (indexVertical + 1) % CHAIN_STYLE.size
42 | constraintSet.update(constraintLayout) {
43 | setVerticalChainStyle(R.id.text_01, CHAIN_STYLE[indexVertical])
44 | }
45 | }
46 |
47 | findViewById(R.id.toggle_d).setOnClickListener {
48 | indexD = (indexD + 1) % CHAIN_STYLE.size
49 | constraintSet.update(constraintLayout) {
50 | setHorizontalChainStyle(R.id.text_04, indexD)
51 | }
52 | }
53 | }
54 |
55 | //endregion
56 |
57 | companion object {
58 | /**
59 | * List of chain styles through which to cycle.
60 | */
61 | private val CHAIN_STYLE = listOf(CHAIN_SPREAD, CHAIN_SPREAD_INSIDE, CHAIN_PACKED)
62 | }
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/CircularConstraintActivity.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.content.Context
4 | import android.os.Bundle
5 | import android.support.v7.app.AppCompatActivity
6 | import android.view.LayoutInflater
7 | import com.randomlytyping.ccl.util.setUpAppBar
8 | import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper
9 |
10 | /**
11 | * Example of circular constraints.
12 | */
13 | class CircularConstraintActivity : AppCompatActivity() {
14 |
15 | //region // Activity lifecycle
16 |
17 | override fun attachBaseContext(newBase: Context?) {
18 | super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase))
19 | }
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 | setContentView(R.layout.activity_container_linear_layout)
24 |
25 | // Inflate content and bind views.
26 | LayoutInflater.from(this)
27 | .inflate(R.layout.content_circular_constraint, findViewById(R.id.linear_layout))
28 |
29 | setUpAppBar()
30 | }
31 |
32 | //endregion
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/ConstraintSetActivity.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.content.Context
4 | import android.graphics.Color
5 | import android.os.Bundle
6 | import android.support.constraint.ConstraintLayout
7 | import android.support.transition.TransitionManager
8 | import android.support.v4.graphics.drawable.DrawableCompat
9 | import android.support.v7.app.AppCompatActivity
10 | import android.view.LayoutInflater
11 | import android.view.Menu
12 | import android.view.MenuItem
13 | import com.randomlytyping.ccl.util.setUpAppBar
14 | import kotterknife.bindView
15 | import rt.randamu.ConstraintSets
16 | import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper
17 |
18 | /**
19 | * Examples of ConstraintSet including transitioning between sets.
20 | */
21 | class ConstraintSetActivity : AppCompatActivity() {
22 |
23 | //region Properties
24 |
25 | private val constraintLayout by bindView(R.id.constraint_layout)
26 | private val constraintSet01 by lazy { ConstraintSets.from(this, R.layout.content_constraintset_01) }
27 | private val constraintSet02 by lazy { ConstraintSets.from(this, R.layout.content_constraintset_02) }
28 |
29 | private var original = true
30 |
31 | //endregion
32 |
33 | //region // Activity lifecycle
34 |
35 | override fun attachBaseContext(newBase: Context?) {
36 | super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase))
37 | }
38 |
39 | override fun onCreate(savedInstanceState: Bundle?) {
40 | super.onCreate(savedInstanceState)
41 | setContentView(R.layout.activity_container_linear_layout)
42 |
43 | // Inflate content and bind views.
44 | LayoutInflater.from(this).inflate(R.layout.content_constraintset_01, findViewById(R.id.linear_layout))
45 |
46 | setUpAppBar()
47 | }
48 |
49 | // endregion
50 |
51 | //region // Action item handling
52 |
53 | override fun onCreateOptionsMenu(menu: Menu): Boolean {
54 | menuInflater.inflate(R.menu.constraint_set, menu)
55 | DrawableCompat.setTint(menu.findItem(R.id.action_swap_constraint_set).icon, Color.WHITE)
56 | return true
57 | }
58 |
59 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
60 | if (item.itemId == R.id.action_swap_constraint_set) {
61 | TransitionManager.beginDelayedTransition(constraintLayout)
62 | if (original) constraintSet02.applyTo(constraintLayout)
63 | else constraintSet01.applyTo(constraintLayout)
64 | original = !original
65 | return true
66 | } else {
67 | return super.onOptionsItemSelected(item)
68 | }
69 |
70 | // endregion
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/DimensionRatioActivity.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.os.Bundle
4 | import android.support.constraint.ConstraintLayout
5 | import android.support.v7.app.AppCompatActivity
6 | import android.view.LayoutInflater
7 | import com.randomlytyping.ccl.util.setUpAppBar
8 |
9 | /**
10 | * Examples of using [ConstraintLayout]'s dimension ratio.
11 | */
12 | class DimensionRatioActivity : AppCompatActivity() {
13 |
14 | //region // Activity lifecycle
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 | setContentView(R.layout.activity_container_linear_layout)
19 |
20 | // Inflate content and bind views.
21 | LayoutInflater.from(this).inflate(R.layout.content_dimension_ratio, findViewById(R.id.linear_layout))
22 |
23 | setUpAppBar()
24 | }
25 |
26 | //endregion
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/DynamicConstraintLayoutActivity.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.content.Context
4 | import android.os.Bundle
5 | import android.support.annotation.IdRes
6 | import android.support.constraint.ConstraintLayout
7 | import android.support.constraint.ConstraintSet
8 | import android.support.constraint.ConstraintSet.*
9 | import android.support.v7.app.AppCompatActivity
10 | import android.view.LayoutInflater
11 | import android.view.View
12 | import android.view.View.NO_ID
13 | import android.widget.ImageView
14 | import android.widget.TextView
15 | import com.randomlytyping.ccl.util.setUpAppBar
16 | import kotterknife.bindView
17 | import rt.randamu.getResourceIdArray
18 | import rt.randamu.toConstraintSet
19 | import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper
20 | import java.util.Random
21 |
22 | /**
23 | * Demonstration of dynamically building up a layout using [ConstraintSet].
24 | *
25 | * Note: the code here is intentionally more verbose as I tend to use this
26 | * example for presentations where I want to explain in more detail.
27 | */
28 | class DynamicConstraintLayoutActivity : AppCompatActivity() {
29 |
30 | // Layout generation
31 | private val inflater by lazy { LayoutInflater.from(this) }
32 | private val constraintLayout by bindView(R.id.constraint_layout)
33 | private val constraintSet by lazy { constraintLayout.toConstraintSet() }
34 |
35 | // Dimension resources
36 | private val rowHeight by lazy { resources.getDimensionPixelSize(R.dimen.dynamic_row_height) }
37 | private val elevation by lazy { resources.getDimension(R.dimen.elevation_content) }
38 |
39 | // Random images/text to choose
40 | private val images by lazy { resources.getResourceIdArray(R.array.unsplash_images) }
41 | private val strings by lazy { resources.getStringArray(R.array.random_words) }
42 |
43 | // Bookkeeping
44 | @IdRes private var lastViewId: Int = NO_ID
45 | @IdRes private var lastRowId: Int = PARENT_ID
46 |
47 | private var indexImages = 0
48 | private var indexStrings = 0
49 | private var currentRowSize = 0
50 |
51 | // Coin flip
52 | private val randomNumber = Random(1)
53 |
54 | //region // Activity lifecycle
55 |
56 | override fun onCreate(savedInstanceState: Bundle?) {
57 | super.onCreate(savedInstanceState)
58 | setContentView(R.layout.activity_container_linear_layout)
59 |
60 | // Inflate content and bind views.
61 | LayoutInflater.from(this).inflate(R.layout.content_dynamic_constraint_layout, findViewById(R.id.linear_layout))
62 |
63 | setUpAppBar()
64 |
65 | findViewById(R.id.button_add_image).setOnClickListener { addItem(this::newImage) }
66 | findViewById(R.id.button_add_text).setOnClickListener { addItem(this::newText) }
67 | findViewById(R.id.button_clear).setOnClickListener {
68 | constraintLayout.removeAllViews()
69 | lastRowId = PARENT_ID
70 | lastViewId = NO_ID
71 | currentRowSize = 0
72 | constraintSet.clone(constraintLayout)
73 | }
74 | }
75 |
76 | //endregion
77 |
78 | //region // Calligraphy bootstrapping
79 |
80 | override fun attachBaseContext(newBase: Context) {
81 | super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase))
82 | }
83 |
84 | //endregion
85 |
86 | //region // Dynamic ConstraintLayout building
87 |
88 | /**
89 | * Add item as either an item in the current row or as the single item in a whole new row.
90 | */
91 | private fun addItem(newItem: () -> View) {
92 | if (currentRowSize > 0 && flip()) addRowItem(newItem()) else addNewRow(newItem())
93 | }
94 |
95 | /**
96 | * Add given [view] as whole new row in layout.
97 | */
98 | private fun addNewRow(view: View) {
99 | constraintLayout.addView(view)
100 |
101 | if (currentRowSize > 0) {
102 | lastRowId = lastViewId
103 | }
104 |
105 | val id = view.id
106 | constraintSet.constrainWidth(id, MATCH_CONSTRAINT)
107 | constraintSet.constrainHeight(id, rowHeight)
108 | constraintSet.connect(id, TOP, lastRowId, if (lastRowId == PARENT_ID) TOP else BOTTOM)
109 | constraintSet.connect(id, START, PARENT_ID, START)
110 | constraintSet.connect(id, END, PARENT_ID, END)
111 |
112 | // Toggle elevation to elevate last added view.
113 | constraintSet.setElevation(id, elevation)
114 | constraintSet.setElevation(lastViewId, 0f)
115 |
116 | // Apply constraints.
117 | constraintSet.applyTo(constraintLayout)
118 |
119 | // Update current row count.
120 | currentRowSize = 1
121 |
122 | // Record as last view added.
123 | lastViewId = id
124 | }
125 |
126 | /**
127 | * Add given [view] as constituent item of current row in layout.
128 | */
129 | private fun addRowItem(view: View) {
130 | if (currentRowSize == 0) {
131 | addNewRow(view)
132 | return
133 | }
134 |
135 | constraintLayout.addView(view)
136 |
137 | val id = view.id
138 |
139 | // Initialize width and height of new view.
140 | constraintSet.constrainWidth(id, MATCH_CONSTRAINT)
141 | constraintSet.constrainHeight(id, rowHeight)
142 |
143 | // Constrain new view vertically.
144 | constraintSet.connect(id, TOP, lastRowId, if (lastRowId == PARENT_ID) TOP else BOTTOM)
145 |
146 | // Update current row.
147 | currentRowSize++
148 |
149 | if (currentRowSize == 2) {
150 | // Once the row has two items in it, create a horizontal chain.
151 | constraintSet.createHorizontalChainRtl(
152 | PARENT_ID, START,
153 | PARENT_ID, END,
154 | intArrayOf(lastViewId, id), floatArrayOf(1f, 1f),
155 | CHAIN_SPREAD_INSIDE)
156 | } else {
157 | // The row already has at least two items so just add the new view to the chain.
158 | constraintSet.addToHorizontalChainRTL(id, lastViewId, PARENT_ID)
159 | constraintSet.setHorizontalWeight(id, 1f)
160 | }
161 |
162 | // Fix for bug in `setHorizontalWeight`.
163 | constraintSet.setHorizontalWeight(lastViewId, 1f)
164 |
165 | // Toggle elevation to elevate last added view.
166 | constraintSet.setElevation(id, elevation)
167 | constraintSet.setElevation(lastViewId, 0f)
168 |
169 | // Apply constraints.
170 | constraintSet.applyTo(constraintLayout)
171 |
172 | // Record as last view added.
173 | lastViewId = id
174 | }
175 |
176 | /**
177 | * Create new ImageView and set its text to the next image drawable in the list.
178 | */
179 | private fun newImage(): ImageView {
180 | val imageView =
181 | inflater.inflate(R.layout.layout_dynamic_image, constraintLayout, false) as ImageView
182 | return imageView.apply {
183 | id = View.generateViewId()
184 | setImageResource(images[indexImages])
185 |
186 | // Adjust index.
187 | indexImages = (indexImages + 1) % images.size
188 | }
189 | }
190 |
191 | /**
192 | * Create new TextView and set its text to the next string in the list.
193 | */
194 | private fun newText(): TextView {
195 | val textView =
196 | inflater.inflate(R.layout.layout_dynamic_text, constraintLayout, false) as TextView
197 | return textView.apply {
198 | id = View.generateViewId()
199 | text = strings[indexStrings]
200 |
201 | // Adjust index
202 | indexStrings = (indexStrings + 1) % strings.size
203 | }
204 | }
205 |
206 | //endregion
207 |
208 | //region // Randomizer
209 |
210 | /**
211 | * Flip a coin. Used to decide between "new row" or "add to current row".
212 | */
213 | private fun flip() = randomNumber.nextInt(2) == 0
214 |
215 | //endregion
216 | }
217 |
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/ListItemActivity.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.content.Context
4 | import android.graphics.Color
5 | import android.graphics.drawable.ColorDrawable
6 | import android.graphics.drawable.Drawable
7 | import android.os.Bundle
8 | import android.support.annotation.LayoutRes
9 | import android.support.constraint.ConstraintLayout
10 | import android.support.constraint.ConstraintSet
11 | import android.support.v4.content.ContextCompat
12 | import android.support.v7.app.AppCompatActivity
13 | import android.support.v7.widget.LinearLayoutManager
14 | import android.support.v7.widget.RecyclerView
15 | import android.transition.TransitionManager
16 | import android.view.LayoutInflater
17 | import android.view.View
18 | import android.view.ViewGroup
19 | import android.widget.ImageView
20 | import android.widget.TextView
21 | import com.randomlytyping.ccl.util.setUpAppBar
22 | import kotterknife.bindView
23 | import rt.randamu.ConstraintSets
24 | import rt.randamu.getResourceIdArray
25 | import rt.randamu.toConstraintSet
26 |
27 | /**
28 | * Example of using [ConstraintLayout] as roots for list items.
29 | */
30 | class ListItemActivity : AppCompatActivity() {
31 |
32 | //region // Properties
33 | private val recyclerView by bindView(R.id.recycler_view)
34 |
35 | //endregion
36 |
37 | //region // Activity lifecycle
38 |
39 | override fun onCreate(savedInstanceState: Bundle?) {
40 | super.onCreate(savedInstanceState)
41 | setContentView(R.layout.activity_container_linear_layout)
42 |
43 | // Inflate content and bind views.
44 | LayoutInflater.from(this).inflate(R.layout.content_recycler_view, findViewById(R.id.linear_layout))
45 |
46 | setUpAppBar()
47 |
48 | recyclerView.run {
49 | layoutManager = LinearLayoutManager(this@ListItemActivity)
50 | adapter = UnsplashAdapter(this@ListItemActivity)
51 | }
52 | }
53 |
54 | //endregion
55 |
56 | //region // RecyclerView/List
57 |
58 | /**
59 | * RecyclerView adapter
60 | *
61 | * @property context The current context.
62 | * @property inflater Layout inflater.
63 | * @property images List of drawable resource IDs for displayed photos.
64 | * @property attributions List of string resource IDs for image attributions.
65 | */
66 | private class UnsplashAdapter(
67 | private val context: Context,
68 | private val inflater: LayoutInflater = LayoutInflater.from(context)
69 | ) : RecyclerView.Adapter() {
70 |
71 | /**
72 | * List of string resource IDs for image URLs.
73 | */
74 | private val urls: IntArray = context.resources.getResourceIdArray(R.array.unsplash_urls)
75 | private val images: IntArray = context.resources.getResourceIdArray(R.array.unsplash_images)
76 | private val attributions: IntArray = context.resources.getResourceIdArray(R.array.unsplash_attributions)
77 |
78 |
79 | //
80 | // RecyclerView.Adapter implementation
81 | //
82 |
83 | override fun getItemId(position: Int) = position.toLong()
84 |
85 | override fun getItemCount() = images.size
86 |
87 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
88 | UnsplashViewHolder(inflater.inflate(R.layout.list_item_unsplash, parent, false),
89 | R.layout.list_item_unsplash_expanded)
90 |
91 | override fun onBindViewHolder(holder: UnsplashViewHolder, position: Int) {
92 | holder.imageDrawable = ContextCompat.getDrawable(context, images[position])
93 | holder.attributionResId = attributions[position]
94 | holder.urlResId = urls[position]
95 | }
96 | }
97 |
98 | /**
99 | * View holder
100 | */
101 | private class UnsplashViewHolder(itemView: View,
102 | @LayoutRes alternateLayout: Int,
103 | private val constraintLayout: ConstraintLayout = itemView as ConstraintLayout,
104 | private val attributionView: TextView = itemView.findViewById(R.id.attribution),
105 | private val urlView: TextView = itemView.findViewById(R.id.url),
106 | private val imageView: ImageView = itemView.findViewById(R.id.image),
107 | private var primary: Boolean = true)
108 | : RecyclerView.ViewHolder(itemView) {
109 |
110 |
111 | private val constraintSet01: ConstraintSet = constraintLayout.toConstraintSet()
112 | private val constraintSet02: ConstraintSet = ConstraintSets.from(itemView.context, alternateLayout)
113 |
114 | /**
115 | * ID of attribution string resource.
116 | */
117 | var attributionResId = 0
118 | set(value) {
119 | attributionView.setText(value)
120 | }
121 |
122 | /**
123 | * ID of url string resource.
124 | */
125 | var urlResId = 0
126 | set(value) {
127 | urlView.setText(value)
128 | }
129 |
130 | /**
131 | * Drawable resource.
132 | */
133 | var imageDrawable: Drawable? = ColorDrawable(Color.TRANSPARENT)
134 | set(value) {
135 | imageView.setImageDrawable(value)
136 | }
137 |
138 | init {
139 | itemView.setOnClickListener { swap() }
140 | }
141 |
142 | //region // Constraint set switching
143 |
144 | /**
145 | * Swap constraint sets.
146 | */
147 | fun swap() {
148 | TransitionManager.beginDelayedTransition(constraintLayout)
149 | if (primary) constraintSet02.applyTo(constraintLayout)
150 | else constraintSet01.applyTo(constraintLayout)
151 | primary = !primary
152 | }
153 | }
154 |
155 | //endregion
156 | }
157 |
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.support.annotation.ColorInt
6 | import android.support.annotation.StringRes
7 | import android.support.v4.content.ContextCompat
8 | import android.support.v4.graphics.drawable.DrawableCompat
9 | import android.support.v7.app.AppCompatActivity
10 | import android.support.v7.widget.LinearLayoutManager
11 | import android.support.v7.widget.RecyclerView
12 | import android.view.View
13 | import android.view.ViewGroup
14 | import android.widget.TextView
15 | import rt.randamu.getResourceIdArray
16 | import kotlin.properties.Delegates
17 |
18 | /**
19 | * Launcher activity + example selector.
20 | */
21 | class MainActivity : AppCompatActivity() {
22 |
23 | //region // Activity lifecycle
24 |
25 | override fun onCreate(savedInstanceState: Bundle?) {
26 | super.onCreate(savedInstanceState)
27 | setContentView(R.layout.activity_main)
28 |
29 | findViewById(android.R.id.list).run {
30 | adapter = ExampleListAdapter()
31 | layoutManager = LinearLayoutManager(this@MainActivity)
32 | }
33 | }
34 |
35 | //endregion
36 |
37 | //region // Example navigation
38 |
39 | /**
40 | * Start activity associated with given example title.
41 | */
42 | fun navigateToExample(@StringRes exampleResId: Int) {
43 | startActivity(Intent(this, when (exampleResId) {
44 | R.string.example_alignment -> AlignmentActivity::class.java
45 | R.string.example_chains -> ChainsActivity::class.java
46 | R.string.example_circular -> CircularConstraintActivity::class.java
47 | R.string.example_list_item -> ListItemActivity::class.java
48 | R.string.example_constraint_set -> ConstraintSetActivity::class.java
49 | R.string.example_dimension_ratio -> DimensionRatioActivity::class.java
50 | R.string.example_dynamic_constraint_layout -> DynamicConstraintLayoutActivity::class.java
51 | else -> throw IllegalArgumentException("Invalid item: $exampleResId")
52 | }))
53 | }
54 |
55 | //endregion
56 |
57 | //region // Example RecyclerView/List
58 |
59 | /**
60 | * RecyclerView adapter
61 | *
62 | * @property examples List of string resource IDs that represent all the navigable examples.
63 | * @property icons List of icon resource IDs that represent all the navigable examples.
64 | */
65 | private inner class ExampleListAdapter(
66 | private val examples: IntArray = resources.getResourceIdArray(R.array.examples),
67 | private val icons: IntArray = resources.getResourceIdArray(R.array.example_icons)
68 | ) : RecyclerView.Adapter() {
69 |
70 | /**
71 | * Color used to tint icons.
72 | */
73 | @ColorInt private val tint: Int =
74 | ContextCompat.getColor(this@MainActivity, R.color.icon_active_color)
75 |
76 | //
77 | // RecyclerView.Adapter implementation
78 | //
79 |
80 | override fun getItemCount() = examples.size
81 |
82 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
83 | ExampleViewHolder(
84 | layoutInflater.inflate(R.layout.list_item_example, parent, false),
85 | this@MainActivity::navigateToExample,
86 | tint
87 | )
88 |
89 | override fun onBindViewHolder(holder: ExampleViewHolder, position: Int) {
90 | holder.run {
91 | resId = examples[position]
92 | iconId = icons[position]
93 | }
94 | }
95 | }
96 |
97 | //endregion
98 |
99 | //region // Inner classes
100 |
101 | /**
102 | * View holder
103 | *
104 | * @param itemView View representing item
105 | * @param exampleListener Action executed when example item is selected.
106 | * @property tint Tint applied to example icon.
107 | */
108 | private class ExampleViewHolder(
109 | itemView: View,
110 | exampleListener: (Int) -> Unit,
111 | @ColorInt private val tint: Int
112 | ) : RecyclerView.ViewHolder(itemView) {
113 |
114 | /**
115 | * Item text view.
116 | */
117 | private val textView: TextView = itemView as TextView
118 |
119 | /**
120 | * ID of string resource for example title.
121 | */
122 | var resId by Delegates.observable(0) { _, _, new ->
123 | textView.setText(new)
124 | }
125 |
126 | /**
127 | * ID of drawable resource for example icon.
128 | */
129 | var iconId by Delegates.observable(0) { _, _, new ->
130 | textView.setCompoundDrawablesRelativeWithIntrinsicBounds(new, 0, 0, 0)
131 | DrawableCompat.setTint(textView.compoundDrawablesRelative[0], tint)
132 | }
133 |
134 | init {
135 | itemView.setOnClickListener { exampleListener(resId) }
136 | }
137 | }
138 |
139 | //endregion
140 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/util/ActivityExtensions.kt:
--------------------------------------------------------------------------------
1 | @file:JvmName("LayoutUtils")
2 |
3 | package com.randomlytyping.ccl.util
4 |
5 | import android.support.v7.app.AppCompatActivity
6 | import com.randomlytyping.ccl.R
7 |
8 | // Utility methods / extensions related to activity layouts
9 |
10 | /**
11 | * Sets up an activity's app bar.
12 | */
13 | fun AppCompatActivity.setUpAppBar() {
14 | // Set up app bar.
15 | setSupportActionBar(findViewById(R.id.app_bar))
16 | supportActionBar?.run {
17 | setDisplayShowHomeEnabled(true)
18 | setDisplayHomeAsUpEnabled(true)
19 | }
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/randomlytyping/ccl/view/SquareImageView.kt:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl.view
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.widget.ImageView
6 |
7 | /**
8 | * Image view that always displays content as a square.
9 | */
10 | class SquareImageView : ImageView {
11 |
12 | //region // View Constructors
13 |
14 | constructor(context: Context) : super(context)
15 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
16 |
17 | //endregion
18 |
19 | //region // View Overrides
20 |
21 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
22 | super.onMeasure(widthMeasureSpec, heightMeasureSpec)
23 |
24 | val size = Math.min(measuredWidth, measuredHeight)
25 | setMeasuredDimension(size, size)
26 | }
27 |
28 | //endregion
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/rt/randamu/ConstraintSetExtensions.kt:
--------------------------------------------------------------------------------
1 | package rt.randamu
2 |
3 | import android.content.Context
4 | import android.support.annotation.LayoutRes
5 | import android.support.constraint.ConstraintLayout
6 | import android.support.constraint.ConstraintSet
7 |
8 | // Utility and extension methods for ConstraintSet
9 |
10 | /**
11 | * Class containing static factory methods for [ConstraintSet] instances.
12 | */
13 | class ConstraintSets private constructor() {
14 | companion object {
15 | /**
16 | * @return A [ConstraintSet] cloned from layout resource file with given [resId].
17 | */
18 | fun from(context: Context, @LayoutRes resId: Int) =
19 | ConstraintSet().apply { clone(context, resId) }
20 | }
21 | }
22 |
23 | /**
24 | * Makes changes to the receiver [ConstraintSet] via the [updates] block and applies the resulting
25 | * new constraints on the given [constraintLayout].
26 | */
27 | inline fun ConstraintSet.update(
28 | constraintLayout: ConstraintLayout,
29 | clone: Boolean = false,
30 | updates: ConstraintSet.() -> Unit
31 | ) {
32 | if (clone) {
33 | clone(constraintLayout)
34 | }
35 | updates()
36 | applyTo(constraintLayout)
37 | }
38 |
39 | /**
40 | * @return A [ConstraintSet] cloned from the receiver.
41 | */
42 | fun ConstraintLayout.toConstraintSet() = ConstraintSet().apply { clone(this@toConstraintSet) }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/rt/randamu/ResourcesExtensions.kt:
--------------------------------------------------------------------------------
1 | @file:JvmName("ResourceUtils")
2 |
3 | package rt.randamu
4 |
5 | import android.content.res.Resources
6 | import android.support.annotation.ArrayRes
7 |
8 | // Utility methods / extensions related to Resources
9 |
10 | /**
11 | * Retrieve an array consisting of resource IDs, a list of references to other resources.
12 | */
13 | fun Resources.getResourceIdArray(@ArrayRes resId: Int): IntArray {
14 | val typedArray = obtainTypedArray(resId)
15 | val idArray = IntArray(typedArray.length())
16 | for (i in 0 until typedArray.length()) {
17 | idArray[i] = typedArray.getResourceId(i, -1)
18 | }
19 | typedArray.recycle()
20 | return idArray
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/java/rt/randamu/ViewDrawableExtensions.kt:
--------------------------------------------------------------------------------
1 | @file:JvmName("DrawableUtils")
2 |
3 | package rt.randamu
4 |
5 | import android.graphics.drawable.Drawable
6 | import android.support.annotation.ColorInt
7 | import android.support.v4.graphics.drawable.DrawableCompat
8 | import android.view.View
9 |
10 | // Utility methods / extensions related to Drawables
11 |
12 | /**
13 | * Tint this view's background with a given color.
14 | *
15 | * Utilizes [DrawableCompat] methods.
16 | */
17 | fun View.tintBackground(@ColorInt tint: Int): Drawable {
18 | val drawable = DrawableCompat.wrap(background)
19 | DrawableCompat.setTint(drawable, tint)
20 | background = drawable
21 | return drawable
22 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/lina_dragon_slave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxhdpi/lina_dragon_slave.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/lina_fiery_soul.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxhdpi/lina_fiery_soul.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/lina_laguna_blade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxhdpi/lina_laguna_blade.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/lina_light_strike_array.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxhdpi/lina_light_strike_array.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/lina_mcbeamish.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxhdpi/lina_mcbeamish.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/overviewicon_agi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxhdpi/overviewicon_agi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/overviewicon_int.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxhdpi/overviewicon_int.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/overviewicon_str.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxhdpi/overviewicon_str.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_caspar_rubin_macbook_sql.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_caspar_rubin_macbook_sql.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_cory_seward_eggs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_cory_seward_eggs.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_danielle_macinnes_artichokes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_danielle_macinnes_artichokes.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_julia_d_alkmin_ice_tea.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_julia_d_alkmin_ice_tea.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_maria_fernanda_gonzalez_coffee.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_maria_fernanda_gonzalez_coffee.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_michal_grosicki_glitter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_michal_grosicki_glitter.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_mike_kenneally_green_beans.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_mike_kenneally_green_beans.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_neven_krcmarek_grapes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_neven_krcmarek_grapes.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_nousnou_iwasaki_coffee_beans.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_nousnou_iwasaki_coffee_beans.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_oreo_cream.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_oreo_cream.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_roberta_sorge_honey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_roberta_sorge_honey.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_roberta_sorge_pineapple.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_roberta_sorge_pineapple.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_roberta_sorge_pomegranate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_roberta_sorge_pomegranate.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_shumilov_ludmila_pears.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_shumilov_ludmila_pears.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_tamarcus_brown_ruler.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_tamarcus_brown_ruler.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/unsplash_tatiana_lapina_macaroon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/drawable-xxxhdpi/unsplash_tatiana_lapina_macaroon.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_android_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_downward_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_forward_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_upward_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_circle_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dot_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_favorite_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_fire_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_format_align_left_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_image_aspect_ratio_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_link_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_list_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_snowflake_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_spa_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_stop_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_swap_horiz_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_view_list_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_widgets_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rect_stroke_grey.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_container_linear_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_container_scroll_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
22 |
23 |
32 |
33 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_alignment.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
23 |
24 |
34 |
35 |
36 |
37 |
51 |
52 |
59 |
60 |
67 |
68 |
75 |
76 |
83 |
84 |
85 |
86 |
95 |
96 |
97 |
108 |
109 |
122 |
123 |
132 |
133 |
142 |
143 |
152 |
153 |
163 |
164 |
172 |
173 |
174 |
184 |
185 |
193 |
194 |
195 |
196 |
208 |
209 |
217 |
218 |
227 |
228 |
234 |
235 |
241 |
242 |
248 |
249 |
255 |
256 |
257 |
258 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_chains.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
22 |
23 |
31 |
32 |
40 |
41 |
42 |
43 |
55 |
56 |
67 |
68 |
79 |
80 |
91 |
92 |
93 |
94 |
105 |
106 |
117 |
118 |
129 |
130 |
141 |
142 |
153 |
154 |
155 |
156 |
169 |
170 |
181 |
182 |
193 |
194 |
205 |
206 |
217 |
218 |
219 |
220 |
233 |
234 |
245 |
246 |
257 |
258 |
269 |
270 |
281 |
282 |
283 |
284 |
297 |
298 |
309 |
310 |
322 |
323 |
334 |
335 |
347 |
348 |
357 |
358 |
367 |
368 |
377 |
378 |
379 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_circular_constraint.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
20 |
21 |
30 |
31 |
40 |
41 |
50 |
51 |
60 |
61 |
70 |
71 |
80 |
81 |
90 |
91 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_constraintset_01.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
23 |
24 |
32 |
33 |
42 |
43 |
57 |
58 |
69 |
70 |
81 |
82 |
96 |
97 |
108 |
109 |
119 |
120 |
130 |
131 |
143 |
144 |
154 |
155 |
165 |
166 |
178 |
179 |
191 |
192 |
205 |
206 |
218 |
219 |
220 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_constraintset_02.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
29 |
30 |
38 |
39 |
55 |
56 |
69 |
70 |
83 |
84 |
94 |
95 |
105 |
106 |
118 |
119 |
130 |
131 |
142 |
143 |
155 |
156 |
167 |
168 |
179 |
180 |
194 |
195 |
207 |
208 |
220 |
221 |
234 |
235 |
247 |
248 |
249 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_constraintset_02_buggy.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
28 |
29 |
37 |
38 |
54 |
55 |
68 |
69 |
82 |
83 |
93 |
94 |
104 |
105 |
117 |
118 |
129 |
130 |
141 |
142 |
154 |
155 |
166 |
167 |
178 |
179 |
193 |
194 |
206 |
207 |
219 |
220 |
233 |
234 |
245 |
246 |
247 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_dimension_ratio.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
18 |
19 |
27 |
28 |
37 |
38 |
50 |
51 |
63 |
64 |
75 |
76 |
87 |
88 |
99 |
100 |
110 |
111 |
119 |
120 |
129 |
130 |
139 |
140 |
149 |
150 |
159 |
160 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_dynamic_constraint_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
21 |
22 |
29 |
30 |
37 |
38 |
39 |
45 |
46 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_recycler_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_constraints_basic.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
26 |
27 |
40 |
41 |
48 |
49 |
56 |
57 |
70 |
71 |
84 |
85 |
98 |
99 |
107 |
108 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_dynamic_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_dynamic_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_guidelines.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
22 |
23 |
29 |
30 |
40 |
41 |
49 |
50 |
60 |
61 |
71 |
72 |
82 |
83 |
89 |
90 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_example.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_unsplash.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
22 |
23 |
33 |
34 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_unsplash_expanded.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
27 |
28 |
38 |
39 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/constraint_set.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | H, 3:1
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 24dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
19 |
23 |
24 |
25 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #4D4D4D
6 | #212121
7 | #AD1457
8 |
9 |
10 | #1E000000
11 | #8A000000
12 |
13 |
14 | #A4C639
15 |
16 | #84FFFF
17 | #FF3D00
18 | #F48FB1
19 |
20 |
21 | @color/black_54p
22 | @color/black_12p
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 16dp
9 | 16dp
10 |
11 |
12 | 8dp
13 | 72dp
14 | 24dp
15 |
16 |
17 | 4dp
18 | 4dp
19 |
20 |
21 | H,16:10
22 |
23 |
24 |
25 | 1dp
26 | 16dp
27 |
28 |
29 | 96dp
30 |
31 |
32 | 40dp
33 |
34 |
35 | 8dp
36 |
37 |
38 | 32dp
39 | 48dp
40 |
41 |
42 | 16sp
43 | 72dp
44 | @dimen/activity_margin_horizontal
45 | 16dp
46 | @dimen/content_margin_horizontal
47 | 20dp
48 | 16dp
49 | @dimen/activity_margin_horizontal
50 |
51 |
52 | 120dp
53 | 48dp
54 |
55 |
56 |
57 |
58 |
59 | 40dp
60 | 24dp
61 |
62 | 80dp
63 | 24dp
64 | 72dp
65 |
66 | 24dp
67 | 48dp
68 |
69 | 48dp
70 | 24dp
71 | 24dp
72 | 56dp
73 |
74 |
75 | 16dp
76 | 40dp
77 | 8dp
78 | 8dp
79 | 120dp
80 |
81 |
82 | 96dp
83 | 80dp
84 |
85 |
86 | 88dp
87 | 16dp
88 | 24dp
89 | 8dp
90 | 48dp
91 | 24dp
92 |
93 |
94 | 80dp
95 |
96 |
--------------------------------------------------------------------------------
/app/src/main/res/values/examples.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Alignment
8 | Chains
9 | Circular Constraints
10 | ConstraintSet
11 | Dimension Ratio
12 | Dynamic ConstraintLayout
13 | Guidelines
14 | ConstraintLayout List Item
15 |
16 |
17 | - @string/example_dimension_ratio
18 | - @string/example_alignment
19 | - @string/example_chains
20 | - @string/example_circular
21 | - @string/example_constraint_set
22 | - @string/example_list_item
23 | - @string/example_dynamic_constraint_layout
24 |
25 |
26 |
27 | - @drawable/ic_image_aspect_ratio_black_24dp
28 | - @drawable/ic_format_align_left_black_24dp
29 | - @drawable/ic_link_black_24dp
30 | - @drawable/ic_circle_black_24dp
31 | - @drawable/ic_view_list_black_24dp
32 | - @drawable/ic_list_black_24dp
33 | - @drawable/ic_widgets_black_24dp
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/items.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - @drawable/unsplash_cory_seward_eggs
6 | - @drawable/unsplash_roberta_sorge_honey
7 | - @drawable/unsplash_tatiana_lapina_macaroon
8 | - @drawable/unsplash_shumilov_ludmila_pears
9 | - @drawable/unsplash_julia_d_alkmin_ice_tea
10 | - @drawable/unsplash_nousnou_iwasaki_coffee_beans
11 | - @drawable/unsplash_mike_kenneally_green_beans
12 | - @drawable/unsplash_danielle_macinnes_artichokes
13 | - @drawable/unsplash_roberta_sorge_pineapple
14 | - @drawable/unsplash_roberta_sorge_pomegranate
15 | - @drawable/unsplash_maria_fernanda_gonzalez_coffee
16 |
17 |
18 |
19 | - @string/unsplash_cory_seward
20 | - @string/unsplash_roberta_sorge
21 | - @string/unsplash_tatiana_lapina
22 | - @string/unsplash_shumilov_ludmila
23 | - @string/unsplash_julia_d_alkmin
24 | - @string/unsplash_nousnou_iwasaki
25 | - @string/unsplash_mike_kenneally
26 | - @string/unsplash_danielle_macinnes
27 | - @string/unsplash_roberta_sorge
28 | - @string/unsplash_roberta_sorge
29 | - @string/unsplash_roberta_sorge
30 |
31 |
32 |
33 | - @string/unsplash_url_cory_seward_eggs
34 | - @string/unsplash_url_roberta_sorge_honey
35 | - @string/unsplash_url_tatiana_lapina_macaroon
36 | - @string/unsplash_url_shumilov_ludmila_pears
37 | - @string/unsplash_url_julia_d_alkmin_ice_tea
38 | - @string/unsplash_url_nousnou_iwasaki_coffee_beans
39 | - @string/unsplash_url_mike_kenneally_green_beans
40 | - @string/unsplash_url_danielle_macinnes_artichokes
41 | - @string/unsplash_url_roberta_sorge_pineapple
42 | - @string/unsplash_url_roberta_sorge_pomegranate
43 | - @string/unsplash_url_maria_fernanda_gonzalez_coffee
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Cool ConstraintLayout
3 |
4 |
5 | Settings
6 |
7 |
8 | Button
9 | Edge
10 | Edge
11 | Baseline
12 |
13 |
14 |
15 | Easier Alignment
16 | Image Ratio
17 | Resize + Center Constraint
18 | Resize + Center Manual
19 |
20 |
21 |
22 | Dimension Ratio
23 | SquareImageView
24 |
25 |
26 | 1:1
27 | 16:10
28 | 16:9
29 | 4:3
30 | 3:1
31 |
32 |
33 |
34 | Chains, Chains, Chains…
35 | Alpha
36 | Beta
37 | Gamma
38 | Delta
39 | Toggle Vertical
40 | Toggle D
41 |
42 |
43 | Center of the Universe
44 |
45 |
46 |
47 | ConstraintSet
48 | LINA
49 | Dragon Slave
50 | Light Strike Array
51 | Fiery Soul
52 | Laguna Blade
53 | 27 + 3.20
54 | 16 + 1.50
55 | 18 + 1.50
56 | Swap
57 |
58 |
59 |
60 |
61 | Build Your Own from Scratch
62 | Add Image
63 | Add Text
64 | Clear
65 |
66 |
67 |
68 | image thumbnail
69 |
70 | Cory Seward
71 | Roberta Sorge
72 | Tatiana Lapina
73 | Shumilov Ludmila
74 | Julia D\'Alkmin
75 | Nousnou Iwasaki
76 | Mike Kenneally
77 | Danielle MacInnes
78 | Maria Fernanda Gonzalez
79 |
80 | https://unsplash.com/photos/svazqK-ShNk
81 | https://unsplash.com/photos/kp9UVn-PUac
82 | https://unsplash.com/photos/qpf2glK0bAA
83 | https://unsplash.com/photos/j7X_hySaUa4
84 | https://unsplash.com/photos/WKCjwrtjhVg
85 | https://unsplash.com/photos/myPzH34VYK4
86 | https://unsplash.com/photos/8eJPcAuqIhY
87 | https://unsplash.com/photos/yOT5d1PqLGY
88 | https://unsplash.com/photos/Q3jYvjW4NDk
89 | https://unsplash.com/photos/hA14zG3R4fk
90 | https://unsplash.com/photos/kWVXCmyB9so
91 |
92 |
93 | - Archipeligo
94 | - Boa
95 | - Charismatic
96 | - Decibel
97 | - Effervescent
98 | - Flare
99 | - Ginger
100 | - Harlequinn
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
22 |
25 |
26 |
31 |
32 |
33 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
53 |
54 |
58 |
59 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
76 |
77 |
78 |
81 |
82 |
83 |
91 |
92 |
95 |
96 |
99 |
100 |
103 |
104 |
107 |
108 |
111 |
112 |
116 |
117 |
121 |
122 |
126 |
127 |
131 |
132 |
133 |
137 |
138 |
146 |
147 |
148 |
153 |
154 |
157 |
158 |
161 |
162 |
165 |
166 |
167 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/test/java/com/randomlytyping/ccl/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.randomlytyping.ccl;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.1.2-4'
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.0'
11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | mavenCentral()
23 | maven {
24 | url "https://oss.sonatype.org/content/repositories/snapshots"
25 | }
26 | }
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queencodemonkey/cool-constraintlayout/250d132c5f4a824826f79ab15a7a7d9a0ad15d46/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Sep 20 21:05:23 EDT 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.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 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------