Open simphonydeveloper opened 3 days ago
Your TreeNode2
class should not contain the parent
field. Remove it and try again.
thank you, it's working. i want to know,Can this component work well with Switch? Thanks again.
It's okay. Check out the code https://github.com/dingyi222666/TreeView/blob/1706aca5112f2760c20a0f3f5ad2f3b73a4def42/treeview/src/main/kotlin/io/github/dingyi222666/view/treeview/TreeView.kt#L912 that supports components that implement the Checkable interface.
I haven't implemented getCheckableView. I want to update all child nodes below when changing a parent node, but I couldn't find a parent class in ViewBinding that can operate on all data properties or methods. Perhaps what I did was wrong.
Thanks
First implement getCheckableView
.
Set the selection mode to MULTIPLE_WITH_CHILDREN
, then operate on the treeView by calling selectNode to select the corresponding parent node. When this happens, the child nodes will also be updated.
Sorry,I have reviewed your example, and you executed it through the menu item. How do I perform this operation on the switch of a certain node?
Thanks
class ViewBinder : TreeViewBinder<TreeNode2>(),
TreeNodeEventListener<TreeNode2> {
override fun createView(parent: ViewGroup, viewType: Int): View {
val layoutInflater = LayoutInflater.from(parent.context)
return if (viewType == 1) {
ItemDirBinding.inflate(layoutInflater, parent, false).root
} else {
ItemFileBinding.inflate(layoutInflater, parent, false).root
}
}
override fun getItemViewType(node: TreeNode<TreeNode2>): Int {
if (node.data!!.children.isNotEmpty()) {
return 1
}
return 0
}
override fun bindView(
holder: TreeView.ViewHolder,
node: TreeNode<TreeNode2>,
listener: TreeNodeEventListener<TreeNode2>
) {
if (node.data!!.children.isNotEmpty()) {
applyDir(holder, node)
} else {
applyFile(holder, node)
}
val itemView = holder.itemView.findViewById<Space>(R.id.space)
// (getCheckableView(node, holder) as Switch).apply {
// isVisible = node.selected
// isSelected = node.selected
// }
itemView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
width = node.depth * 22
}
}
override fun getCheckableView(
node: TreeNode<TreeNode2>,
holder: TreeView.ViewHolder
): Checkable? {
return if (node.isChild) {
ItemDirBinding.bind(holder.itemView).switchOn
} else {
ItemFileBinding.bind(holder.itemView).switchOn
}
//return super.getCheckableView(node, holder)
}
private fun applyFile(holder: TreeView.ViewHolder, node: TreeNode<TreeNode2>) {
val binding = ItemFileBinding.bind(holder.itemView)
binding.tvName.text = node.data!!.name.toString()
}
private fun applyDir(holder: TreeView.ViewHolder, node: TreeNode<TreeNode2>) {
val binding = ItemDirBinding.bind(holder.itemView)
binding.tvName.text = node.data!!.name.toString()
binding.switchOn.isChecked = node.data!!.isSwitchOn
binding.switchOn.setOnCheckedChangeListener(object :
CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) {
// node.data!!.isSwitchOn = p1
// if (node.hasChild) {
// flattenTree(node.data!!.children, p1)
// }
/// bad code
lifecycleScope.launch {
binding.treeview.apply {
// select node and it's children
selectionMode = TreeView.SelectionMode.MULTIPLE_WITH_CHILDREN
selectNode(binding.treeview.tree.rootNode, true)
expandAll()
selectionMode = TreeView.SelectionMode.MULTIPLE_WITH_CHILDREN
}
}
}
})
binding
.ivArrow
.animate()
.rotation(if (node.expand) 180f else 0f)
.setDuration(200)
.start()
}
fun flattenTree(treeNodes: List<TreeNode2>, isSwitchOn: Boolean): List<TreeNode2> {
val result = mutableListOf<TreeNode2>()
for (node in treeNodes) {
node.isSwitchOn = isSwitchOn
result.add(node)
if (node.children.isNotEmpty()) {
val flattenedChildren = flattenTree(node.children, isSwitchOn)
result.addAll(flattenedChildren)
}
}
return result
}
// fun flattenTree(): List<TreeNode2> {
// val result = mutableListOf<TreeNode2>()
// for (node in treeNodes) {
// node.isSwitchOn = isSwitchOn
// result.add(node)
// if (node.children.isNotEmpty()) {
// val flattenedChildren = flattenTree(node.children, isSwitchOn)
// result.addAll(flattenedChildren)
// }
// }
// return result
// }
override fun onClick(node: TreeNode<TreeNode2>, holder: TreeView.ViewHolder) {
if (node.data!!.children.isNotEmpty()) {
applyDir(holder, node)
} else {
//Toast.makeText(this@MainActivity, "Clicked ${node.name}", Toast.LENGTH_LONG).show()
}
}
override fun onToggle(
node: TreeNode<TreeNode2>,
isExpand: Boolean,
holder: TreeView.ViewHolder
) {
applyDir(holder, node)
}
}
class ItemTreeNodeGenerator(
private val rootItem: TreeNode2
) : TreeNodeGenerator<TreeNode2> {
suspend fun fetchNodeChildData(targetNode: TreeNode<TreeNode2>): Set<TreeNode2> {
return targetNode.requireData().children.toSet()
}
override fun createNode(
parentNode: TreeNode<TreeNode2>,
currentData: TreeNode2,
tree: AbstractTree<TreeNode2>
): TreeNode<TreeNode2> {
return TreeNode(
data = currentData,
depth = parentNode.depth + 1,
name = currentData.name,
id = tree.generateId(),
hasChild = currentData.children.isNotEmpty(),
// It should be taken from the Item
isChild = currentData.children.isNotEmpty(),
expand = false
)
}
override fun createRootNode(): TreeNode<TreeNode2> {
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
)
}
override suspend fun fetchChildData(targetNode: TreeNode<TreeNode2>): Set<TreeNode2> {
return targetNode.requireData().children.toSet()
}
}
Upload all your example code to github as a repository, I'll read and modify it later.
repository: https://github.com/simphonydeveloper/AndroidTreeViewSample.git
Thanks
Okay. You can check out my code example: https://github.com/dingyi222666/AndroidTreeViewSample
Thank you!
Great code, I have implemented the simultaneous selection and closure of Switch according to your code.
When all child nodes are selected, the parent node is also selected. This operation needs to be completed in the class DataSource
, right?
⭐
You need to change on both the DataSource
and the Tree
.
Part of my inspiration comes from here. https://github.com/dingyi222666/TreeView/issues/4 It seems to have entered an infinite loop problem.
this is my version io.github.dingyi222666:treeview:1.3.1
Thanks ERROR: