android中怎么自定义树形
发表于:2025-02-07 作者:千家信息网编辑
千家信息网最后更新 2025年02月07日,android中怎么自定义树形,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。TreeView.java代码:package com.
千家信息网最后更新 2025年02月07日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"; ListtreeElements = 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; Listelements; 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 ListlvAddressData = 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安全错误
数据库的锁怎样保障安全
域控服务器管理用户权限
中华万年历服务器地址
信访局网络安全检查总结报告
qq语音会保存在服务器吗
xs是什么服务器
孟津公安局网络安全大队
谷歌服务器地址和类型
保达服务器需要多少钱
佛山六意互联网科技有限公司
淮北工程管理软件开发需要多少钱
creo的服务器管理
2k20服务器保留多久
服务器安全组怎么放端口
如何创建数据库表空间
登录数据库软件
跨境电商目前的网络安全网络
软件开发行业人员需求
金山区网络营销软件开发供应商
显示屏的软件开发
宁波新壹互联网科技
丽水工业软件开发自学步骤
门禁服务器是什么样
宣传网络安全知识怎么说
国内vps服务器租用
州仕佳网络技术有限公司
拼单交友软件开发
杭州平台软件开发公司
软件开发 内部设计和外部设计
ping服务器丢包
大学生校园网络安全教育案例