您的位置:首页 > 移动开发 > Android开发

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文件的字符串格式,可以根据需求换用解析文件或输入流等方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: