android中怎么自定义树形
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,android中怎么自定义树形,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。TreeView.java代码:package com.
千家信息网最后更新 2025年12月03日android中怎么自定义树形
android中怎么自定义树形,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
TreeView.java代码:
package com.tbx.android.widget;import java.util.ArrayList;public class TreeView extends ListView implements OnItemClickListener { private static String TAG = "TreeView"; List treeElements = null;// 所有节点集合 List currentElements = null;// 当前显示的节点集合 List tempElements = null;// 用于临时存储 HashMap> deleteMap = new HashMap>(); //用于存储要删除的子节点,以及间接子节点。 TreeViewAdapter adapter = null;// 用于数据填充 LastLevelItemClickListener itemClickCallBack;// 用户点击事件回调 public TreeView(final Context context, AttributeSet attrs) { super(context, attrs); Log.d(TAG, "create with TreeView(Context context, AttributeSet attrs)"); treeElements = new ArrayList(); currentElements = new ArrayList(); adapter = new TreeViewAdapter(context, currentElements); this.setAdapter(adapter); itemClickCallBack = new LastLevelItemClickListener() { @Override public void onLastLevelItemClick(int position,TreeViewAdapter adapter) { Log.d(TAG, "last level element " + currentElements.get(position).getTitle() + " is clicked"); } }; this.setOnItemClickListener(this); } public void initData(Context context, List treeElements) { this.treeElements = treeElements; getFirstLevelElements(context); adapter.notifyDataSetChanged(); } /** * 设置点击事件回调接口 * * @param itemClickCallBack */ public void setLastLevelItemClickCallBack(LastLevelItemClickListener itemClickCallBack) { this.itemClickCallBack = itemClickCallBack; } /** * 初始化树形结构列表数据,把第一层级的数据添加到currentElements中 */ public void getFirstLevelElements(Context context) { Log.d(TAG, "initCurrentElements"); int size = treeElements.size(); Log.d(TAG, "tree elements num is: " + size); if (currentElements == null) { currentElements = new ArrayList(); } currentElements.clear(); for (int i = 0; i < size; i++) { if (treeElements.get(i).getLevel() == 1) { currentElements.add(treeElements.get(i)); Log.d(TAG, "find a first level element: " + treeElements.get(i)); } } } /** * 从所有节点集合中获取某父节点的子节点集合 * * @param parentId * @return */ private List getChildElementsFromAllById(String parentId) { tempElements = new ArrayList(); int size = treeElements.size(); for (int i = 0; i < size; i++) { String temptParentId = treeElements.get(i).getParentId() ; if(temptParentId != null){ if (temptParentId.equalsIgnoreCase(parentId)) { tempElements.add(treeElements.get(i)); Log.d(TAG, "find a child element: " + treeElements.get(i)); } } } return tempElements; } /** * 从当前显示的节点集合中 , 获取某父节点的子节点集合 * @param parentId * @return */ private List getChildElementsFromCurrentById(String parentId) { Log.d(TAG, "getChildElementsFromCurrentById parentId: " + parentId); if (tempElements == null) { tempElements = new ArrayList(); } else { tempElements.clear(); } int size = currentElements.size(); if(size > 0){ for(TreeElement treeElement : currentElements){ String temp = treeElement.getParentId(); if(temp != null){ if (temp.equalsIgnoreCase(parentId)) { tempElements.add(treeElement); Log.d(TAG, "find a child element to delete: " +treeElement); } } } } return tempElements; } /** * 删除某父节点的所有子节点集合(包括直接节点和间接节点) * @param parentId * @return */ private synchronized boolean delAllChildElementsByParentId(String parentId) { Log.e(TAG, "delAllChildElementsByParentId: " + parentId); List childElments = getChildElementsFromCurrentById(parentId); List treeElementsToDel = deleteMap.get(parentId); if (treeElementsToDel == null) { treeElementsToDel = new ArrayList(); deleteMap.put(parentId, treeElementsToDel); } else { treeElementsToDel.clear(); } int size = childElments.size(); Log.e(TAG, "childElments size : " + size); TreeElement childElement = null; for (int i = 0; i < size; i++) { childElement = childElments.get(i); //寻找间接节点 if (childElement.hasChild && childElement.fold) { treeElementsToDel.add(childElement); } } size = treeElementsToDel.size(); Log.e(TAG, "treeElementsToDel size : " + size); if(size > 0){ //删除间接节点 List deleteTreeElement = treeElementsToDel; for(TreeElement element : deleteTreeElement){ delAllChildElementsByParentId(element.getId()); } } //删除直接节点 delDirectChildElementsByParentId(parentId); return true; } /** * 删除某父节点的直接子节点集合 * * @param parentId * @return */ private synchronized boolean delDirectChildElementsByParentId( String parentId) { Log.d(TAG, "delDirectChildElementsByParentId(): " + parentId); boolean success = false; if (currentElements == null || currentElements.size() == 0) { Log.d(TAG, "delChildElementsById() failed,currentElements is null or it's size is 0"); return success; } synchronized (currentElements) { int size = currentElements.size(); Log.d(TAG, "begin delete"); for (int i = size - 1; i >= 0; i--) { String temp = currentElements.get(i).getParentId(); if(temp != null && temp.equalsIgnoreCase(parentId)){ currentElements.get(i).fold = false;// 记得隐藏子节点时把展开状态设为false currentElements.remove(i); } } } success = true; return success; } /** * 根据id查下标 * * @param id * @return */ @SuppressWarnings("unused") private int getElementIndexById(String id) { int num = currentElements.size(); for (int i = 0; i < num; i++) { if (currentElements.get(i).getId().equalsIgnoreCase(id)) { return i; } } return -1; } @SuppressWarnings("unused") private TreeElement getElementById(String id){ int num = currentElements.size(); if( num > 0){ for (int i = 0; i < num; i++) { if (currentElements.get(i).getId().equalsIgnoreCase(id)) { return currentElements.get(i); } } } return null; } @Override public void onItemClick(AdapterView> arg0, View convertView, int position, long id) { TreeElement element = currentElements.get(position); if (element.isHasChild()) {// 当前节点有子节点时只进行数据显示或隐藏等操作 if (!element.isFold()) {// 当前父节点为未展开状态 currentElements.addAll(position + 1,this.getChildElementsFromAllById(element.getId())); } else if (element.fold) {// 当前父节点为展开状态 boolean success = this.delAllChildElementsByParentId(element.getId()); Log.d(TAG, "delete child state: " + success); if (!success) { return; } } element.setFold(!element.isFold());// 设置反状态 adapter.notifyDataSetChanged();// 刷新数据显示 } else {// 当前节点有子节点时只进行用户自定义操作 itemClickCallBack.onLastLevelItemClick(position,adapter); } } /** * 自定义内部接口,用于用户点击最终节点时的事件回调 */ public interface LastLevelItemClickListener { public void onLastLevelItemClick(int position,TreeViewAdapter adapter); }} TreeElement.java代码:
/** * 类名:TreeElement.java* 类描述:树形结构节点类 * 创建时间:2012-11-23 16:32 */public class TreeElement { String id = null;// 当前节点id String title = null;// 当前节点文字 boolean hasParent = false;// 当前节点是否有父节点 boolean hasChild = false;// 当前节点是否有子节点 boolean childShow = false;// 如果子节点,字节当当前是否已显示 String parentId = null;// 父节点id int level = -1;// 当前界面层级 boolean fold = false;// 是否处于展开状态...}TreeViewAdapter.java
package com.tbx.android.adapter;import java.util.List;/** * 类名:TreeViewAdapter.java * 类描述:用于填充数据的类* 创建时间:2012-11-23 16:32*/public class TreeViewAdapter extends BaseAdapter { class ViewHolder { ImageView icon; TextView title; } Context context; ViewHolder holder; LayoutInflater inflater; List elements; public TreeViewAdapter(Context context, List elements) { this.context = context; this.elements = elements; } @Override public int getCount() { return elements.size(); } @Override public Object getItem(int position) { return elements.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { /** * ---------------------- get holder------------------------ */ if (convertView == null) { if (inflater == null) { inflater = LayoutInflater.from(context); } holder = new ViewHolder(); convertView = inflater .inflate(R.layout.tree_view_item, null); holder.icon = (ImageView) convertView .findViewById(R.id.tree_view_item_icon); holder.title = (TextView) convertView .findViewById(R.id.tree_view_item_title); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } /** * ---------------------- set holder-------------------------- */ if (elements.get(position).isHasChild()) {// 有子节点,要显示图标 if (elements.get(position).isFold()) { holder.icon.setImageResource(R.drawable.tree_view_icon_open); } else if (!elements.get(position).isFold()) { holder.icon.setImageResource(R.drawable.tree_view_icon_close); } holder.icon.setVisibility(View.VISIBLE); } else {// 没有子节点,要隐藏图标 holder.icon.setImageResource(R.drawable.tree_view_icon_close); holder.icon.setVisibility(View.INVISIBLE); } holder.icon.setPadding(25 * (elements.get(position).getLevel()), 0, 0, 0);// 根据层级设置缩进 holder.title.setText(elements.get(position).getTitle()); holder.title.setTextSize(35 - elements.get(position).getLevel() * 5); // 根据层级设置字体大小 return convertView; }} MainActivity.java
public class MainActivity extends Activity { private TreeView lvAddress; //通讯录列表 private List lvAddressData = new ArrayList(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvAddress = (TreeView) findViewById(R.id.frame_listview_address); LastLevelItemClickListener itemClickCallBack = new LastLevelItemClickListener() { // 创建节点点击事件监听 @Override public void onLastLevelItemClick(int position, TreeViewAdapter adapter) { TreeElement element = (TreeElement) adapter.getItem(position); //然后自己处理 } }; //初始化数据 initData(); lvAddress.initData(this, lvAddressData);// 初始化数据 lvAddress.setLastLevelItemClickCallBack(itemClickCallBack);// 设置节点点击事件监听 } private void initData() {//测试数据 TreeElement root = new TreeElement(); root.setId("01"); root.setLevel(1); root.setTitle("好友"); root.setFold(false); root.setHasChild(true); root.setHasParent(false); root.setParentId(null); lvAddressData.add(root); TreeElement twoLevel = new TreeElement(); twoLevel.setId("0101"); twoLevel.setLevel(2); twoLevel.setTitle("初中同学"); twoLevel.setFold(false); twoLevel.setHasChild(true); twoLevel.setHasParent(true); twoLevel.setParentId("01"); lvAddressData.add(twoLevel); TreeElement threeLevel = new TreeElement(); threeLevel.setId("010101"); threeLevel.setLevel(3); threeLevel.setTitle("发财"); threeLevel.setFold(false); threeLevel.setHasChild(false); threeLevel.setHasParent(true); threeLevel.setParentId("0101"); lvAddressData.add(threeLevel); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; }} tree_view_item.xml布局内容
关于android中怎么自定义树形问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。
节点
数据
事件
状态
树形
层级
用户
问题
代码
内容
图标
接口
时间
更多
类名
结构
存储
帮助
监听
解答
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
惠州plc软件开发
成都网络安全大奖
泉州丰泽公安分局网络安全大队
执法局网络安全预警机制
手机网络安全密钥华为
数据库语音
58同城奥商网络技术有限公司
人工智能应用软件开发工程师
dos启动数据库服务
网络安全治理作文
楼宇服务器
伊犁网络安全工作
前橙网络技术
软件开发的程序
新疆教师网络技术培训
乐视激活服务器异常怎么办
浪潮软件开发运维工资和前途
update更新云数据库
印尼手机用什么网络技术
安全接入服务器地址山东
网络技术部岗位说明书
数据库事务处理题目
湖南智能软件开发报价
软件开发学习ios好还是安卓好
广州千网网络技术有限公司
美国19亿更换中国网络技术
达梦数据库和SQL
会科网络技术有限公司
数据库建外键的好处
拼脸软件开发