├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── sjl │ │ └── treeview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── sjl │ │ │ └── treeview │ │ │ ├── MainActivity.java │ │ │ └── bean │ │ │ ├── BranchNode.java │ │ │ ├── BranchViewBinder.java │ │ │ ├── LeafNode.java │ │ │ ├── LeafViewBinder.java │ │ │ ├── RootNode.java │ │ │ └── RootViewBinder.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_checked.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_tree_node.xml │ │ └── ic_uncheck.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── item_branch.xml │ │ ├── item_leaf.xml │ │ └── item_root.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── sjl │ └── treeview │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libtreeview ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── sjl │ │ └── libtreeview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── sjl │ │ │ └── libtreeview │ │ │ ├── TreeViewAdapter.java │ │ │ └── bean │ │ │ ├── LayoutItem.java │ │ │ ├── TreeNode.java │ │ │ └── TreeViewBinder.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── sjl │ └── libtreeview │ └── ExampleUnitTest.java ├── settings.gradle └── show.gif /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | build 4 | .idea 5 | /local.properties 6 | /.idea/workspace.xml 7 | /.idea/libraries 8 | .DS_Store 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TreeView 2 | 这是一个功能多样的自定义树形列表,在使用RecyclerView实现树形列表,并在其基础上附加了一些额外功能。 3 | 4 | **基本功能:** 5 | - 展开收拢,收拢后保持子节点展开收拢状态(1.0.1实现) 6 | - 响应点击事件(1.0.1实现) 7 | 8 | **附加功能:** 9 | - 自定义每个节点的布局,自定义每个节点所保存的数据(1.1.0实现) 10 | - 选中功能,响应选中事件,可设置选中子节点后是否选中父节点(1.1.0实现) 11 | - 全部展开(展开列表中数据,不响应节点展开事件)和全部收拢功能(1.1.0实现) 12 | - 将展开收拢细分成(1.2.0实现): 13 | - 点击展开收拢后事件响应toggleClick(可在此请求该节点下孩子节点数据,并添加到当前结点下) 14 | - 列表展开或收拢toggle 15 | - 展开后事件响应toggled(节点箭头旋转等) 16 | 17 | ## 添加依赖 18 | 仓库 19 | ``` 20 | allprojects { 21 | repositories { 22 | ... 23 | maven { url 'https://jitpack.io' } 24 | } 25 | } 26 | ``` 27 | ([最新版本](https://github.com/q1113225201/TreeView/releases/latest)) 28 | 29 | ``` 30 | compile 'com.github.q1113225201:TreeView:1.2.0' 31 | ``` 32 | 33 | 具体使用可参考[博客](http://blog.csdn.net/q1113225201/article/details/79328247)或[项目中MainActivity.java](https://github.com/q1113225201/TreeView/blob/master/app/src/main/java/com/sjl/treeview/MainActivity.java) 34 | 35 | ## 效果展示 36 | ![url](show.gif) 37 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | defaultConfig { 6 | applicationId "com.sjl.treeview" 7 | minSdkVersion 16 8 | targetSdkVersion 26 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(include: ['*.jar'], dir: 'libs') 23 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 24 | testImplementation 'junit:junit:4.12' 25 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 26 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 27 | implementation project(':libtreeview') 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/sjl/treeview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.sjl.treeview; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.sjl.treeview", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/treeview/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.sjl.treeview; 2 | 3 | import android.app.Activity; 4 | import android.app.ProgressDialog; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.text.Editable; 10 | import android.text.TextUtils; 11 | import android.text.TextWatcher; 12 | import android.view.View; 13 | import android.widget.CompoundButton; 14 | import android.widget.EditText; 15 | import android.widget.Toast; 16 | import android.widget.ToggleButton; 17 | 18 | import com.sjl.libtreeview.TreeViewAdapter; 19 | import com.sjl.libtreeview.bean.LayoutItem; 20 | import com.sjl.libtreeview.bean.TreeNode; 21 | import com.sjl.libtreeview.bean.TreeViewBinder; 22 | import com.sjl.treeview.bean.BranchNode; 23 | import com.sjl.treeview.bean.BranchViewBinder; 24 | import com.sjl.treeview.bean.LeafNode; 25 | import com.sjl.treeview.bean.LeafViewBinder; 26 | import com.sjl.treeview.bean.RootNode; 27 | import com.sjl.treeview.bean.RootViewBinder; 28 | 29 | import java.util.ArrayList; 30 | import java.util.Arrays; 31 | import java.util.List; 32 | 33 | public class MainActivity extends Activity { 34 | private static final String TAG = "MainActivity"; 35 | private RecyclerView rv; 36 | private List list = new ArrayList<>(); 37 | private TreeViewAdapter adapter; 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_main); 43 | 44 | initView(); 45 | } 46 | 47 | private void initView() { 48 | rv = findViewById(R.id.rv); 49 | findViewById(R.id.btnLoad).setOnClickListener(new View.OnClickListener() { 50 | @Override 51 | public void onClick(View v) { 52 | list.clear(); 53 | list.addAll(initRoot()); 54 | adapter.notifyData(list); 55 | } 56 | }); 57 | findViewById(R.id.btnOpenAll).setOnClickListener(new View.OnClickListener() { 58 | @Override 59 | public void onClick(View v) { 60 | adapter.openAll(); 61 | } 62 | }); 63 | findViewById(R.id.btnCloseAll).setOnClickListener(new View.OnClickListener() { 64 | @Override 65 | public void onClick(View v) { 66 | adapter.closeAll(); 67 | } 68 | }); 69 | ((ToggleButton) findViewById(R.id.tbChoose)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 70 | @Override 71 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 72 | adapter.setChangeParentCheck(isChecked); 73 | } 74 | }); 75 | ((EditText) findViewById(R.id.etKeyWord)).addTextChangedListener(new TextWatcher() { 76 | @Override 77 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { 78 | 79 | } 80 | 81 | @Override 82 | public void onTextChanged(CharSequence s, int start, int before, int count) { 83 | if(count!=0){ 84 | //adapter.searchList(s.toString()); 85 | } 86 | } 87 | 88 | @Override 89 | public void afterTextChanged(Editable s) { 90 | 91 | } 92 | }); 93 | TreeNode rootNode = new TreeNode<>(new RootNode("根节点")); 94 | TreeNode branchNode1 = new TreeNode<>(new BranchNode("枝节点1")); 95 | TreeNode branchNode2 = new TreeNode<>(new BranchNode("枝节点2")); 96 | // TreeNode leafNode1 = new TreeNode<>(new LeafNode("叶节点1")); 97 | // TreeNode leafNode2 = new TreeNode<>(new LeafNode("叶节点2")); 98 | // TreeNode leafNode3 = new TreeNode<>(new LeafNode("叶节点3")); 99 | 100 | rootNode.addChild(branchNode1); 101 | rootNode.addChild(branchNode2); 102 | // branchNode1.addChild(leafNode1); 103 | // branchNode2.addChild(leafNode2); 104 | // branchNode2.addChild(leafNode3); 105 | list.add(rootNode); 106 | initAdapter(); 107 | } 108 | 109 | private void initAdapter() { 110 | adapter = new TreeViewAdapter(list, Arrays.asList(new RootViewBinder(), new BranchViewBinder(), new LeafViewBinder())) { 111 | 112 | @Override 113 | public void toggleClick(TreeViewBinder.ViewHolder viewHolder, View view, boolean isOpen, TreeNode treeNode) { 114 | if(isOpen){ 115 | addNewNode(treeNode); 116 | }else{ 117 | adapter.lastToggleClickToggle(); 118 | } 119 | } 120 | 121 | @Override 122 | public void toggled(TreeViewBinder.ViewHolder viewHolder, View view, boolean isOpen, TreeNode treeNode) { 123 | viewHolder.findViewById(R.id.ivNode).setRotation(isOpen ? 90 : 0); 124 | } 125 | 126 | @Override 127 | public void checked(TreeViewBinder.ViewHolder viewHolder, View view, boolean checked, TreeNode treeNode) { 128 | 129 | } 130 | 131 | @Override 132 | public void itemClick(TreeViewBinder.ViewHolder viewHolder, View view, TreeNode treeNode) { 133 | String name = null; 134 | LayoutItem item = treeNode.getValue(); 135 | if (item instanceof RootNode) { 136 | name = ((RootNode) item).getName(); 137 | } else if (item instanceof BranchNode) { 138 | name = ((BranchNode) item).getName(); 139 | } else if (item instanceof LeafNode) { 140 | name = ((LeafNode) item).getName(); 141 | } 142 | Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show(); 143 | } 144 | }; 145 | rv.setLayoutManager(new LinearLayoutManager(this)); 146 | rv.setAdapter(adapter); 147 | } 148 | private void addNewNode(final TreeNode treeNode) { 149 | autoProgress(true); 150 | new Handler().postDelayed(new Runnable() { 151 | @Override 152 | public void run() { 153 | String name = null; 154 | LayoutItem item = treeNode.getValue(); 155 | if(item instanceof RootNode){ 156 | name = ((RootNode) item).getName(); 157 | } else if (item instanceof BranchNode) { 158 | name = ((BranchNode) item).getName(); 159 | } else if (item instanceof LeafNode) { 160 | name = ((LeafNode) item).getName(); 161 | } 162 | TreeNode leafNode1 = new TreeNode<>(new LeafNode(name+"新增叶1")); 163 | TreeNode leafNode2 = new TreeNode<>(new LeafNode(name+"新增叶2")); 164 | List list = treeNode.getChildNodes(); 165 | boolean hasLeaf = false; 166 | for (TreeNode child:list){ 167 | if(child.getValue() instanceof LeafNode){ 168 | hasLeaf = true; 169 | break; 170 | } 171 | } 172 | if(!hasLeaf) { 173 | treeNode.addChild(leafNode1); 174 | treeNode.addChild(leafNode2); 175 | } 176 | autoProgress(false); 177 | adapter.lastToggleClickToggle(); 178 | } 179 | },1000); 180 | } 181 | 182 | private ProgressDialog progressDialog; 183 | private void autoProgress(boolean show){ 184 | if(progressDialog==null){ 185 | progressDialog = new ProgressDialog(this); 186 | progressDialog.setMessage("正在加载数据。。。"); 187 | } 188 | if(show){ 189 | progressDialog.show(); 190 | }else{ 191 | progressDialog.dismiss(); 192 | } 193 | } 194 | 195 | /** 196 | * 初始化跟 197 | * 198 | * @return 199 | */ 200 | private List initRoot() { 201 | List rootList = new ArrayList<>(); 202 | for (int i = 0; i < 3; i++) { 203 | TreeNode node = new TreeNode<>(new RootNode("根" + i)); 204 | if (i % 2 == 0) { 205 | node.setChildNodes(initBranchs(node.getValue().getName())); 206 | } else { 207 | node.setChildNodes(initLeaves(node.getValue().getName())); 208 | } 209 | rootList.add(node); 210 | } 211 | return rootList; 212 | } 213 | 214 | int count = 5; 215 | 216 | /** 217 | * 初始化枝 218 | * 219 | * @param name 220 | * @return 221 | */ 222 | private List initBranchs(String name) { 223 | List branchList = new ArrayList<>(); 224 | for (int i = 0; i < 3; i++) { 225 | TreeNode node = new TreeNode<>(new BranchNode(name + "枝" + i)); 226 | if (i % 2 == 0) { 227 | node.setChildNodes(initLeaves(node.getValue().getName())); 228 | } else { 229 | if (count > 0) { 230 | count--; 231 | node.setChildNodes(initBranchs(node.getValue().getName())); 232 | } else { 233 | node.setChildNodes(initLeaves(node.getValue().getName())); 234 | } 235 | } 236 | branchList.add(node); 237 | } 238 | return branchList; 239 | } 240 | 241 | /** 242 | * 初始化叶 243 | * 244 | * @param name 245 | * @return 246 | */ 247 | private List initLeaves(String name) { 248 | List leafList = new ArrayList<>(); 249 | for (int i = 0; i < 3; i++) { 250 | TreeNode node = new TreeNode<>(new LeafNode(name + "叶" + i)); 251 | leafList.add(node); 252 | } 253 | return leafList; 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/treeview/bean/BranchNode.java: -------------------------------------------------------------------------------- 1 | package com.sjl.treeview.bean; 2 | 3 | import com.sjl.libtreeview.bean.LayoutItem; 4 | import com.sjl.treeview.R; 5 | 6 | /** 7 | * BranchNode 8 | * 9 | * @author 林zero 10 | * @date 2018/1/14 11 | */ 12 | 13 | public class BranchNode implements LayoutItem { 14 | private String name; 15 | 16 | public BranchNode(String name) { 17 | this.name = name; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | @Override 29 | public int getLayoutId() { 30 | return R.layout.item_branch; 31 | } 32 | 33 | @Override 34 | public int getToggleId() { 35 | return R.id.ivNode; 36 | } 37 | 38 | @Override 39 | public int getCheckedId() { 40 | return R.id.ivCheck; 41 | } 42 | 43 | @Override 44 | public int getClickId() { 45 | return R.id.tvName; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/treeview/bean/BranchViewBinder.java: -------------------------------------------------------------------------------- 1 | package com.sjl.treeview.bean; 2 | 3 | import android.view.View; 4 | import android.widget.ImageView; 5 | import android.widget.TextView; 6 | 7 | import com.sjl.libtreeview.bean.TreeNode; 8 | import com.sjl.libtreeview.bean.TreeViewBinder; 9 | import com.sjl.treeview.R; 10 | 11 | /** 12 | * BranchViewBinder 13 | * 14 | * @author 林zero 15 | * @date 2018/1/17 16 | */ 17 | 18 | public class BranchViewBinder extends TreeViewBinder { 19 | 20 | @Override 21 | public int getLayoutId() { 22 | return R.layout.item_branch; 23 | } 24 | 25 | @Override 26 | public int getToggleId() { 27 | return R.id.ivNode; 28 | } 29 | 30 | @Override 31 | public int getCheckedId() { 32 | return R.id.ivCheck; 33 | } 34 | 35 | @Override 36 | public int getClickId() { 37 | return R.id.tvName; 38 | } 39 | 40 | @Override 41 | public ViewHolder creatViewHolder(View itemView) { 42 | return new ViewHolder(itemView); 43 | } 44 | 45 | @Override 46 | public void bindViewHolder(ViewHolder holder, int position, TreeNode treeNode) { 47 | ((TextView) holder.findViewById(R.id.tvName)).setText(((BranchNode) treeNode.getValue()).getName()); 48 | holder.findViewById(R.id.ivNode).setRotation(treeNode.isExpanded() ? 90 : 0); 49 | ((ImageView) holder.findViewById(R.id.ivCheck)).setImageResource(treeNode.isChecked() ? R.drawable.ic_checked : R.drawable.ic_uncheck); 50 | holder.findViewById(R.id.llParent).setBackgroundColor(holder.itemView.getContext().getResources().getColor(treeNode.isChecked() ? R.color.gray : R.color.white)); 51 | } 52 | 53 | class ViewHolder extends TreeViewBinder.ViewHolder { 54 | public ViewHolder(View itemView) { 55 | super(itemView); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/treeview/bean/LeafNode.java: -------------------------------------------------------------------------------- 1 | package com.sjl.treeview.bean; 2 | 3 | import com.sjl.libtreeview.bean.LayoutItem; 4 | import com.sjl.treeview.R; 5 | 6 | /** 7 | * LeafNode 8 | * 9 | * @author 林zero 10 | * @date 2018/1/14 11 | */ 12 | 13 | public class LeafNode implements LayoutItem { 14 | private String name; 15 | 16 | public LeafNode(String name) { 17 | this.name = name; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | @Override 29 | public int getLayoutId() { 30 | return R.layout.item_leaf; 31 | } 32 | 33 | @Override 34 | public int getToggleId() { 35 | return 0; 36 | } 37 | 38 | @Override 39 | public int getCheckedId() { 40 | return R.id.ivCheck; 41 | } 42 | 43 | @Override 44 | public int getClickId() { 45 | return R.id.tvName; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/treeview/bean/LeafViewBinder.java: -------------------------------------------------------------------------------- 1 | package com.sjl.treeview.bean; 2 | 3 | import android.view.View; 4 | import android.widget.ImageView; 5 | import android.widget.TextView; 6 | 7 | import com.sjl.libtreeview.bean.TreeNode; 8 | import com.sjl.libtreeview.bean.TreeViewBinder; 9 | import com.sjl.treeview.R; 10 | 11 | /** 12 | * LeafViewBinder 13 | * 14 | * @author 林zero 15 | * @date 2018/1/17 16 | */ 17 | 18 | public class LeafViewBinder extends TreeViewBinder { 19 | @Override 20 | public int getLayoutId() { 21 | return R.layout.item_leaf; 22 | } 23 | 24 | @Override 25 | public int getToggleId() { 26 | return 0; 27 | } 28 | 29 | @Override 30 | public int getCheckedId() { 31 | return R.id.ivCheck; 32 | } 33 | 34 | @Override 35 | public int getClickId() { 36 | return R.id.tvName; 37 | } 38 | 39 | @Override 40 | public ViewHolder creatViewHolder(View itemView) { 41 | return new ViewHolder(itemView); 42 | } 43 | 44 | @Override 45 | public void bindViewHolder(ViewHolder holder, int position, TreeNode treeNode) { 46 | ((TextView) holder.findViewById(R.id.tvName)).setText(((LeafNode) treeNode.getValue()).getName()); 47 | ((ImageView) holder.findViewById(R.id.ivCheck)).setImageResource(treeNode.isChecked() ? R.drawable.ic_checked : R.drawable.ic_uncheck); 48 | holder.findViewById(R.id.llParent).setBackgroundColor(holder.itemView.getContext().getResources().getColor(treeNode.isChecked() ? R.color.gray : R.color.white)); 49 | } 50 | 51 | class ViewHolder extends TreeViewBinder.ViewHolder { 52 | public ViewHolder(View itemView) { 53 | super(itemView); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/treeview/bean/RootNode.java: -------------------------------------------------------------------------------- 1 | package com.sjl.treeview.bean; 2 | 3 | import com.sjl.libtreeview.bean.LayoutItem; 4 | import com.sjl.treeview.R; 5 | 6 | /** 7 | * RootNode 8 | * 9 | * @author 林zero 10 | * @date 2018/1/14 11 | */ 12 | 13 | public class RootNode implements LayoutItem { 14 | private String name; 15 | 16 | public RootNode(String name) { 17 | this.name = name; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | @Override 29 | public int getLayoutId() { 30 | return R.layout.item_root; 31 | } 32 | 33 | @Override 34 | public int getToggleId() { 35 | return R.id.ivNode; 36 | } 37 | 38 | @Override 39 | public int getCheckedId() { 40 | return R.id.ivCheck; 41 | } 42 | 43 | @Override 44 | public int getClickId() { 45 | return R.id.tvName; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/treeview/bean/RootViewBinder.java: -------------------------------------------------------------------------------- 1 | package com.sjl.treeview.bean; 2 | 3 | import android.view.View; 4 | import android.widget.ImageView; 5 | import android.widget.TextView; 6 | 7 | import com.sjl.libtreeview.bean.TreeNode; 8 | import com.sjl.libtreeview.bean.TreeViewBinder; 9 | import com.sjl.treeview.R; 10 | 11 | /** 12 | * RootViewBinder 13 | * 14 | * @author 林zero 15 | * @date 2018/1/17 16 | */ 17 | 18 | public class RootViewBinder extends TreeViewBinder { 19 | @Override 20 | public int getLayoutId() { 21 | return R.layout.item_root; 22 | } 23 | 24 | @Override 25 | public int getToggleId() { 26 | return R.id.ivNode; 27 | } 28 | 29 | @Override 30 | public int getCheckedId() { 31 | return R.id.ivCheck; 32 | } 33 | 34 | @Override 35 | public int getClickId() { 36 | return R.id.tvName; 37 | } 38 | 39 | @Override 40 | public ViewHolder creatViewHolder(View itemView) { 41 | return new ViewHolder(itemView); 42 | } 43 | 44 | @Override 45 | public void bindViewHolder(ViewHolder holder, int position, TreeNode treeNode) { 46 | ((TextView) holder.findViewById(R.id.tvName)).setText(((RootNode) treeNode.getValue()).getName()); 47 | holder.findViewById(R.id.ivNode).setRotation(treeNode.isExpanded() ? 90 : 0); 48 | ((ImageView) holder.findViewById(R.id.ivCheck)).setImageResource(treeNode.isChecked() ? R.drawable.ic_checked : R.drawable.ic_uncheck); 49 | holder.findViewById(R.id.llParent).setBackgroundColor(holder.itemView.getContext().getResources().getColor(treeNode.isChecked() ? R.color.gray : R.color.white)); 50 | } 51 | 52 | class ViewHolder extends TreeViewBinder.ViewHolder { 53 | 54 | public ViewHolder(View itemView) { 55 | super(itemView); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_checked.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tree_node.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_uncheck.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |