Skip to content

Commit 944104f

Browse files
committed
Merge branch 'tmp' into main
2 parents ca323d1 + a4b4dd6 commit 944104f

8 files changed

Lines changed: 128 additions & 40 deletions

File tree

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

library/src/main/java/com/gyso/treeview/GysoTreeView.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public GysoTreeView(@NonNull Context context, @Nullable AttributeSet attrs, int
4545
treeViewContainer.setLayoutParams(layoutParams);
4646
addView(treeViewContainer);
4747
treeViewGestureHandler = new TouchEventHandler(getContext(), treeViewContainer);
48+
49+
//Note: do not set setKeepInViewport(true), there still has bug
4850
treeViewGestureHandler.setKeepInViewport(false);
4951

5052
//set animate default

library/src/main/java/com/gyso/treeview/TreeViewContainer.java

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel)
412412
mTreeModel.addNode(targetHolderNode,releasedChildHolderNode);
413413
mTreeModel.calculateTreeNodesDeep();
414414
if(isAnimateMove()){
415-
recordAnchorLocationOnViewPort(false,targetHolderNode);
415+
recordAnchorLocationOnViewPort(false,false,targetHolderNode);
416416
}
417417
requestLayout();
418418
}else{
@@ -561,7 +561,7 @@ public void onDataSetChange(){
561561
public void onAddNodes(NodeModel<?> parent, NodeModel<?>... childNodes) {
562562
if(adapter!=null){
563563
if(isAnimateAdd()){
564-
recordAnchorLocationOnViewPort(false, parent);
564+
recordAnchorLocationOnViewPort(false, false,parent);
565565
}
566566
mTreeModel.addNode(parent,childNodes);
567567
mTreeModel.calculateTreeNodesDeep();
@@ -572,52 +572,73 @@ public void onAddNodes(NodeModel<?> parent, NodeModel<?>... childNodes) {
572572
}
573573

574574
@Override
575-
public void onRemoveNodes(NodeModel<?>... nodeModels) {
575+
public void onRemoveNode(NodeModel<?> nodeModel) {
576+
innerRemoveNode(nodeModel, false);
577+
}
578+
579+
@Override
580+
public void onRemoveChildNodes(NodeModel<?> parentNode) {
581+
innerRemoveNode(parentNode,true);
582+
}
583+
584+
private void innerRemoveNode(NodeModel<?> nodeModel, boolean isRemoveChildNodesOnly){
576585
if(adapter!=null){
577586
if(isAnimateRemove()){
578-
recordAnchorLocationOnViewPort(true, nodeModels);
579-
}
580-
for (NodeModel<?> nodeToRemove : nodeModels) {
581-
adapter.getTreeModel().removeNode(nodeToRemove.getParentNode(), nodeToRemove);
582-
}
583-
mTreeModel.calculateTreeNodesDeep();
584-
if(isAnimateRemove()){
585-
requestLayout();
587+
recordAnchorLocationOnViewPort(true,isRemoveChildNodesOnly ,nodeModel);
588+
if(isRemoveChildNodesOnly){
589+
nodeModel.traverseDirectChildren(next->adapter.getTreeModel().removeNode(nodeModel, next));
590+
}else{
591+
adapter.getTreeModel().removeNode(nodeModel.getParentNode(), nodeModel);
592+
}
586593
}else{
587-
for (NodeModel<?> nodeToRemove : nodeModels) {
588-
nodeToRemove.selfTraverse(next -> {
589-
//remove view
590-
TreeViewHolder<?> holder = getTreeViewHolder(next);
591-
if(holder != null){
592-
removeView(holder.getView());
593-
recycleHolder(holder);
594-
}
595-
});
594+
if(isRemoveChildNodesOnly){
595+
nodeModel.traverseExcludeSelf(this::removeViewByNode);
596+
nodeModel.traverseDirectChildren(next->adapter.getTreeModel().removeNode(nodeModel, next));
597+
}else{
598+
nodeModel.traverseIncludeSelf(this::removeViewByNode);
599+
adapter.getTreeModel().removeNode(nodeModel.getParentNode(), nodeModel);
596600
}
597601
}
602+
mTreeModel.calculateTreeNodesDeep();
603+
requestLayout();
604+
}
605+
}
606+
607+
/**
608+
* Remove View By Node
609+
* @param nodeModel node to remove the view
610+
*/
611+
private void removeViewByNode(NodeModel<?> nodeModel){
612+
//remove view
613+
TreeViewHolder<?> holder = getTreeViewHolder(nodeModel);
614+
if(holder != null){
615+
removeView(holder.getView());
616+
recycleHolder(holder);
598617
}
599618
}
600619

601620
/**
602621
* Prepare moving, adding or removing nodes, record the last one node as an anchor node on view port, so that make it looks smooth change
603-
* Note:
604-
* The last one will been choose as target node.
605-
*
606-
* @param nodeModels nodes[nodes.length-1] as the target one
622+
* @param targetNode the target one
607623
*/
608-
private void recordAnchorLocationOnViewPort(boolean isRemove, NodeModel<?>... nodeModels) {
609-
if(nodeModels==null || nodeModels.length==0){
624+
private void recordAnchorLocationOnViewPort(boolean isRemove, boolean isRemoveChildrenOnly, NodeModel<?> targetNode) {
625+
if(targetNode==null){
610626
return;
611627
}
612-
NodeModel<?> targetNode = nodeModels[nodeModels.length-1];
613-
if(targetNode!=null && isRemove){
628+
if(isRemove){
614629
//if remove, parent will be the target node
615630
Map<NodeModel<?>,View> removeNodeMap = new HashMap<>();
616-
targetNode.selfTraverse(node -> {
617-
removeNodeMap.put(node,getTreeViewHolder(node).getView());
618-
});
631+
if(isRemoveChildrenOnly){
632+
targetNode.traverseExcludeSelf(node -> {
633+
removeNodeMap.put(node,getTreeViewHolder(node).getView());
634+
});
635+
}else{
636+
targetNode.traverseIncludeSelf(node -> {
637+
removeNodeMap.put(node,getTreeViewHolder(node).getView());
638+
});
639+
targetNode = targetNode.getParentNode();
640+
}
619641
setTag(R.id.mark_remove_views,removeNodeMap);
620-
targetNode = targetNode.getParentNode();
621642
}
622643
if(targetNode!=null){
623644
TreeViewHolder<?> targetHolder = getTreeViewHolder(targetNode);

library/src/main/java/com/gyso/treeview/TreeViewEditor.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,18 @@ public void addChildNodes(NodeModel<?> parent, NodeModel<?>... childNodes) {
6868
public void removeNode(NodeModel<?> nodeToRemove){
6969
TreeViewContainer container = getContainer();
7070
if(container!=null){
71-
container.onRemoveNodes(nodeToRemove);
71+
container.onRemoveNode(nodeToRemove);
72+
}
73+
}
74+
75+
/**
76+
* remove children nodes by parent node
77+
* @param parentNode parent node to remove children
78+
*/
79+
public void removeNodeChildren(NodeModel<?> parentNode){
80+
TreeViewContainer container = getContainer();
81+
if(container!=null){
82+
container.onRemoveChildNodes(parentNode);
7283
}
7384
}
7485
}

library/src/main/java/com/gyso/treeview/listener/TreeViewNotifier.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
*/
1313
public interface TreeViewNotifier{
1414
void onDataSetChange();
15-
void onRemoveNodes(NodeModel<?>... nodeModel);
15+
void onRemoveNode(NodeModel<?>nodeModel);
16+
void onRemoveChildNodes(NodeModel<?> parentNode);
1617
void onItemViewChange(NodeModel<?> nodeModel);
1718
void onAddNodes(NodeModel<?> parent, NodeModel<?>... childNodes);
1819
}

library/src/main/java/com/gyso/treeview/model/NodeModel.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import androidx.annotation.Nullable;
55

66
import java.io.Serializable;
7+
import java.util.Iterator;
78
import java.util.LinkedList;
89
import java.util.List;
910
import java.util.Stack;
@@ -128,29 +129,60 @@ private boolean addChildNode(NodeModel<T> aChild){
128129
* traverse
129130
* @param node to deal node
130131
*/
131-
public void traverse(NodeModel<T> node, INext<T> next){
132+
private void traverse(NodeModel<T> node, INext<T> next){
133+
traverse(node,next,true);
134+
}
135+
136+
private void traverse(NodeModel<T> node, INext<T> next, boolean isIncludeSelf){
132137
if(node==null || next==null){
133138
return;
134139
}
135140
Stack<NodeModel<T>> stack = new Stack<>();
136141
stack.add(node);
137142
while (!stack.isEmpty()) {
138143
NodeModel<T> tmp = stack.pop();
139-
next.next(tmp);
144+
if(isIncludeSelf){
145+
next.next(tmp);
146+
}else if(tmp!=this){
147+
next.next(tmp);
148+
}
140149
LinkedList<NodeModel<T>> childNodes = tmp.getChildNodes();
141150
stack.addAll(childNodes);
142151
}
143152
}
153+
/**
154+
* traverse all sub node include self
155+
* @param next callback
156+
*/
157+
public void traverseIncludeSelf(INext<T> next){
158+
if(next==null){
159+
return;
160+
}
161+
traverse(this,next,true);
162+
}
144163

145164
/**
146-
* traverse bys self
165+
* traverse all sub node exclude self
147166
* @param next callback
148167
*/
149-
public void selfTraverse(INext<T> next){
168+
public void traverseExcludeSelf(INext<T> next){
150169
if(next==null){
151170
return;
152171
}
153-
traverse(this,next);
172+
traverse(this,next,false);
173+
}
174+
175+
/**
176+
* traverse only direct children
177+
* @param next callback
178+
*/
179+
public void traverseDirectChildren(INext<T> next){
180+
if(next==null){
181+
return;
182+
}
183+
for (NodeModel<T> childNode : new LinkedList<>(childNodes)) {
184+
next.next(childNode);
185+
}
154186
}
155187

156188
public void removeChildNode(NodeModel<T> aChild){

sample/src/main/java/com/gyso/gysotreeviewapplication/MainActivity.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class MainActivity extends AppCompatActivity {
3333
private NodeModel<Animal> targetNode;
3434
private AtomicInteger atomicInteger = new AtomicInteger();
3535
private Handler handler = new Handler();
36+
private NodeModel<Animal> parentToRemoveChildren = null;
3637
@Override
3738
protected void onCreate(Bundle savedInstanceState) {
3839
super.onCreate(savedInstanceState);
@@ -116,6 +117,11 @@ void doYourOwnJobs(TreeViewEditor editor, AnimalTreeViewAdapter adapter){
116117
editor.removeNode(toRemoveNode);
117118
});
118119

120+
//remove node
121+
binding.removeChildrenBt.setOnClickListener(v->{
122+
editor.removeNodeChildren(parentToRemoveChildren);
123+
});
124+
119125
adapter.setOnItemListener((item, node)-> {
120126
Animal animal = node.getValue();
121127
Toast.makeText(this,"you click the head of "+animal,Toast.LENGTH_SHORT).show();
@@ -203,6 +209,7 @@ private void setData(AnimalTreeViewAdapter adapter){
203209
treeModel.addNode(sub1,sub2);
204210
treeModel.addNode(sub0,sub4,sub5);
205211
treeModel.addNode(sub4,sub6);
212+
parentToRemoveChildren = sub0;
206213
// treeModel.addNode(sub5,sub7,sub8);
207214
// treeModel.addNode(sub6,sub9,sub10,sub11);
208215
// treeModel.addNode(sub3,sub12,sub13);

sample/src/main/res/layout/activity_main.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@
6767
android:foreground="?attr/selectableItemBackground"
6868
app:layout_constraintLeft_toRightOf="@+id/add_nodes_bt"
6969
app:layout_constraintTop_toTopOf="parent" />
70+
<TextView
71+
android:id="@+id/remove_children_bt"
72+
android:layout_width="wrap_content"
73+
android:layout_height="wrap_content"
74+
android:layout_margin="5dp"
75+
android:padding="6dp"
76+
android:checked="false"
77+
android:text="REMOVE C"
78+
android:textStyle="bold"
79+
android:textColor="@android:color/white"
80+
android:background="@drawable/drag_mode_bg"
81+
android:foreground="?attr/selectableItemBackground"
82+
app:layout_constraintLeft_toRightOf="@+id/add_nodes_bt"
83+
app:layout_constraintTop_toTopOf="parent" />
7084
</LinearLayout>
7185
<com.google.android.material.switchmaterial.SwitchMaterial
7286
android:id="@+id/drag_edit_mode_rd"

0 commit comments

Comments
 (0)