0

How to implement the following feature. I have a list in recycler. When I click on item below clicked item appear description. But at the same time the items of the list have to move down to become below opened description.

Bo Z
  • 2,359
  • 1
  • 13
  • 31
  • Take a look at this library it'll help https://github.com/AAkira/ExpandableLayout – Mr. Patel Jul 16 '19 at 15:05
  • what does list means here ? ListView or just content ? well, if it is content then it ll just work if you toggle visibility of content else use the following layouts https://github.com/Ramotion/folding-cell-android or this one is also good https://github.com/worldline/FoldableLayout – Harkal Jul 16 '19 at 15:05
  • @HarKal yes. Something like this. Is there a way to implement it without 3rd party library with just native way? – Bo Z Jul 16 '19 at 15:10
  • @Mr.Patel Something like this. Is there a way to implement it without 3rd party library with just native way? – Bo Z Jul 16 '19 at 15:10
  • To do this native way take a look at this link https://stackoverflow.com/questions/27203817/recyclerview-expand-collapse-items – Mr. Patel Jul 16 '19 at 15:15
  • @BorisRuzanov look at the code in the lib just copy the basic concept from there ;) – Harkal Jul 16 '19 at 15:25
  • @Mr.Patel will it work on old devices or only on latest ones? – Bo Z Jul 16 '19 at 15:25
  • @HarKal it looks awesome. But will that work on api 15-21 devices? Or only on new one? – Bo Z Jul 16 '19 at 15:26
  • @BorisRuzanov obviously on all 14+ devices – Harkal Jul 16 '19 at 15:27
  • @HarKal strange. I got Manifest merger failed when adding that library – Bo Z Jul 16 '19 at 15:28
  • @BorisRuzanov which of the two u tried well i think the problem is because u might not be using androidx support lib and the latest one of the repo is based on androidx support lib so u should downgrade and use else import it manually and edit at some places. there are only 4 files that needs to be updated – Harkal Jul 16 '19 at 15:33
  • @HarKal trying folding cell – Bo Z Jul 16 '19 at 15:36
  • @BorisRuzanov i got u and the problem its because of android suppport lib the lib uses androidx – Harkal Jul 16 '19 at 15:37
  • so u import it manually by downloading the code and update the lib's gradle file to android appcompat lib – Harkal Jul 16 '19 at 15:37
  • @HarKal do i understand right that I need to use androidX to fix that issue? i didnt work with that before thats why asking – Bo Z Jul 16 '19 at 15:39
  • not necessary it ll take such much time to upgrade to androidx it ll possibly break your project – Harkal Jul 16 '19 at 15:40
  • i m happy with my androd appcommpat lib whenever any lib demands androidx i just handle it manually – Harkal Jul 16 '19 at 15:41
  • @HarKal thank you so much for your time. So what gona be my solution to start using folding cell? What do I need to do? – Bo Z Jul 16 '19 at 15:42
  • i m writing an answer just follow the instructions – Harkal Jul 16 '19 at 15:43
  • This solution will work on all devices as it's suggested by google – Mr. Patel Jul 16 '19 at 15:44
  • @Mr.Patel you talking about expandable layout link you provided right? – Bo Z Jul 16 '19 at 15:45
  • yes i'm talking about both links native one will work too and library one will work too difference is just that when you'll use library you'll need to do less code as compared to native code – Mr. Patel Jul 16 '19 at 15:47
  • I've personally used expandable layout library and never ever faced any issue with any devices – Mr. Patel Jul 16 '19 at 15:48
  • @BorisRuzanov check the answer bro ! – Harkal Jul 16 '19 at 15:56

2 Answers2

1

follow the link Folding Cell

then click on clone or download button to download it you can use git

once you have downloaded it then unzip it and copy the folding-cell folder from the unzipped folder to your projects folder i mean you have to put folding -cell in parallel to app folder

once u do that go to your android studio and do the following changes :

open settings.gradle the file miight look like this

include ':app'

you have to update it to the following :

include ':app'
    ':folding-cell'

after that open your app build.gradle file and add the following line to the dependencies portion

implementation project(':folding-cell')

once you have done that just sync the project after the building is done u ll get the same error as you were getting earlier

so now you have to open the folding-cell build.gradle file and update the androidx lib to android

just update the whole file to this

    apply plugin: 'com.android.library'

android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')

    implementation 'com.android.support:appcompat-v7:28.0.0'

    testImplementation 'junit:junit:4.12'
    testImplementation 'org.mockito:mockito-core:2.22.0'
}

and now again build the project

everything ll work without error

if u face any problem let me know !

Harkal
  • 1,770
  • 12
  • 28
0

For a case like this, you want to utilize multiple ViewHolders, each with it's own layout:

data class Item(
    title: String, 
    description: String, 
    showDescription: Boolean = false
)

open class TitleViewHolder(
    itemView: View,
    onClicked: (Int) -> Unit
) : RecyclerView.ViewHolder(itemView) {

    private val titleView: TextView = itemView.findViewById(R.id.title)

    init {
        itemView.setOnClickListener { 
            if (adapterPosition != RecyclerView.NO_POSITION)
                onClicked(adapterPosition)
        }
    }

    fun bindTo(item: Item) {
        titleView.text = item.title
        onBind(item)
    }

    protected open fun onBind(item: Item) {
        // Do nothing
    }

}

class TitleAndDescriptionViewHolder(
    itemView: View,
    onClicked: (Int) -> Unit
) : TitleViewHolder(itemView) {
    private val description: TextView = itemView.findViewById(R.id.description)

    override fun onBind(item: Item) {
        description.text = item.description
    }
}

override fun getItemViewType(position: Int) = if (items[position].showDescription)
    R.layout.item_with_description else R.layout.item_with_title

override fun createViewHolder(...) {
    val view = LayoutInflater.from(...).inflate(viewType, parent, false)

    // Note: This presentation logic can be easily extracted, utilizing a
    // Lambda passed to the adapter which takes (Item) and returns Unit.
    // You'd then need a `setList` method which uses `DiffUtil` to update the
    // List but the result should be the same.
    val onClick: (Int) -> Unit = {
        val dataItem = data[it]
        val newItem = dataItem.copy(showDescription = !dataItem.showDescription)
        data[it] = newItem
        notifyItemChanged(it)
    }

    return when (viewType) {
        R.layout.item_with_description -> TitleAndDescriptionViewHolder(view)
        R.layout.item_with_title -> TitleViewHolder(view)
    }
}

override fun bindViewHolder(holder, position) {
    holder.bindTo(data[position])
}

When you click an item, you update it's showDescription flag and notify the Adapter that something changed at that position. That will trigger building the new item, perform the proper animations, etc.

Alex Hart
  • 1,663
  • 12
  • 15
  • thank you. But basically it suppose to be not a new Item but extention of the same one. – Bo Z Jul 16 '19 at 15:30
  • It's the same underlying item. All we're doing is replacing which view is displaying it. Is there a specific reason it needs to be the same view instance? As far as I remember, remeasuring views in a RecyclerView can be tricky. – Alex Hart Jul 16 '19 at 15:32
  • I am passing the object to put data from it in cell. So I guess it suppose to be the same item to make it work with the same object – Bo Z Jul 16 '19 at 15:44
  • I'd use a wrapper type then, and use that for my adapter: `data class ItemWrapper(item: OriginalItem, showDescription: Boolean)` – Alex Hart Jul 16 '19 at 15:47