🦚 An expandable layout that shows a two-level layout with an indicator.

Overview

ExpandableLayout


🦚 An expandable layout that shows a two-level layout with an indicator.


License API Travis Android Weekly Javadoc

Including in your project

Maven Central Jitpack

Gradle

Add below codes to your root build.gradle file (not your module build.gradle file).

allprojects {
    repositories {
        mavenCentral()
    }
}

And add a dependency code to your module's build.gradle file.

dependencies {
    implementation "com.github.skydoves:expandablelayout:1.0.6"
}

Usage

Add following XML namespace inside your XML layout file.

xmlns:app="http://schemas.android.com/apk/res-auto"

ExpandableLayout

Here is a basic example of implementing ExpandableLayout.

<com.skydoves.expandablelayout.ExpandableLayout
  android:id="@+id/expandable"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="30dp"
  app:expandable_duration="300"
  app:expandable_isExpanded="false" // expand the second layout initially or not.
  app:expandable_parentLayout="@layout/layout_parent" // sets the parent layout. 
  app:expandable_secondLayout="@layout/layout_second" // sets the second layout.
  app:expandable_showSpinner="true" // shows the spinner or not.
  app:expandable_spinner="@drawable/ic_arrow_down" // sets the spinner's drawable.
  app:expandable_spinner_animate="true" // animates the spinner when expanding or collapse.
  app:expandable_spinner_margin="14dp" // sets the margin to the spinner.
  app:expandable_spinner_gravity="start" // sets the gravity to the spinner.
  app:expandable_spinner_size="32dp" // sets the spinner size.
/>

Create using builder class

We can create an instance of ExpandableLayout using the builder class.

val myExpandableLayout = expandableLayout(context) {
  setParentLayoutResource(R.layout.layout_parent)
  setSecondLayoutResource(R.layout.layout_second)
  setShowSpinner(true)
  setSpinnerAnimate(true)
  setSpinnerMargin(12f)
  setSpinnerRotation(90)
  setDuration(200)
  setOnExpandListener { toast("is expanded : $it") }
}

Expand and Collapse

We can expand and collapse using the below methods.

expandablelayout.expand() // expand the second layout with indicator animation.
expandablelayout.collapse() // collapse the second layout with indicator animation.

ParentLayout and SecondLayout

We can get the parentLayout and secondLayout of the ExpandableLayout.
And we can access child views of them.

expandablelayout.parentLayout.setOnClickListener {
  toast("the parent layout is clicked!")
}
expandablelayout.secondLayout.setOnClickListener {
  toast("the second layout is clicked!")
}

// getting child view using findViewById.
expandablelayout.secondLayout.findViewById<Button>(R.id.button0).setOnClickListener { 
    toast("button0 clicked") 
}
// getting child view using android extension.
expandablelayout.secondLayout.button0.setOnClickListener { toast("button0 clicked") }

OnExpandListener

We can listen to the ExpandableLayout is expanded or collapsed.

expandablelayout.onExpandListener = object : OnExpandListener {
  override fun onExpand(isExpanded: Boolean) {
    toast("Expanded : $it")
  }
}

// or we can listen using a lambda expression.
expandable.setOnExpandListener {
  if (it) {
    toast("expanded")
  } else {
    toast("collapse")
  }
}

ExpandableAnimation

We can customize the expanding and collapsing animation.

ExpandableAnimation.NORMAL
ExpandableAnimation.ACCELERATE
ExpandableAnimation.BOUNCE
NORMAL ACCELERATE BOUNCE

ExpandableLayout Attributes

Attributes Type Default Description
isExpanded Boolean false Expand the second layout initially or not.
parentLayout layout default layout Sets the parent layout.
secondLayout layout default layout Sets the second layout.
duration Long 250L Sets the duration of the spinner animation.
spinner Drawable arrow_down Sets the spinner's drawable.
showSpinner Boolean true Shows the spinner or not.
spinner_animate Boolean true Animates the spinner when expanding or collapse.
spinner_rotation Integer -180 Sets the rotation of the spinner animation.
spinner_size Dimension 36dp Sets the size of the spinner.
spinner_margin Dimension 8dp Sets the margin of the spinner.
spinner_gravity SpinnerGravity end Sets the gravity of the spinner.

Find this library useful? ❤️

Support it by joining stargazers for this repository.
And follow me for my next creations! 🤩

License

Copyright 2019 skydoves (Jaewoong Eum)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • General Sizing (Height) Issues

    General Sizing (Height) Issues

    Library Version is 1.0.4

    Describe the Bug:

    I had the following problem when trying to implement your library. I was using a deprecated expandable layout library and I decided to switch to yours. My existing solution had a header (parent) layout of height ?attr/actionBarSize so I assumed I'd just be able to reuse these layouts. I converted them to support your system of having a parent and child layout and got it compiling.

    I noticed that there was a gap between my parent and secondary layout and couldn't figure out why. After looking into the source for the library I found the issue to be in the resource file ExpandableLayout/expandablelayout/src/main/res/layout/expandable_layout_parent.xml

    This layout defines the height of the parent to be a static 36dp rather than adapt to the custom view the developer chooses to be the parent view.

    Also, I noticed a few issues when calculating the height of the secondary layout, it being larger than the source layout file. I will open a pull request that should shed some more light on the subject.

    Expected Behavior: I expect the parent layout to be the size of the layout I define as the parentLayout.

    I expect the secondary layout to be the exact size that I define in the layout file, not larger.

    Released 
    opened by joeShuff 4
  • Second layout does not have the right height

    Second layout does not have the right height

    Please complete the following information:

    • Library Version 1.0.3
    • Affected Device(s) Generic device

    I'm using this library inside a recyclerview. Each item in the recyclerview can be expanded, but the content of each item can vary, so the height is different for each item. The library seems to calculate the height for each item, however the height is not correct. For each item is always less the the real layout size.

    Expected Behavior:

    Since the content of each item is dynamic, the library should expose a method that can re mesure the height of the second layout.

    Released 
    opened by fgnm 4
  • Error inflating class on Android 4.x

    Error inflating class on Android 4.x

    • Library Version [v1.0.5]
    • Affected Device(s) [AS emulator 4.2, 4.4]

    Describe the Bug: When inflating the layout containing expandablelayout, the app crashes. Unfortunately not much is reported to the logcat. Only "Error inflating class com.skydoves.expandablelayout"

    Expected Behavior: It should work as it does on Android 7 and 10; I tested on.

    This is where it crashes LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_main_settings, null, false);

    Below is how I use this library inside my layout <com.skydoves.expandablelayout.ExpandableLayout android:id="@+id/ABC" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="6dp" app:expandable_duration="150" app:expandable_isExpanded="false" app:expandable_parentLayout="@layout/abc_parent" app:expandable_secondLayout="@layout/abc_child" app:expandable_showSpinner="true" app:expandable_spinner="@drawable/ic_arrow_down" app:expandable_spinner_color="@color/violetDark" app:expandable_spinner_animate="true" app:expandable_spinner_margin="0dp" app:expandable_spinner_size="36dp"/>

    bug Released 
    opened by thereisonlywe 3
  • How can I show ListView or RecyclerView inside secondLayout?

    How can I show ListView or RecyclerView inside secondLayout?

    My implementation not work. https://prnt.sc/pdgzsa https://prnt.sc/pdgzxy When I expanding parentLayout, there is no list. But if I put a button there, I see the button and first item of recyclerView

    opened by Pirokar 3
  • secondLayout not completely hide when collapsing

    secondLayout not completely hide when collapsing

    • Library Version - 1.0.6

    I had implement multiple expandableLayout and I notice that when collapsing the second expandableLayout, the secondLayout is not completely hide.

    I am using ScrollView as my main's parent layout to make it scrollable. is it ScrollView makes the secondLayout work abnormally?

    https://user-images.githubusercontent.com/39330565/112133694-e84d3b00-8c06-11eb-9ef3-518627e6df9c.mp4

    opened by WenLonG12345 2
  • Spinner margin doesn't work when the layout is RTL

    Spinner margin doesn't work when the layout is RTL

    • Library Version [v1.0.5]
    • Affected Device(s) [AS emulator Android 10]

    Describe the Bug: Setting "app:expandable_spinner_margin" has no effect when the layout is RTL.

    bug Released 
    opened by thereisonlywe 2
  • Duplicate Arrow

    Duplicate Arrow

    Please complete the following information:

    • Library Version: 1.0.7
    • Affected Device(s): Android Emulator - Pixel 3a XL API 30

    Description:

    A duplicate arrow is shown with my own provided drawable. PS: Setting layout programmatically worked only, not with XML

    Expected Behavior:

    It should override the provided drawable icon in expandable_layout_frame.xml -> AppCompatImageView.

    image image

    Actual Behavior:

    SS-2 SS-1

    opened by mohsinraza-10P 1
  • toggleLayout() cannot be resolved

    toggleLayout() cannot be resolved

    • Library Version - 1.0.6

    Hi, recently I found this library and the implementation is great and simple. Thanks for it :) But there is some problem regarding on the method toggleLayout(). I can't use this method as it stated as not resolved.

    Here is the screenshot. Screenshot_1

    I am using Fragment instead of Activity. Is it the problem exist because I am using Fragment?

    PS: I notice that there is no toggleLayout() in ExpandableLayout.kt

    opened by WenLonG12345 1
  • Spinner  expanded icon color

    Spinner expanded icon color

    Hi. When using your component expanded spinner icon sets to yellow color by default.

    Can you please tell me what style should I override to solve this? Thank you!

    image

    opened by Cianid 1
  • Wrong header size

    Wrong header size

    Please complete the following information:

    • Library Version: 1.0.6
    • Affected Device(s): Samsung Galaxy S9+ Android 10.

    Describe the Bug: Hi,

    I am having some troubles while displaying the parent layout. It seems to have a fixed size and it does not adapts to the actual size of my parent layout. The Expandable layout is wrapped within a linearlayout in a nestedscroll view.

    I attach the code in case I am doing something wrong:

    <com.skydoves.expandablelayout.ExpandableLayout
                    android:id="@+id/expandableThirdPartyDevices"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="15dp"
                    app:expandable_duration="300"
                    app:expandable_isExpanded="false"
                    app:expandable_parentLayout="@layout/content_expandable_parent"
                    app:expandable_secondLayout="@layout/content_expandable_second"
                    app:expandable_showSpinner="true"
                    app:expandable_spinner="@drawable/ic_arrow_down"
                    app:expandable_spinner_animate="true"
                    app:expandable_spinner_margin="14dp"
                    app:expandable_spinner_gravity="end"
                    app:expandable_spinner_size="32dp" />`
    

    content_expandable_parent:

    <?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:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@drawable/rounded_corners_button"
        android:backgroundTint="@color/StemyEnergy.Color.UI.Text.Background.Blue"
        android:id="@+id/ctlySelectDevice">
    
        <TextView
            android:id="@+id/txtSelectDevice"
            android:textSize="@dimen/medium_text_size_app"
            android:textColor="@color/StemyEnergy.Color.UI.Text.Blue"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingStart="15dp"
            android:gravity="start|center"
            android:text="@string/StemyEnergy.String.UI.GeneralMessages.TestText"
            />
    </LinearLayout>
    

    Expected Behavior: What I expect is the expandable layout header to adapt to my parent layout content.

    Thanks in advance for your help!!

    Cheers, Nacho

    opened by IgnacioBasallote 1
  • Setting the spinner color programmatically does not work

    Setting the spinner color programmatically does not work

    I tried to use setSpinnerColor(int) after expanding, but does not update already showing expanded layout. Changing the spinner color in xml works, but not programmatically.

    Released 
    opened by aldwinbabierra 1
  • Parent layout textview is not showing multi text

    Parent layout textview is not showing multi text

    • implementation "com.github.skydoves:expandablelayout:1.0.7"
    • Device : All

    I am trying to set multiline text in parent layout textview. It's working in XML preview and when i run the device its showing only one line. I have tried with maxLine =5 and singleLine=false properties as well. Please help me

    opened by androidbala126 0
  • conflicts with another tag that has the same ID

    conflicts with another tag that has the same ID

    Please complete the following information:

    • Library Version [e.g. v1.0.0]
    • Affected Device(s) [e.g. Samsung Galaxy s10 with Android 9.0]

    This is what i am getting in my app

    {"msg":"\u003ccom.skydoves.expandablelayout.ExpandableLayout id\u003d\u0027@+id/expandable\u0027\u003e conflicts with another tag that has the same ID","file":"app\src\main\res\layout\fragment_kyc_overview.xml","pos":[{"line0":187,"col0":24,"line1":195,"col1":64}]}

    opened by oluwabajio 1
  • The lib has weird issues in RecyclerView

    The lib has weird issues in RecyclerView

    Please complete the following information:

    • Library Version: 1.0.7
    • Affected Device(s) : Samsung Galaxy Note 10 with Android 12.0

    Describe the Bug: I have attached the reproduced video and code

    https://user-images.githubusercontent.com/5199109/153915619-ce1c4240-c2be-4f74-965b-b2ab5f1b3f13.mp4

    
    /*
     * Copyright (C) 2019 skydoves
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package com.skydoves.expandablelayoutdemo
    
    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import com.skydoves.expandablelayoutdemo.databinding.ActivityCustomBinding
    import kotlin.random.Random
    
    class CustomActivity : AppCompatActivity() {
    
      private val adapter = ParentAdapter()
    
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val binding = ActivityCustomBinding.inflate(layoutInflater)
        setContentView(binding.root)
    
        binding.recyclerView.adapter = adapter
        for (i in 0..100){
          val child = ArrayList<String>()
          val randomValues = List(10) { Random.nextInt(0, 50) }
          randomValues.forEach {
            child.add("child $i")
          }
          adapter.addSectionItem(
            SectionItem("Title $i", R.color.colorPrimary, child)
          )
        }
    
      }
    }
    
    

    Expected Behavior:

    As demo sample

    opened by chihung93 0
  • Spinner icon color only changes one time programmatically

    Spinner icon color only changes one time programmatically

    Please complete the following information:

    • Library-Version: v1.0.7
    • Affected Device(s) Google Pixel3 with Android 12 and Huawei Android 8

    Describe the Bug:

    For the expansion spinner icon, I set its color from the XML file to be gray

    <com.skydoves.expandablelayout.ExpandableLayout android:id="@+id/requestFailedExpandLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/_12sdp" android:layout_marginEnd="@dimen/_12sdp" app:expandable_duration="300" app:expandable_isExpanded="false" app:expandable_parentLayout="@layout/request_failed_header_layout" app:expandable_secondLayout="@layout/request_failed_body_layout" app:expandable_showSpinner="true" app:expandable_spinner_animate="true" app:expandable_spinner_color="@color/gray_8b8b8b" />

    then I added a listener on the layout when it's expanded the icon should be blue else should be gray

    setOnExpandListener { if (isExpanding) { parentLayout.backgroundTintList = ContextCompat.getColorStateList(requireContext(), R.color.blue_daebfd) spinnerColor = R.color.colorPrimary parentLayout.findViewById<MaterialTextView>(R.id.tvRecommendationExpandTitle).setTextColor(ContextCompat.getColor(requireContext(), R.color.colorPrimary)) } else { parentLayout.backgroundTintList = ContextCompat.getColorStateList(requireContext(), R.color.gray_c7c7c7) spinnerColor = R.color.gray_8b8b8b parentLayout.findViewById<MaterialTextView>(R.id.tvRecommendationExpandTitle).setTextColor(ContextCompat.getColor(requireContext(), R.color.gray_8b8b8b)) } }

    but after one single change, the color never changes again.

    Expected Behavior:

    the spinner icon color to be always changeable

    opened by MohamedEmish 1
  • View Binding for parent and second layouts

    View Binding for parent and second layouts

    Unable to get the viewBinding references for parent and second layouts inside Expandable Layout view. Tried with mainActivityBinding.expandableLayout.parentLayout/parentLayoutResource etc.. unable to get the viewbinding instance for the layouts inside expandable layout.

    [mainActivityBinding being the binidng for the layout in which Exapandable layout with id expandableLayout.]

    opened by Ramu3967 0
  • Recycler View in second Layout is not mesured

    Recycler View in second Layout is not mesured

    • Library Version : 1.0.7
    • Pixel 3 and 4, OnePlus Nord, Android 10 and 11

    Describe the Bug:

    I put a recycler view in the second layout, but it doesn't get mesured, hence it is not displayed. The only way i made it appear is by giving it a fixed height in dp, which is not good for my app.

    Expected Behavior:

    The child recycler view should be displayed in full when it's height is set to wrap_content

    opened by ThomasKreactive 2
Releases(1.0.7)
Owner
Jaewoong Eum
Android software engineer. Digital Nomad. Open Source Contributor. ❤️ Love coffee, music, magic tricks and writing poems. Coffee Driven Development.
Jaewoong Eum
💳 A quick and easy flip view through which you can create views with two sides like credit cards, poker cards etc.

The article on how this library was created is now published. You can read it on this link here. →. ?? EasyFlipView Built with ❤︎ by Wajahat Karim and

Wajahat Karim 1.3k Dec 14, 2022
A lightweight indicator like in nexus 5 launcher

CircleIndicator A lightweight indicator like in nexus 5 launcher Gradle AndroidX dependencies { implementation 'me.relex:circleindicator:2.1.6' }

relex 4.1k Dec 30, 2022
A view pager indicator view to deal with a large amount of pages.

Attention I'm not going to support this anymore. Just use a better solution, e.g. this one Indefinite-Pager-Indicator BubblePagerIndicator A view page

Bogdan Kornev 134 Aug 18, 2022
With MVVM Architecture pattern using Android Architecture Components This is a sample app demonstrating Youtube player animation using constraint layout

Youtube UI/UX Animation This is a sample app demonstrating Youtube UX/UI animation using ConstraintLayout.It implements the Keyframe Animation feature

Burhanuddin Rashid 866 Dec 29, 2022
Extended Android Tab Layout with animated indicators that have continuous feedback.

Dachshund Tab Layout Introduction Boosted Android Tab Layout with custom animated indicators including "Dachshund" animation inspired by this. Sample

Andrii 859 Nov 10, 2022
🎢 Zoom Recycler Layout Manager For Android Kotlin

Zoom Recyler Layout An beautiful Zoom Animation Library for RecyclerView Items in Android using Kotlin. Preview 1. Horizontal Scroll 2. Vertical Scrol

Sanju S 778 Jan 2, 2023
Animation samples with motion layout and object animator 🦹🏻‍♀️

?? Animations ?? Animation samples with motion layout and object animator ????‍♀️ Car Animation with Object Animator ?? ?? I've created this project b

Yağmur Erdoğan 25 Dec 28, 2022
A backport of the SwitchPreference component that was introduced on Android 4 (ICS / level 14). This port works on Android 2.1+ (Eclair MR1 / level 7).

Android Switch Preference Backport A backport of the SwitchPreference component that was introduced on Android 4 (ICS / level 14). This port works on

Benoit Lubek 498 Dec 29, 2022
Dubins path refers to the shortest curve that connects two points in the two-dimensional Euclidean plane

Dubins Dubins path refers to the shortest curve that connects two points in the two-dimensional Euclidean plane (i.e. x-y plane) with a constraint on

Erik Schouten 8 Jan 20, 2022
Pager (especially for ViewPager) indicator in two styles: circle & fraction.

PagerIndicator Pager (especially for ViewPager) indicator in two styles: circle & fraction. Demo circle fraction Dependency implementation 'me.liangfe

Fei Liang 212 Nov 28, 2022
Pager (especially for ViewPager) indicator in two styles: circle & fraction.

PagerIndicator Pager (especially for ViewPager) indicator in two styles: circle & fraction. Demo circle fraction Dependency implementation 'me.liangfe

Fei Liang 212 Nov 28, 2022
Step by step,just use HorizontalStepView,VerticalStepView. step indicator,flow indicator,timeline,order process,express status

StepView Step by step. Step indicator. Flow indicator。 snapshot like this:HorizontalStepView like this also like this:VerticalStepView Yeah,I am not w

baoyachi. Aka Rust Hairy crabs 4.1k Dec 30, 2022
This app shows you the latest news within the last two hours

News This app shows you the latest news within the last two hours. also it let's

Mohamed Saleh 1 Oct 24, 2022
Dots indicator that shows the current position on a View Pager. It does all the work for you with a few customisations.

Dots What is Dots? Dots is a library that helps in implementing a simple yet effective dots indicator for the View Pagers used in your android code. I

Deepan 23 Feb 16, 2022
A layout to transition between two views using a Floating Action Button as shown in many Material Design concepts

⚠ This library is no longer maintained ⚠️ FABRevealLayout A layout to transition between two views using a Floating Action Button as shown in many Mat

Tomás Ruiz-López 901 Dec 9, 2022
Android Layout (Relative Layout, Linear Layout etc) to Image

Layout-to-Image Android Layout Xml File Containing any Parent Layout (Relative Layout, Linear Layout etc) to Image Screenshot of Sample Application Qu

Vipul Asri 166 Nov 22, 2022
[] An Android library for an expandable button menu

ExpandableButtonMenu ExpandableButtonMenu is an Android library which implements an expandable button that can be used as a substitute of a fixed size

Lemon Labs 325 Nov 14, 2022
A better ExpandableListView, with animated expandable views for each list item

SlideExpandableListView for Android Not happy with the Android ExpandableListView android offers? Want something like the Spotify app. This library al

Tjerk Wolterink 2k Dec 22, 2022
Customized and Expandable TextView

Customized and Expandable TextView Simple library to change the Textview as rectangle, circle and square shapes by adding one line of code in xml file

Raja Gopal 62 Sep 22, 2022