android 从xml文件读取数据初始化,并实现无分级的树状菜单的显示
2012-05-09 14:23
676 查看
1.树状菜单的实现原理(借鉴网上一哥们的代码,同时解决了代码中存在的小问题):
使用ListView模仿树状菜单,如果某个节点存在父节点,在节点展开的时候就相应的设置与其节点深度有关的缩进距离,具体见代码所有的节点信息都封装进,节点类中,类的属性定义了节点的全部信息,对应xml文件中的相应属性
2.实现代码:
1封装节点信息的类/** * * @author wx * 封装节点属性的类 */ public class TreeElement { //节点的标识id,用来唯一标识节点 private String id; //节点上显示的文本内容 private String text ; //节点是否有父节点 private boolean hasparent; //节点是否有子节点 private boolean haschild ; //父节点的id private String parentid; //节点的深度 private int level; //节点是否展开 private boolean expanded; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getOutlineTitle() { return text; } public void setOutlineTitle(String outlineTitle) { this.text = outlineTitle; } public boolean isMhasParent() { return hasparent; } public void setMhasParent(boolean mhasParent) { this.hasparent = mhasParent; } public boolean hasChild() { return haschild; } public void sethasChild(boolean hasChild) { this.haschild = hasChild; } public String getParent() { return parentid; } public void setParent(String parent) { this.parentid = parent; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } /** * 带参构造方法 * @param id * @param text * @param hasparent * @param haschild * @param parentid * @param level * @param expanded */ public TreeElement(String id, String text, boolean hasparent, boolean haschild, String parentid, int level, boolean expanded) { super(); this.id = id; this.text = text; this.hasparent = hasparent; this.haschild = haschild; this.parentid = parentid; this.level = level; this.expanded = expanded; } }
2.实现树状菜单显示的类,使用ArrayAdapter动态添加View
public class TreeView extends ListActivity { private List<TreeElement> treeSets=new ArrayList<TreeElement>(); // 第一次加载时要显示在界面上的数据(默认未展开是的数据) private ArrayList<TreeElement> elementsShowedOnload = new ArrayList<TreeElement>(); // 所有要显示的数据 private ArrayList<TreeElement> allElements = new ArrayList<TreeElement>(); private TreeViewAdapter treeViewAdapter = null; //解析xml文件的类 private AnalyXml analyXml=new AnalyXml(); private String treexmlStr=""; private String mcstype=""; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle bundle = this.getIntent().getExtras(); treexmlStr=bundle.getString("_responseValue"); mcstype = analyXml.attValue(treexmlStr, "/mcs", "type"); if (mcstype.contains("tree")) { initialData(treexmlStr); } treeViewAdapter = new TreeViewAdapter(this, R.layout.outline, elementsShowedOnload); setListAdapter(treeViewAdapter); // registerForContextMenu(getListView()); } /** * 初始化要显示的数据 */ private void initialData(String treexmlStr) { treeSets=analyXml.getTreeElements(treexmlStr); for(TreeElement e:treeSets){ if(!e.isMhasParent()){ elementsShowedOnload.add(e); } allElements.add(e); } } /** * * @author wx * */ @SuppressWarnings("rawtypes") private class TreeViewAdapter extends ArrayAdapter { // adapter构造方法 @SuppressWarnings("unchecked") public TreeViewAdapter(Context context, int textViewResourceId, List objects) { super(context, textViewResourceId, objects); mInflater = LayoutInflater.from(context); elements = objects; mIconCollapse = BitmapFactory.decodeResource( context.getResources(), R.drawable.outline_list_collapse); mIconExpand = BitmapFactory.decodeResource(context.getResources(), R.drawable.outline_list_expand); } private LayoutInflater mInflater; //节点集合 private List<TreeElement> elements; // 未展开的图片 private Bitmap mIconCollapse; // 展开的图片 private Bitmap mIconExpand; // 方法重写获得要显示的数据的个数 public int getCount() { return elements.size(); } // 方法重写获得位置 public Object getItem(int position) { return position; } // 方法重写获得位置对应的id public long getItemId(int position) { return position; } // 获得View public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { // 设置要显示的布局,布局里面有一个ImageVIew(树形菜单图片)一个TextView(要显示的数据) convertView = mInflater.inflate(R.layout.outline, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); // 这里的icon会被替换为需要显示的展开或者收起的图片 holder.icon = (ImageView) convertView.findViewById(R.id.icon); // View.setTag(Object)方法,可以给View添加一个额外的数据,在使用的时候可以使用getTag()取出来 convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.icon.setVisibility(View.VISIBLE); // 根据位置获得节点 TreeElement pdfOutlineElement = elements.get(position); int level = pdfOutlineElement.getLevel(); // 获得在treeview中显示在第几层,根据层次设置缩进 holder.icon.setPadding(25 * (level + 1), holder.icon.getPaddingTop(), 0, holder.icon.getPaddingBottom()); holder.text.setText(pdfOutlineElement.getOutlineTitle()); // 如果该位置节点有有子节点并且节点未展开 if (pdfOutlineElement.hasChild() && (pdfOutlineElement.isExpanded() == false)) { holder.icon.setImageBitmap(mIconCollapse); // 如果有子节点,节点展开了 } if (pdfOutlineElement.hasChild() && (pdfOutlineElement.isExpanded() == true)) { holder.icon.setImageBitmap(mIconExpand); // 如果没有子节点 } if (!pdfOutlineElement.hasChild()) { holder.icon.setImageBitmap(mIconCollapse); // 将图标隐藏 holder.icon.setVisibility(View.INVISIBLE); } return convertView; } // 控制一行View显示的内容,图片和文字两项 class ViewHolder { TextView text; ImageView icon; } } // 选中事件 @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); // 如果没有子节点,这里就可以进行点击跳转等相应的操作 if (!elementsShowedOnload.get(position).hasChild()) { Toast.makeText(this, elementsShowedOnload.get(position).getOutlineTitle(), 0) .show(); //这里可以处理没有子节点的节点的选中事件 return; } // 如果节点处于展开状态 if (elementsShowedOnload.get(position).isExpanded()) { // 将展开张泰设置为false elementsShowedOnload.get(position).setExpanded(false); TreeElement pdfOutlineElement = elementsShowedOnload .get(position); ArrayList<TreeElement> temp = new ArrayList<TreeElement>(); for (int i = position + 1; i < elementsShowedOnload.size(); i++) { if (pdfOutlineElement.getLevel() >= elementsShowedOnload.get(i) .getLevel()) { break; } temp.add(elementsShowedOnload.get(i)); } elementsShowedOnload.removeAll(temp); // 提醒数据改变需要刷新 treeViewAdapter.notifyDataSetChanged(); /* * fileExploreAdapter = new TreeViewAdapter(this, R.layout.outline, * mPdfOutlinesCount); */ // setListAdapter(fileExploreAdapter); } else { // 如果节点处于关闭状态,设置展开为true elementsShowedOnload.get(position).setExpanded(true); int level = elementsShowedOnload.get(position).getLevel(); int nextLevel = level + 1; for (TreeElement pdfOutlineElement : allElements) { int j = 1; if (pdfOutlineElement.getParent().equals(elementsShowedOnload.get( position).getId())) { pdfOutlineElement.setLevel(nextLevel); pdfOutlineElement.setExpanded(false); elementsShowedOnload.add(position + j, pdfOutlineElement); j++; } } treeViewAdapter.notifyDataSetChanged(); /* * fileExploreAdapter = new TreeViewAdapter(this, R.layout.outline, * mPdfOutlinesCount); */ // setListAdapter(fileExploreAdapter); } } }
需要注意的是如果oncreate方法中注释掉的代码没有被注释的话,如果要从别的Acitvity跳转到这个ListActivity的话会报异常,(原因没搞懂...)
3.对应ListActivity的layout文件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginRight="6.0dip" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" /> <TextView android:textAppearance="?android:textAppearanceMedium" android:gravity="center_vertical" android:id="@+id/text" android:textColor="#ffffff" android:layout_width="fill_parent" android:layout_height="fill_parent" android:singleLine="true" android:layout_toRightOf="@id/icon" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" /> </RelativeLayout>
其中imageview为树状菜单展开和缩进的图片,textview为显示的文字,图片放在资源文件中,可自己修改
4.对应的xml文件
<?xml version="1.0" encoding="utf-8" ?> <mcs type="tree"> <head> <title>消息提示测试</title> </head> <body> <treeview> <treeelement id="1" text="编程语言" hasparent="false" haschild="true" parentid="0" level="0" expanded="false" href="xxx" /> <treeelement id="2" text="JAVA" hasparent="true" haschild="true" parentid="1" level="1" expanded="false" href="xxx" /> <treeelement id="3" text="C语言" hasparent="true" haschild="false" parentid="1" level="1" expanded="false" href="xxx" /> <treeelement id="4" text="Thinking in Java" hasparent="true" haschild="true" parentid="2" level="2" expanded="false" href="xxx" /> <treeelement id="5" text="中文版" hasparent="true" haschild="false" parentid="4" level="3" expanded="false" href="xxx" /> <treeelement id="6" text="英文版" hasparent="true" haschild="false" parentid="4" level="3" expanded="false" href="xxx" /> <treeelement id="7" text="开发工具" hasparent="false" haschild="false" parentid="0" level="0" expanded="false" href="xxx" /> </treeview> </body> </mcs>
代码中使用了parseText,直接解析xml文件的字符串格式,可以根据需求换用解析文件或输入流等方法
相关文章推荐
- php从数据库读取菜单数据并树状显示
- Visual C++中实现对图像数据的读取显示
- Visual C++中实现对图像数据的读取显示
- asp.net 读取并显示excel数据的实现代码
- Android采用ListView实现数据列表显示
- Android采用ListView实现数据列表显示
- Android开发入门之采用ListView实现数据列表显示
- Android 读取后台数据并显示。模拟小区车辆管理系统
- android第十六步采用ListView实现数据列表显示
- android中dom操作xml文件(保存和读取数据)
- 【Android UI设计与开发】7.底部菜单栏(四)PopupWindow 实现显示仿腾讯新闻底部弹出菜单
- Android 蓝牙4.0BLE开发实现对蓝牙的写入数据和读取数据
- Android编程实现读取手机联系人、拨号、发送短信及长按菜单操作方法实例小结
- android 容器还没初始化完毕加载数据没显示
- 两个Repeater嵌套实现动态菜单(ado.net+sql和xml+Linq两种读取数据方式)
- C#使用Jquery zTree实现树状结构显示_异步数据加载
- android实现始终显示overflow菜单的方法
- Android实现类似Excel显示数据功能(支持拖动改变列宽)v 1.0
- 从数据库读取数据。在页面用表格显示,并实现隔行换色
- Android 控件的相对动画实现小说阅读的上下菜单的隐藏与显示