Skip to content

Commit

Permalink
Merge pull request #11 from skydoves/fix/measure_height
Browse files Browse the repository at this point in the history
Fix/measure height
  • Loading branch information
skydoves authored Apr 4, 2020
2 parents 14e16ae + b36b3f4 commit 3d60124
Show file tree
Hide file tree
Showing 13 changed files with 72 additions and 86 deletions.
4 changes: 1 addition & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ android {

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin"
implementation "androidx.appcompat:appcompat:$versions.androidxAppcompat"
implementation "androidx.cardview:cardview:$versions.cardView"
implementation "com.google.android.material:material:$versions.googleMaterial"
implementation "com.github.skydoves:baserecyclerviewadapter:$versions.baseAdapter"
implementation "androidx.recyclerview:recyclerview:$versions.recyclerView"
implementation project(":expandablelayout")
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<activity android:name=".CustomActivity" />
<activity android:name=".MainActivity">
<intent-filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ package com.skydoves.expandablelayoutdemo
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.layout_second.view.*
import kotlinx.android.synthetic.main.activity_main.expandable
import kotlinx.android.synthetic.main.activity_main.expandable1
import kotlinx.android.synthetic.main.activity_main.expandable2
import kotlinx.android.synthetic.main.layout_second.view.button0
import kotlinx.android.synthetic.main.layout_second.view.button1
import kotlinx.android.synthetic.main.layout_second.view.button2
import kotlinx.android.synthetic.main.layout_second.view.button3

class MainActivity : AppCompatActivity() {

Expand Down Expand Up @@ -58,7 +63,7 @@ class MainActivity : AppCompatActivity() {
if (expandable1.isExpanded) {
expandable1.collapse()
} else {
expandable1.expand(370)
expandable1.expand()
}
}
expandable1.secondLayout.setOnClickListener { toast("clicked the second layout") }
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/layout/item_row.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
android:layout_height="wrap_content"
android:background="@color/background800"
android:foreground="?attr/selectableItemBackground"
android:orientation="vertical">
android:orientation="vertical"
tools:ignore="UnusedAttribute">

<TextView
android:id="@+id/row_title"
Expand Down
12 changes: 7 additions & 5 deletions app/src/main/res/layout/layout_parent.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_cover"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/skyBlue"
android:foreground="?attr/selectableItemBackground"
android:padding="16dp">
android:gravity="center"
android:padding="16dp"
tools:ignore="UnusedAttribute">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center_vertical"
android:layout_gravity="center"
android:text="This is the ExpandableLayout"
android:textColor="@color/white_87" />
</RelativeLayout>
</LinearLayout>
8 changes: 5 additions & 3 deletions app/src/main/res/layout/layout_second1.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background800"
android:foreground="?attr/selectableItemBackground"
android:orientation="vertical"
android:padding="10dp">
android:padding="10dp"
tools:ignore="UnusedAttribute">

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="120dp"
android:text="All men have stars, but they are not the same things for different people. For some, who are travelers, the stars are guides. For others they are no more than little lights in the sky. For others, who are scholars, they are problems... But all these stars are silent. You-You alone will have stars as no one else has them."
android:layout_height="wrap_content"
android:text="@string/text_stars"
android:textColor="@android:color/white" />
</LinearLayout>
9 changes: 5 additions & 4 deletions app/src/main/res/layout/layout_second2.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background800"
android:orientation="vertical">

<androidx.cardview.widget.CardView
Expand All @@ -15,9 +16,9 @@

<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="Travelocity has some of the best prices on vacation packages guaranteed. Book your flight and hotel together to save money today!"
android:text="@string/text_travel"
android:textColor="@color/white_93" />
</androidx.cardview.widget.CardView>
</RelativeLayout>
</LinearLayout>
4 changes: 3 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<resources>
<string name="app_name">ExpandableLayoutDemo</string>
<string name="app_name">ExpandableLayoutDemo</string>
<string name="text_travel">Travelocity has some of the best prices on vacation packages guaranteed. Book your flight and hotel together to save money today!</string>
<string name="text_stars">All men have stars, but they are not the same things for different people. For some, who are travelers, the stars are guides. For others they are no more than little lights in the sky. For others, who are scholars, they are problems... But all these stars are silent. You-You alone will have stars as no one else has them.</string>
</resources>
7 changes: 3 additions & 4 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ ext.versions = [
versionName : '1.0.4',

gradleBuildTool : '3.5.3',
spotlessGradle : '3.26.1',
spotlessGradle : '3.28.0',
dokkaGradle : '0.9.17',
bintrayRelease : '0.9.1',

kotlin : '1.3.61',
kotlin : '1.3.70',
androidxAppcompat : '1.1.0',

// for demo
cardView : '1.0.0',
recyclerView : '1.1.0',
googleMaterial : '1.2.0-alpha05',
baseAdapter : '0.1.3'
]
1 change: 0 additions & 1 deletion expandablelayout/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin"
implementation "androidx.appcompat:appcompat:$versions.androidxAppcompat"
implementation "androidx.recyclerview:recyclerview:$versions.recyclerView"
}

dokka {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@ import androidx.annotation.ColorInt
import androidx.annotation.LayoutRes
import androidx.annotation.Px
import androidx.core.widget.ImageViewCompat
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.expandable_layout_parent.view.arrow
import kotlinx.android.synthetic.main.expandable_layout_parent.view.cover

/** An expandable layout that shows a two-level layout with an indicator. */
@Suppress("unused")
class ExpandableLayout : FrameLayout {

lateinit var parentLayout: ViewGroup
lateinit var secondLayout: ViewGroup
lateinit var parentLayout: View
lateinit var secondLayout: View
private lateinit var parentFrameLayout: RelativeLayout
@LayoutRes var parentLayoutResource: Int = R.layout.expandable_layout_parent
set(value) {
Expand Down Expand Up @@ -128,7 +126,7 @@ class ExpandableLayout : FrameLayout {
a.getResourceId(R.styleable.ExpandableLayout_expandable_secondLayout,
this.secondLayoutResource)
this.duration =
a.getInteger(R.styleable.ExpandableLayout_expandable_duration, this.duration.toInt()).toLong()
a.getInteger(R.styleable.ExpandableLayout_expandable_duration, duration.toInt()).toLong()
val animation =
a.getInteger(R.styleable.ExpandableLayout_expandable_animation,
this.expandableAnimation.value)
Expand All @@ -139,19 +137,19 @@ class ExpandableLayout : FrameLayout {
}
this.spinnerDrawable = a.getDrawable(R.styleable.ExpandableLayout_expandable_spinner)
this.showSpinner =
a.getBoolean(R.styleable.ExpandableLayout_expandable_showSpinner, this.showSpinner)
a.getBoolean(R.styleable.ExpandableLayout_expandable_showSpinner, showSpinner)
this.spinnerAnimate =
a.getBoolean(R.styleable.ExpandableLayout_expandable_spinner_animate, this.spinnerAnimate)
a.getBoolean(R.styleable.ExpandableLayout_expandable_spinner_animate, spinnerAnimate)
this.spinnerRotation =
a.getInt(R.styleable.ExpandableLayout_expandable_spinner_rotation, this.spinnerRotation)
a.getInt(R.styleable.ExpandableLayout_expandable_spinner_rotation, spinnerRotation)
this.spinnerSize =
a.getDimension(R.styleable.ExpandableLayout_expandable_spinner_size, this.spinnerSize)
a.getDimension(R.styleable.ExpandableLayout_expandable_spinner_size, spinnerSize)
this.spinnerMargin =
a.getDimension(R.styleable.ExpandableLayout_expandable_spinner_margin, this.spinnerMargin)
a.getDimension(R.styleable.ExpandableLayout_expandable_spinner_margin, spinnerMargin)
this.spinnerColor =
a.getColor(R.styleable.ExpandableLayout_expandable_spinner_color, this.spinnerColor)
a.getColor(R.styleable.ExpandableLayout_expandable_spinner_color, spinnerColor)
this.isExpanded =
a.getBoolean(R.styleable.ExpandableLayout_expandable_isExpanded, this.isExpanded)
a.getBoolean(R.styleable.ExpandableLayout_expandable_isExpanded, isExpanded)
}

override fun onFinishInflate() {
Expand All @@ -172,21 +170,25 @@ class ExpandableLayout : FrameLayout {

private fun updateParentLayout() {
this.parentFrameLayout = inflate(R.layout.expandable_layout_parent) as RelativeLayout
this.parentLayout = inflate(this.parentLayoutResource)
this.parentLayout = inflate(parentLayoutResource)
this.parentLayout.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
this.parentFrameLayout.cover.addView(this.parentLayout)
this.parentFrameLayout.cover.addView(parentLayout)
this.parentFrameLayout.cover.updateLayoutParams { height = parentLayout.measuredHeight }
addView(this.parentFrameLayout)
addView(parentFrameLayout)
}

private fun updateSecondLayout() {
this.secondLayout = inflate(this.secondLayoutResource)
with(this.secondLayout) {
updateLayoutParams { height = 0 }
y = parentLayout.measuredHeight.toFloat()
secondLayout = inflate(secondLayoutResource)
secondLayout.visible(false)
addView(secondLayout)
secondLayout.post {
secondLayoutHeight = getMeasuredHeight(secondLayout)
secondLayout.visible(true)
with(secondLayout) {
updateLayoutParams { height = 0 }
y = parentLayout.measuredHeight.toFloat()
}
}
addView(this.secondLayout)
setMeasureHeight(secondLayout)
}

private fun updateSpinner() {
Expand All @@ -209,44 +211,21 @@ class ExpandableLayout : FrameLayout {
}
}

private fun setMeasureHeight(parent: ViewGroup): Int {
parent.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
var height = parent.height
height += getTopBottomPaddingSize(parent)
height += getTopBottomMarginSize(parent)
for (i in 0 until parent.childCount) {
val child = parent.getChildAt(i)
child.post {
child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
height += when (child) {
is ExpandableLayout -> child.height + child.secondLayoutHeight
is RecyclerView -> child.measuredHeight
is ViewGroup -> setMeasureHeight(child)
else -> child.measuredHeight
}
height += getTopBottomPaddingSize(child)
height += getTopBottomMarginSize(child)
if (height > this.secondLayoutHeight) {
this.secondLayoutHeight = height
private fun getMeasuredHeight(view: View): Int {
var height = view.height
if (view is ViewGroup) {
for (i in 0 until view.childCount) {
val child = view.getChildAt(i)
if (child is ExpandableLayout) {
child.post {
height += getMeasuredHeight(child)
}
}
}
}
return height
}

private fun getTopBottomPaddingSize(view: View): Int {
return view.paddingTop + view.paddingBottom
}

private fun getTopBottomMarginSize(view: View): Int {
var margin = 0
if (view.layoutParams is MarginLayoutParams) {
val marginLayoutParams = (view.layoutParams as MarginLayoutParams)
margin += marginLayoutParams.topMargin + marginLayoutParams.bottomMargin
}
return margin
}

/**
* This function is for supporting Java language.
* Expand the second layout with indicator animation.
Expand Down Expand Up @@ -315,18 +294,15 @@ class ExpandableLayout : FrameLayout {
}
}

private fun inflate(@LayoutRes resource: Int): ViewGroup {
private fun inflate(@LayoutRes resource: Int): View {
val inflater: LayoutInflater =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(resource, this, false)
if (view is ViewGroup) {
return view
} else {
throw IllegalArgumentException("the layout resource should be wrapped a ViewGroup.")
}
return view
}

/** Builder class for creating [ExpandableLayout]. */
@Suppress("unused")
@ExpandableLayoutDsl
class Builder(context: Context) {
private val expandableLayout = ExpandableLayout(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<FrameLayout
android:id="@+id/cover"
android:layout_width="match_parent"
android:layout_height="36dp" />
android:layout_height="wrap_content" />

<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/arrow"
Expand Down

0 comments on commit 3d60124

Please sign in to comment.