通过对ListView简单的扩展、再封装,即可实现无限层级的树控件TreeView。
1 package cn.asiontang.nleveltreelistview; 2 3 import android.annotation.TargetApi; 4 import android.content.Context; 5 import android.os.Build; 6 import android.util.AttributeSet; 7 import android.view.View; 8 import android.widget.AdapterView; 9 import android.widget.ListAdapter; 10 import android.widget.ListView; 11 12 /** 13 * 支持N(无限)层级的树列表结构 14 * 15 * <p>参考资料:</p> 16 * <ul> 17 * <li> 18 * <a href="http://item.congci.com/item/android-wuxian-ji-shuzhuang-jiegou">Android无限级树状结构 - 19 * Android 20 * - 从此网</a> 21 * </li> 22 * </ul> 23 * 24 * @author AsionTang 25 * @since 2016年6月1日 18:38:43 26 */ 27 @SuppressWarnings("unused") 28 public class NLevelTreeView extends ListView 29 { 30 private OnTreeNodeClickListener mOnTreeNodeClickListener; 31 32 public NLevelTreeView(final Context context) 33 { 34 super(context); 35 this.init(); 36 } 37 38 public NLevelTreeView(final Context context, final AttributeSet attrs) 39 { 40 super(context, attrs); 41 this.init(); 42 } 43 44 public NLevelTreeView(final Context context, final AttributeSet attrs, final int defStyleAttr) 45 { 46 super(context, attrs, defStyleAttr); 47 this.init(); 48 } 49 50 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 51 public NLevelTreeView(final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes) 52 { 53 super(context, attrs, defStyleAttr, defStyleRes); 54 this.init(); 55 } 56 57 private void init() 58 { 59 } 60 61 public void setAdapter(final NLevelTreeNodeAdapter adapter) 62 { 63 super.setAdapter(adapter); 64 65 //让 NLevelTreeNodeAdapter 处理 节点 收缩展开 动作 66 super.setOnItemClickListener(adapter); 67 68 //处理当 叶子节点 被点击后的事件 回调。 69 adapter.setOuterOnItemClickListener(new OnItemClickListener() 70 { 71 @Override 72 public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) 73 { 74 if (NLevelTreeView.this.mOnTreeNodeClickListener != null) 75 { 76 final NLevelTreeNode item = (NLevelTreeNode) parent.getItemAtPosition(position); 77 NLevelTreeView.this.mOnTreeNodeClickListener.onTreeNodeClick(item); 78 } 79 } 80 }); 81 } 82 83 /** 84 * 必须使用继承自 NLevelTreeNodeAdapter 的 适配器,否则会出现异常。 85 */ 86 @Override 87 public void setAdapter(final ListAdapter adapter) 88 { 89 if (adapter instanceof NLevelTreeNodeAdapter) 90 this.setAdapter((NLevelTreeNodeAdapter) adapter); 91 else 92 throw new RuntimeException("For NLevelTreeView, use setAdapter(NLevelTreeNodeAdapter) instead of setAdapter(ListAdapter)"); 93 } 94 95 /** 96 * 不支持使用此回调方式 97 */ 98 @Override 99 @Deprecated 100 public void setOnItemClickListener(final OnItemClickListener listener) 101 { 102 //实际的事件回调在setAdapter里设置,由 setOnTreeNodeClickListener 处理。 103 //super.setOuterOnItemClickListener(listener); 104 105 throw new RuntimeException("For NLevelTreeView, use setOnTreeNodeClickListener() instead of setOnItemClickListener()"); 106 } 107 108 /** 109 * 默认只支持叶子节点的Click事件 110 */ 111 public void setOnTreeNodeClickListener(final OnTreeNodeClickListener listener) 112 { 113 this.mOnTreeNodeClickListener = listener; 114 } 115 116 /** 117 * 默认只支持叶子节点的Click事件 118 */ 119 public interface OnTreeNodeClickListener 120 { 121 /** 122 * 默认只支持叶子节点的Click事件 123 */ 124 void onTreeNodeClick(NLevelTreeNode node); 125 } 126 }