Android TreeView for RecyclerView with highly customizable

Overview

Gapo Tree View

Support TreeView for RecyclerView with highly customizable

Demo

Features

  • Expand/Collapse nodes
  • Select/Unselect/Get Selected nodes
  • Highly customizable UI with NodeState (example below)
  • Support margin by node's level
  • Support concat adapters
  • Show/Hide Tree: Highly effective when used with concat adapters

Installation

Gradle

implementation 'vn.gapowork.android:tree-view:1.0.0-alpha01'

Usage

Prepare input data, the model need extends NodeData, example:

data class Example(
    //required
    override val nodeViewId: String, 
    val child: List<ExampleNodeViewData>, 
    //your custom field
    val exampleId: String, 
    val exampleName: String,
) : NodeData<ExampleNodeViewData> {

    //list child
    override fun getNodeChild(): List<NodeData<Example>> {
        return child
    }

    //for diff util
    override fun areItemsTheSame(item: NodeData<Example>): Boolean {
       ...
    }

    //for diff util
    override fun areContentsTheSame(item: NodeData<Example>): Boolean {
        ...
    }
    
     //for diff util
    override fun getChangePayload(item: NodeData<Example>): Bundle {
        return Bundle()
    }
}

Create Tree

val treeView = GapoTreeView.Builder.plant<DepartmentNodeViewData>(Context)
    .withRecyclerView(binding.treeViewDepartment) //RecyclerView will be supported tree view
    .withLayoutRes(R.layout.department_node_view_item) //item layout
    .setListener(GapoTreeView.Listener) //listener of tree view
    .setData(List<NodeData>) //list NodeData
    .itemMargin(Int) //optional: margin by node's level. default = 24dp
    .addItemDecoration() //optional: item decoration of RecyclerView. If use this will disable feature itemMargin
    .showAllNodes(Boolean) //optional: show all nodes or just show parent node. default = false
    .addAdapters(config: ConcatAdapter.Config, adapters: List<RecyclerView.Adapter<*>>) //optional: the adapters to concat
    .build()

Basic functions

//expand node
fun expandNode(nodeId: String)

//collapse node
fun collapseNode(nodeId: String)

//select a node by id. This function only updates data, not UI and will trigger [onNodeSelected] for further processing
fun selectNode(nodeId: String, isSelected: Boolean)

//select multiple nodes. This function only updates data, not UI
fun setSelectedNode(nodes: List<NodeViewData<T>>, isSelected: Boolean)

//unselect all nodes. This function only updates data, not UI
fun clearNodesSelected()

//get all selected nodes
fun getSelectedNodes(): List<T>

//update layout
fun requestUpdateTree()

Highly customizable with NodeState

The main purpose of NodeState is to customize the UI. Set NodeState as you need and then update at onBind() (see onBind() of GapoTreeView.Listener below for more details)
You can optionally create NodeStates like:

object DisabledNodeState: NodeState
class SpecialNodeState(val label: String): NodeState

//set NodeState for nodes. This function only updates data, not UI
fun setNodesState(nodeIds: List<String>, nodeState: NodeState?)

//remove state for all nodes. This function only updates data, not UI
fun clearNodesState()

//get nodes by state
fun getNodesByState(nodeState: NodeState)

GapoTreeView.Listener

/**
 * @param [holder] view holder of Recyclerview Adapter
 * @param [position] current item position
 * @param [item] node item info
 * @param [bundle] change payload
 */
 override fun onBind(
    holder: View,
    position: Int,
    item: NodeViewData<Example>,
    bundle: Bundle? 
){
    //find view by id
    val rbCheck = holder.findViewById<AppCompatRadioButton>(R.id.rb_check)
    val button = holder.findViewById<Button>(R.id.button)
    
    //get your model. This case is Example
    val data: Example = item.getData() 
    //get state of node
    val state: NodeState = item.nodeState 
    
    //suppose when click 1 button, set state that node to DisabledNodeState
    button.setOnClickListener {
        treeView.setNodesState(listOf(item.nodeId), DisabledNodeState)
    }
    
    //bind UI by NodeState
    if(state is DisabledNodeState) {
        
    }

    //expand/collapse node
    holder.setDebouncedOnClickListener {
        if (item.isExpanded) {
            treeView.collapseNode(item.nodeId)
        } else {
            treeView.expandNode(item.nodeId)
        }
    }

    //select node
    rbCheck.setOnClickListener {
        treeView.selectNode(item.nodeId, !item.isSelected) //will trigger onNodeSelected
    }
}

/**
 * Will be triggered after call treeView.selectNode()
 * @param [node] node item
 * @param [child] child of selected node
 * @param [isSelected] is selected or not
 */
override fun onNodeSelected(
    node: NodeViewData<DepartmentNodeViewData>,
    child: List<NodeViewData<DepartmentNodeViewData>>,
    isSelected: Boolean
) {
    //example case single-choice
    if (!isSelected) return //not allow unselect

    treeView.clearNodesSelected() 
    treeView.setSelectedNode(listOf(node), isSelected) 
    treeView.requestUpdateTree()
}

Support Concat Adapter:

  1. Why need support concat adapter?
    For example, a screen needs to display a list of treeviews, and at the same time has a search function. With the search function, it will display flat/breadcrumb form, So there are 2 ways to do it: the first way is to use 2 recyclerview, the second way is to use 1 recyclerview with concat adapter.
    If you are using GapoTreeView in fragment, activity there won't be any problem, can be easily split into 2 recyclerviews, 1 for TreeView, 1 for search feature.
    However, if using 2 RecyclerView in the BottomSheetFragment, there will have a issue that can't scroll the RecyclerView and the BottomSheet together. So the solution here is to use ConcatAdapter for 1 RecyclerView.

  2. Usage: In the GapoTreeView's constructor, pass the other adapters that need concat to the adapters param.
    Functions to show/hide tree

 fun hideTree()
 
 fun showTree()

Sample

License

Copyright (c) 2021, Gapo Technology JSC
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of Gapo Technology JSC nor the names of its contributors
      may be used to endorse or promote products derived from this software
      without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL GAPO TECHNOLOGY JSC BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You might also like...
[UNMAINTAINED] Sticky Headers decorator for Android's RecyclerView
[UNMAINTAINED] Sticky Headers decorator for Android's RecyclerView

This project is no longer being maintained sticky-headers-recyclerview This decorator allows you to easily create section headers for RecyclerViews us

Android library providing simple way to control divider items (ItemDecoration) of RecyclerView
Android library providing simple way to control divider items (ItemDecoration) of RecyclerView

RecyclerView-FlexibleDivider Android library providing simple way to control divider items of RecyclerView Release Note [Release Note] (https://github

[] Super fast and easy way to create header for Android RecyclerView

DEPRECATED I created this library back in the day when I thought RecyclerView was all new and difficult. Writing an adapter that could inflate multipl

Android Library to provide swipe, click and other functionality to RecyclerView

RecyclerViewEnhanced Android Library to provide swipe, click and other functionality to RecyclerView Usage Add this to your build.gradle file dependen

Android library defining adapter classes of RecyclerView to manage multiple view types
Android library defining adapter classes of RecyclerView to manage multiple view types

RecyclerView-MultipleViewTypeAdapter RecyclerView adapter classes for managing multiple view types Release Note [Release Note] (https://github.com/yqr

ItemDecoration for RecyclerView using LinearLayoutManager for Android
ItemDecoration for RecyclerView using LinearLayoutManager for Android

RecyclerItemDecoration RecyclerItemDecoration allows you to draw divider between items in recyclerview with multiple ViewType without considering item

Set of plugable extenstions for Android RecyclerView

DynamicRecyclerView Set of light and non-invasive extensions for Android RecyclerView widget. Does not use custom RecyclerView or LayoutManager. With

Android library for RecyclerView to manage order of items and multiple view types.
Android library for RecyclerView to manage order of items and multiple view types.

recyclerview-binder Android Library for RecyclerView to manage order of items and multiple view types. Features Insert any items to wherever you want

A pull to zoom-in RecyclerView for android
A pull to zoom-in RecyclerView for android

PullZoomRecyclerView Using RecyclerView requires three steps: Step one: use the PullZoomRecyclerView in XML Step two: call the function setAdapter and

Comments
  • Duplicated item margin

    Duplicated item margin

    If I instantiate the builder on the same recycler view more than one time, each time the library seems to duplicate the space on the left of the indented items (item margin). I'm using the library with the default margin, without setting a new value.

    Is there another way to re-instantiate the object or, maybe, change the dataset?

    opened by AsiaMartini 0
Releases(1.0.0-alpha01)
TikTok-RecyclerView - This is a demo app built using 'Koin' a new dependency injection framework for Android along with RecyclerView and ExoPlayer2.

TikTok-RecyclerView Demo About This is a demo app built using 'Koin' a new dependency injection framework for Android along with RecyclerView and ExoP

Baljeet Singh 19 Dec 28, 2022
A RecyclerView that implements pullrefresh and loadingmore featrues.you can use it like a standard RecyclerView

XRecyclerView a RecyclerView that implements pullrefresh , loadingmore and header featrues.you can use it like a standard RecyclerView. you don't need

XRecyclerView 5.3k Dec 26, 2022
A RecyclerView that implements pullrefresh and loadingmore featrues.you can use it like a standard RecyclerView

XRecyclerView a RecyclerView that implements pullrefresh , loadingmore and header featrues.you can use it like a standard RecyclerView. you don't need

XRecyclerView 5.3k Dec 26, 2022
Carousel Recyclerview let's you create carousel layout with the power of recyclerview by creating custom layout manager.

Carousel Recyclerview let's you create carousel layout with the power of recyclerview by creating custom layout manager.

Jack and phantom 504 Dec 25, 2022
RecyclerView : SleepQualityTracker with RecyclerView app

RecyclerView - SleepQualityTracker with RecyclerView app SleepQualityTracker with RecyclerView This app builds on the SleepQualityTracker developed pr

Kevin 2 May 14, 2022
Pagination-RecyclerView - Simple and easy way to Paginating a RecyclerView

Pagination-RecyclerView Simple and easy way to Paginating a RecyclerView Android

Rakshit Nawani 0 Jan 3, 2022
A customizable and easy-to-use Timeline View library for Android

TimelineView A customizable and easy-to-use Timeline View library for Android Can be used as a standalone view or as a RecyclerView decorator Setup 1.

Riccardo Lattarulo 189 Dec 10, 2022
An Android Animation library which easily add itemanimator to RecyclerView items.

RecyclerView Animators RecyclerView Animators is an Android library that allows developers to easily create RecyclerView with animations. Please feel

Daichi Furiya 11.2k Jan 8, 2023
A RecyclerView(advanced and flexible version of ListView in Android) with refreshing,loading more,animation and many other features.

UltimateRecyclerView Master branch: Dev branch: Project website:https://github.com/cymcsg/UltimateRecyclerView Description UltimateRecyclerView is a R

MarshalChen 7.2k Jan 2, 2023