Skip to content
This repository was archived by the owner on Aug 22, 2024. It is now read-only.

Commit 890d7e6

Browse files
authored
Merge pull request #31 from amardeshbd/feature/28_layout_view_visibility_behaviour
Feature/28 layout view visibility behaviour
2 parents 2c94cf2 + f87848c commit 890d7e6

File tree

12 files changed

+306
-25
lines changed

12 files changed

+306
-25
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
<category android:name="android.intent.category.LAUNCHER" />
1818
</intent-filter>
1919
</activity>
20-
<activity android:name=".layoutpositioning.LayoutPositioningDemoActivity"></activity>
20+
<activity android:name=".layoutpreview.LayoutPreviewBaseActivity" />
21+
<activity android:name=".layoutpreview.LayoutVisibilityGoneActivity"></activity>
2122
</application>
2223

2324
</manifest>

app/src/main/java/com/hossainkhan/android/demo/browse/MainActivity.kt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ package com.hossainkhan.android.demo.browse
1919
import android.support.v7.app.AppCompatActivity
2020
import android.os.Bundle
2121
import android.support.v7.widget.GridLayoutManager
22-
import android.support.v7.widget.LinearLayoutManager
2322
import android.support.v7.widget.RecyclerView
24-
import android.view.View
2523
import com.hossainkhan.android.demo.R
2624
import com.hossainkhan.android.demo.data.AppDataStore
27-
import com.hossainkhan.android.demo.layoutpositioning.LayoutPositioningDemoActivity
25+
import com.hossainkhan.android.demo.layoutpreview.LayoutPreviewBaseActivity
26+
import com.hossainkhan.android.demo.layoutpreview.LayoutVisibilityGoneActivity
2827
import dagger.android.AndroidInjection
2928
import timber.log.Timber
3029
import javax.inject.Inject
@@ -66,7 +65,16 @@ class MainActivity : AppCompatActivity() {
6665
fun onLayoutItemSelected(layoutResId: Int) {
6766
Timber.i("Selected layout id: %s", layoutResId)
6867

69-
startActivity(LayoutPositioningDemoActivity
70-
.createStartIntent(this, layoutResId))
68+
when (layoutResId) {
69+
R.layout.preview_visibility_gone -> {
70+
startActivity(LayoutVisibilityGoneActivity
71+
.createStartIntent(this))
72+
}
73+
else -> {
74+
startActivity(LayoutPreviewBaseActivity
75+
.createStartIntent(this, layoutResId))
76+
}
77+
}
78+
7179
}
7280
}

app/src/main/java/com/hossainkhan/android/demo/dagger/ActivityBindingModule.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
package com.hossainkhan.android.demo.dagger
1818

19-
import com.hossainkhan.android.demo.layoutpositioning.LayoutPositioningDemoActivity
19+
import com.hossainkhan.android.demo.layoutpreview.LayoutPreviewBaseActivity
20+
import com.hossainkhan.android.demo.layoutpreview.LayoutVisibilityGoneActivity
2021
import dagger.Module
2122
import dagger.android.ContributesAndroidInjector
2223

@@ -46,5 +47,9 @@ abstract class ActivityBindingModule {
4647
*/
4748
@ActivityScope
4849
@ContributesAndroidInjector
49-
abstract fun layoutPositioningActivity(): LayoutPositioningDemoActivity
50+
abstract fun layoutPositioningActivity(): LayoutPreviewBaseActivity
51+
52+
@ActivityScope
53+
@ContributesAndroidInjector
54+
abstract fun layoutVisibilityActivity(): LayoutVisibilityGoneActivity
5055
}

app/src/main/java/com/hossainkhan/android/demo/data/LayoutDataStore.kt

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ import javax.inject.Singleton
2626
@Singleton
2727
class LayoutDataStore @Inject constructor(
2828
private val resources: Resources) {
29+
/**
30+
* Various layouts features and it's information mostly taken from official documentation.
31+
*
32+
* See:
33+
* - https://github.com/amardeshbd/android-constraint-layout-cheatsheet/blob/master/app/src/main/res/layout/.README.md
34+
* - https://developer.android.com/reference/android/support/constraint/ConstraintLayout#VisibilityBehavior
35+
*/
2936
val supportedLayoutInfos = listOf(
3037
LayoutInformation(
3138
layoutResourceId = R.layout.preview_positioning_top_left,
@@ -45,7 +52,16 @@ class LayoutDataStore @Inject constructor(
4552
"\n\n" +
4653
"layout_constraintCircle : references another widget id\n" +
4754
"layout_constraintCircleRadius : the distance to the other widget center\n" +
48-
"layout_constraintCircleAngle : which angle the widget should be at (in degrees, from 0 to 360)\n")
55+
"layout_constraintCircleAngle : which angle the widget should be at (in degrees, from 0 to 360)\n"),
56+
LayoutInformation(
57+
layoutResourceId = R.layout.preview_visibility_gone,
58+
thumbnailResourceId = R.drawable.thumb_visibility_behaviour,
59+
title = "Visibility: GONE behaviour",
60+
description = "A view marked as GONE are not going to be displayed and are not part of the layout itself.\n" +
61+
"But in terms of the layout computations, GONE widgets are still part of it, with an important distinction:" +
62+
"\n\n" +
63+
" * For the layout pass, their dimension will be considered as zero (basically, they will be resolved to a point)\n" +
64+
" * If they have constraints to other widgets they will still be respected, but any margins will be as if equals to zero")
4965
)
5066

5167
/**
@@ -66,12 +82,12 @@ class LayoutDataStore @Inject constructor(
6682
// com.hossainkhan.android.demo:layout/preview_positioning_top_left
6783
val resourceName = resources.getResourceName(layoutResourceId)
6884

69-
if(!resourceName.contains("layout")) {
85+
if (!resourceName.contains("layout")) {
7086
throw IllegalStateException("Only layout resource is allowed.")
7187
}
7288

7389
return AppConfig.GITHUB_BASE_URL.plus("/blob/master/app/src/main/res/") +
7490
resourceName.split(':')
75-
.last().plus(".xml")
91+
.last().plus(".xml")
7692
}
7793
}

app/src/main/java/com/hossainkhan/android/demo/layoutpositioning/LayoutPositioningDemoActivity.kt renamed to app/src/main/java/com/hossainkhan/android/demo/layoutpreview/LayoutPreviewBaseActivity.kt

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.hossainkhan.android.demo.layoutpositioning
17+
package com.hossainkhan.android.demo.layoutpreview
1818

1919
import android.content.Context
2020
import android.content.Intent
@@ -34,14 +34,18 @@ import timber.log.Timber
3434
import javax.inject.Inject
3535

3636
/**
37-
* Relative positioning is one of the basic building block of creating layouts in ConstraintLayout.
38-
* Those constraints allow you to position a given widget relative to another one.
39-
* You can constrain a widget on the horizontal and vertical axis.
37+
* This the the **base** activity for previewing different constraint layout features.
38+
*
39+
* Currently, the activity does following basic actions:
40+
* 1. Inject necessary dependencies required for all activities.
41+
* 1. Load and populate [LayoutInformation] for currently viewing layout.
42+
* 1. Shows tooltip with layout details for the first time only.
43+
* 1. Loads layout XML source code from Github.
4044
*/
41-
class LayoutPositioningDemoActivity : AppCompatActivity() {
45+
open class LayoutPreviewBaseActivity : AppCompatActivity() {
4246

4347
companion object {
44-
private const val BUNDLE_KEY_LAYOUT_RESID = "KEY_LAYOUT_RESOURCE_ID"
48+
internal const val BUNDLE_KEY_LAYOUT_RESID = "KEY_LAYOUT_RESOURCE_ID"
4549

4650
/**
4751
* Creates an intent with required information to start this activity.
@@ -50,26 +54,25 @@ class LayoutPositioningDemoActivity : AppCompatActivity() {
5054
* @param layoutResourceId The layout resource ID to load into the view.
5155
*/
5256
fun createStartIntent(context: Context, @LayoutRes layoutResourceId: Int): Intent {
53-
val intent = Intent(context, LayoutPositioningDemoActivity::class.java)
57+
val intent = Intent(context, LayoutPreviewBaseActivity::class.java)
5458
intent.putExtra(BUNDLE_KEY_LAYOUT_RESID, layoutResourceId)
5559
return intent
5660
}
5761
}
5862

5963
@Inject
60-
lateinit var appDataStore: AppDataStore
64+
internal lateinit var appDataStore: AppDataStore
6165

62-
lateinit var layoutInformation: LayoutInformation
63-
var flashbar: Flashbar? = null
66+
internal lateinit var layoutInformation: LayoutInformation
67+
internal var flashbar: Flashbar? = null
6468

6569
override fun onCreate(savedInstanceState: Bundle?) {
6670
AndroidInjection.inject(this)
6771
super.onCreate(savedInstanceState)
6872

6973
val layoutResourceId = intent.getIntExtra(BUNDLE_KEY_LAYOUT_RESID, -1)
70-
val resourceName = appDataStore.layoutStore.getLayoutUrl(layoutResourceId)
7174
layoutInformation = appDataStore.layoutStore.layoutsInfos[layoutResourceId]!!
72-
Timber.d("Loading layout: %s, info: %s", resourceName, layoutInformation)
75+
Timber.d("Loading layout: %s", layoutInformation)
7376

7477
setContentView(layoutResourceId)
7578

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2018 Hossain Khan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.hossainkhan.android.demo.layoutpreview
18+
19+
import android.content.Context
20+
import android.content.Intent
21+
import android.os.Bundle
22+
import android.view.View
23+
import android.widget.Button
24+
import com.hossainkhan.android.demo.R
25+
26+
class LayoutVisibilityGoneActivity : LayoutPreviewBaseActivity() {
27+
28+
companion object {
29+
/**
30+
* Creates an intent with required information to start this activity.
31+
*
32+
* @param context Activity context.
33+
*/
34+
fun createStartIntent(context: Context): Intent {
35+
val intent = Intent(context, LayoutVisibilityGoneActivity::class.java)
36+
intent.putExtra(BUNDLE_KEY_LAYOUT_RESID, R.layout.preview_visibility_gone)
37+
return intent
38+
}
39+
}
40+
41+
override fun onCreate(savedInstanceState: Bundle?) {
42+
super.onCreate(savedInstanceState)
43+
44+
// Setup additional view that is only available in this screen.
45+
val toggleButton = findViewById<Button>(R.id.toggle_view_visibility_button)
46+
val firstView = findViewById<View>(R.id.visibility_behaviour_box_start)
47+
48+
toggleButton.setOnClickListener {
49+
when (firstView.visibility) {
50+
View.VISIBLE -> firstView.visibility = View.GONE
51+
else -> firstView.visibility = View.VISIBLE
52+
}
53+
}
54+
}
55+
56+
57+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<!--
2+
~ Copyright (c) 2018 Hossain Khan
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
18+
android:width="24dp"
19+
android:height="24dp"
20+
android:viewportWidth="640"
21+
android:viewportHeight="640">
22+
<path
23+
android:fillAlpha="0"
24+
android:fillColor="#FF000000"
25+
android:pathData="M2.19,637.84L637.81,637.84L637.81,2.16L2.19,2.16L2.19,637.84Z"
26+
android:strokeWidth="2"
27+
android:strokeAlpha="1"
28+
android:strokeColor="#000000" />
29+
<path
30+
android:fillAlpha="1"
31+
android:fillColor="#00acc1"
32+
android:pathData="M593.85,97.35C596.4,97.35 598.46,99.42 598.46,101.97C598.46,119.95 598.46,169.28 598.46,187.27C598.46,189.81 596.4,191.88 593.85,191.88C566.21,191.88 487.91,191.88 460.27,191.88C457.72,191.88 455.65,189.81 455.65,187.27C455.65,169.28 455.65,119.95 455.65,101.97C455.65,99.42 457.72,97.35 460.27,97.35C487.91,97.35 566.21,97.35 593.85,97.35Z" />
33+
<path
34+
android:fillAlpha="1"
35+
android:fillColor="#0c5d18"
36+
android:pathData="M47.18,52.31L72.82,52.31L72.82,540L47.18,540L47.18,52.31Z" />
37+
<path
38+
android:fillAlpha="1"
39+
android:fillColor="#c18600"
40+
android:pathData="M336.53,102.74C339.08,102.74 341.15,104.8 341.15,107.35C341.15,125.33 341.15,174.67 341.15,192.65C341.15,195.2 339.08,197.26 336.53,197.26C309,197.26 231,197.26 203.47,197.26C200.92,197.26 198.85,195.2 198.85,192.65C198.85,174.67 198.85,125.33 198.85,107.35C198.85,104.8 200.92,102.74 203.47,102.74C231,102.74 309,102.74 336.53,102.74Z" />
41+
<path
42+
android:fillAlpha="0"
43+
android:fillColor="#FF000000"
44+
android:pathData="M365.31,136.45L346.15,151.78L365.31,136.45Z"
45+
android:strokeWidth="6"
46+
android:strokeAlpha="0.85"
47+
android:strokeColor="#006064" />
48+
<path
49+
android:fillAlpha="0"
50+
android:fillColor="#FF000000"
51+
android:pathData="M345.94,149.01L365.7,163.55L345.94,149.01Z"
52+
android:strokeWidth="6"
53+
android:strokeAlpha="0.85"
54+
android:strokeColor="#006064" />
55+
<path
56+
android:fillAlpha="0"
57+
android:fillColor="#FF000000"
58+
android:pathData="M109.61,136.13L90.45,151.46L109.61,136.13Z"
59+
android:strokeWidth="6"
60+
android:strokeAlpha="0.85"
61+
android:strokeColor="#006064" />
62+
<path
63+
android:fillAlpha="0"
64+
android:fillColor="#FF000000"
65+
android:pathData="M90.24,149.33L110,163.87L90.24,149.33Z"
66+
android:strokeWidth="6"
67+
android:strokeAlpha="0.85"
68+
android:strokeColor="#006064" />
69+
<path
70+
android:fillAlpha="0"
71+
android:fillColor="#FF000000"
72+
android:pathData="M92,150L192,150"
73+
android:strokeWidth="8"
74+
android:strokeAlpha="0.85"
75+
android:strokeColor="#006064" />
76+
<path
77+
android:fillAlpha="0"
78+
android:fillColor="#FF000000"
79+
android:pathData="M348.67,150L448.67,150"
80+
android:strokeWidth="8"
81+
android:strokeAlpha="0.85"
82+
android:strokeColor="#006064" />
83+
<path
84+
android:fillAlpha="1"
85+
android:fillColor="#00acc1"
86+
android:pathData="M337.91,342.74C340.46,342.74 342.52,344.8 342.52,347.35C342.52,365.33 342.52,414.67 342.52,432.65C342.52,435.2 340.46,437.26 337.91,437.26C310.27,437.26 231.97,437.26 204.33,437.26C201.78,437.26 199.72,435.2 199.72,432.65C199.72,414.67 199.72,365.33 199.72,347.35C199.72,344.8 201.78,342.74 204.33,342.74C231.97,342.74 310.27,342.74 337.91,342.74Z" />
87+
<path
88+
android:fillAlpha="0"
89+
android:fillColor="#FF000000"
90+
android:pathData="M109.37,381.84L90.21,397.17L109.37,381.84Z"
91+
android:strokeWidth="6"
92+
android:strokeAlpha="0.85"
93+
android:strokeColor="#006064" />
94+
<path
95+
android:fillAlpha="0"
96+
android:fillColor="#FF000000"
97+
android:pathData="M90,394.39L109.76,408.93L90,394.39Z"
98+
android:strokeWidth="6"
99+
android:strokeAlpha="0.85"
100+
android:strokeColor="#006064" />
101+
<path
102+
android:fillAlpha="0"
103+
android:fillColor="#FF000000"
104+
android:pathData="M93.24,395.3L193.24,395.3"
105+
android:strokeWidth="8"
106+
android:strokeAlpha="0.85"
107+
android:strokeColor="#006064" />
108+
<path
109+
android:fillAlpha="1"
110+
android:fillColor="#ad0000"
111+
android:pathData="M256.87,148.72L238.46,167.13L248.77,177.44L267.18,159.03L285.59,177.44L295.9,167.13L277.49,148.72L295.9,130.31L285.59,120L267.18,138.41L248.77,120L238.46,130.31L256.87,148.72Z" />
112+
<path
113+
android:fillAlpha="1"
114+
android:fillColor="#fffb3a"
115+
android:pathData="M272.4,406.51L272.41,406.51L261.04,420L240,395.01L251.36,381.52L261.04,393.01L289.92,358.72L301.28,372.21L272.4,406.51Z" />
116+
<path
117+
android:fillAlpha="1"
118+
android:fillColor="#fffb3a"
119+
android:pathData="M528.56,157.79L528.56,157.79L517.2,171.28L496.15,146.29L507.51,132.8L517.2,144.3L546.08,110L557.44,123.49L528.56,157.79Z" />
120+
</vector>

app/src/main/res/layout/preview_positioning_centered.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
android:layout_height="match_parent"
2323
android:foreground="@drawable/ic_grid_overlay"
2424
android:foregroundTint="@color/grid_tint"
25-
tools:context=".layoutpositioning.LayoutPositioningDemoActivity">
25+
tools:context=".layoutpreview.LayoutPreviewBaseActivity">
2626

2727

2828
<!--

app/src/main/res/layout/preview_positioning_top_left.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
android:layout_height="match_parent"
2222
android:foreground="@drawable/ic_grid_overlay"
2323
android:foregroundTint="@color/grid_tint"
24-
tools:context=".layoutpositioning.LayoutPositioningDemoActivity">
24+
tools:context=".layoutpreview.LayoutPreviewBaseActivity">
2525

2626

2727
<!--

0 commit comments

Comments
 (0)