-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to build a tree from dynamic data? #4
Comments
For dynamic data, we recommend using TreeNodeGenerator |
Is there an example for this? @dingyi222666 |
Like this. |
Thanks, @dingyi222666 |
Yes, but I still recommend using |
Ok, got, thanks |
No, it may not be necessary to update the API of the val item = Item(
"head", listOf(
Item(
"1", listOf(
Item("11", listOf()),
Item("12", listOf())
)
),
Item(
"2", listOf(
Item("21", listOf()),
Item("22", listOf())
)
)
)
)
fun DataSourceScope<Item>.getSubBranches(item: Item): List<Unit> {
val branches: MutableList<Unit> = mutableListOf()
item.childItems.forEach {
branches.add(
Branch(it.name, item) {
getSubBranches(it)
}
)
}
return branches
}
// The dataCreator is not needed because the data is already provided in Branch(name:String,data,T).
// The dataCreator is called only when the set data is null.
return buildTree {
getSubBranches(item)
} |
This is an example of using private fun createTree(): Tree<Item> {
val item = Item(
"head", listOf(
Item(
"1", listOf(
Item("11", listOf()),
Item("12", listOf())
)
),
Item(
"2", listOf(
Item("21", listOf()),
Item("22", listOf())
)
)
)
)
return Tree.createTree<Item>().apply {
generator = ItemTreeNodeGenerator(item)
initTree()
}
}
inner class ItemTreeNodeGenerator(
private val rootItem: Item
) : TreeNodeGenerator<Item> {
override suspend fun fetchNodeChildData(targetNode: TreeNode<Item>): Set<Item> {
return targetNode.requireData().childItems.toSet()
}
override fun createNode(
parentNode: TreeNode<Item>,
currentData: Item,
tree: AbstractTree<Item>
): TreeNode<Item> {
return TreeNode(
data = currentData,
depth = parentNode.depth + 1,
name = currentData.name,
id = tree.generateId(),
hasChild = currentData.childItems.isNotEmpty(),
// It should be taken from the Item
isChild = currentData.childItems.isNotEmpty(),
expand = false
)
}
override fun createRootNode(): TreeNode<Item> {
return TreeNode(
data = rootItem,
depth = 0,
name = rootItem.name,
id = Tree.ROOT_NODE_ID,
hasChild = true,
isChild = true
)
}
} |
@dingyi222666 thanks for your kind help |
@dingyi222666 If there are several root nodes, then how can I implement it?
|
If you are using private fun createTree(): Tree<Item> {
val items =
listOf(
Item(
"root1", listOf(
Item("1", listOf(
Item("11", listOf()),
Item("12", listOf())
)),
Item("2", listOf(
Item("21", listOf()),
Item("22", listOf())
))
)
),
Item(
"root2", listOf(
Item("1", listOf(
Item("11", listOf()),
Item("12", listOf())
)),
Item("2", listOf(
Item("21", listOf()),
Item("22", listOf())
))
)
)
)
val rootItem = Item("root_not_show", items)
return Tree.createTree<Item>().apply {
generator = ItemTreeNodeGenerator(rootItem)
initTree()
}
}
inner class ItemTreeNodeGenerator(
private val rootItem: Item
) : TreeNodeGenerator<Item> {
override suspend fun fetchNodeChildData(targetNode: TreeNode<Item>): Set<Item> {
return targetNode.requireData().childItems.toSet()
}
override fun createNode(
parentNode: TreeNode<Item>,
currentData: Item,
tree: AbstractTree<Item>
): TreeNode<Item> {
return TreeNode(
data = currentData,
depth = parentNode.depth + 1,
name = currentData.name,
id = tree.generateId(),
hasChild = currentData.childItems.isNotEmpty(),
// It should be taken from the Item
isChild = currentData.childItems.isNotEmpty(),
expand = false
)
}
override fun createRootNode(): TreeNode<Item> {
return TreeNode(
data = rootItem,
// Set to -1 to not show the root node
depth = -1,
name = rootItem.name,
id = Tree.ROOT_NODE_ID,
hasChild = true,
isChild = true
)
}
} |
If you use private fun createTree(): Tree<DataSource<Item>> {
val items =
listOf(
Item(
"root1", listOf(
Item("1", listOf(
Item("11", listOf()),
Item("12", listOf())
)),
Item("2", listOf(
Item("21", listOf()),
Item("22", listOf())
))
)
),
Item(
"root2", listOf(
Item("1", listOf(
Item("11", listOf()),
Item("12", listOf())
)),
Item("2", listOf(
Item("21", listOf()),
Item("22", listOf())
))
)
)
)
fun DataSourceScope<Item>.getSubBranches(items:List<Item>) {
items.forEach {
Branch(it.name, it) {
getSubBranches(it.childItems)
}
}
}
return buildTree {
getSubBranches(items)
}
} |
Thank you, @dingyi222666 |
@dingyi222666 |
|
that doesn't work, i'm loading a folder from the device, with the functionality of creating, delete, rename etc, which i have added already and it works fine, but calling |
Can you show me how your |
@dingyi222666 |
No, it should call |
@dingyi222666 the |
@BlueCatSoftware The data flow should look like this raw data -> node generator -> tree -> treeView |
this works but doesn't retain the tree hierarchy, it literally reloads and collapses the tree. At this point an example will definitely help |
yeah i am aware of this method, it fetches the data. i'm still confused, the problem is there's no method to update the node's data. i know how to fetch nodes data but doesn't know how to manipulate it. |
@BlueCatSoftware Actually, I recommend you to use File directly, so that the node generator only needs |
i get your point, here is my problem Sorry for too much question lol. |
@BlueCatSoftware Let me give you a sample code. class FileTreeNodeGenerator(val rootItem: FileSet) : TreeNodeGenerator<FileSet> {
override fun createNode(
parentNode: TreeNode<FileSet>,
currentData: FileSet,
tree: AbstractTree<FileSet>
): TreeNode<FileSet> {
return TreeNode(
currentData,
parentNode.depth + 1,
currentData.file.name,
tree.generateId(),
currentData.subDir.isNotEmpty(),
currentData.subDir.isNotEmpty(),
false
)
}
override suspend fun fetchNodeChildData(targetNode: TreeNode<FileSet>): Set<FileSet> = withContext(Dispatcher.IO) {
// refresh data here
val fileSet = targetNode.requireData()
fileSet.subDir.clear()
for (file in dir.listFiles()) {
fileSet.subDir.add(FileSet(fileSet))
}
fileSet.subDir.toSet()
}
override fun createRootNode(): TreeNode<FileSet> {
return TreeNode(
data = rootItem,
depth = 0,
name = rootItem.file.name,
id = Tree.ROOT_NODE_ID,
hasChild = true,
isChild = true
)
}
}
data class FileSet(val file: File, val subDir: MutableSet<FileSet> = mutableSetOf()) |
@dingyi222666 |
override suspend fun fetchNodeChildData(targetNode: TreeNode<FileSet>): Set<FileSet> =
withContext(Dispatchers.IO) {
val set = targetNode.requireData().subDir
set.clear()
val files = targetNode.requireData().file.listFiles() ?: return@withContext set
for (file in files) {
when {
file.isFile -> set.add(FileSet(file))
file.isDirectory -> {
val tempSet = mutableSetOf<FileSet>().apply {
addAll(transverseTree(file))
}
set.add(FileSet(file, subDir = tempSet))
}
}
}
return@withContext set
} this definitely worked for me, i didn't know |
Let’s take another look at this data flow: raw data -> node generator -> tree -> treeView. |
@BlueCatSoftware I'm soon to release version 1.2.0, which will improve some things, so feel free to update and use it. |
I have dynamic data, I want to build a tree from it.
Let me put an example.
I have my own
Item
I use dynamic Item.
For example:
How can I create tree for this dynamic item?
I tried the above code, but I am getting 1 dimension tree and there are no subbranches.
How can I approach it?
Thank you!
The text was updated successfully, but these errors were encountered: