Android 自定义横向ListView实现无限级菜单导航类目

应朋友要求,帮他实现一个pad应用打分系统部分UI的Demo,其中有客户数据有部分是无限极分类,需要移动端实现无限级菜单导航类目。
我的实现思路是 利用github上某位大神写的开源控件 横向ListView,将横向ListView中子项Item中嵌入正常的竖向ListView,在 横向ListView的重载BaseAdapter的getView方法中实现子ListView的OnItemClickListener事件,在该事件中通过操作Adapter的List数组增删,实现无限级更新和复选替换。

还是看几个重要文件的源代码更好的理解一下吧


首先是 我们定义的数据对象 

public class ColumnEntity {
	/**
	 * 栏目
	 */
	String id; // ID
	String title;// 标题
	int level;// 层级
	List subLists = new ArrayList();// 子项数组
	
	public ColumnEntity(){
	
	}
	
	public ColumnEntity(String _id,String _title,int _level,List _list){
		id=_id;
		title=_title;
		level=_level;
		subLists=_list;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public List getSubLists() {
		return subLists;
	}

	public void setSubLists(List subLists) {
		this.subLists = subLists;
	}

}

这个对象很简单唯一重要的就是 level 层级:用来确定当前是菜单的第几层,后面操作数据的remove是会用到。已经内涵List;


接下来是 横向ListView的自定义Adapter

public class ColumnAdapter extends BaseAdapter{

	private List mLists;
	private LayoutInflater mInflater;
	private Context mContext;
	
	public ColumnAdapter(Context _context, List _lists) {
		mInflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mLists = _lists;
		mContext=_context;
	}
	@Override
	public int getCount() {
		int size = mLists != null ? mLists.size() : 0;
		return size;
	}

	@Override
	public ColumnEntity getItem(int position) {
		ColumnEntity item = mLists != null ? mLists.get(position) : null;
		return item;
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ColumnEntity entity=getItem(position);
		final ViewHolder viewHolder;
		if (convertView != null) {
			viewHolder = (ViewHolder) convertView.getTag();
		} else {
			viewHolder = new ViewHolder();
			convertView = mInflater.inflate(R.layout.item_cloumn, null);
			viewHolder.columnList = (ListView) convertView.findViewById(R.id.lv_column);
			convertView.setTag(viewHolder);
		}
		
		List columnList=entity.getSubLists();
		final CategoryAdapter mAdapter=new CategoryAdapter(mContext, columnList);
		viewHolder.columnList.setAdapter(mAdapter);
		viewHolder.columnList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView view, View parent, int position,
					long id) {
				
				ColumnEntity entity=mAdapter.getList().get(position);
				Log.v("当前点击的是:", entity.getTitle());
				int level=entity.getLevel();
				for (int i = mLists.size(); i > level ; i--) {
					Log.v("", "移除第:"+i+"项");
					Log.v("", "--数组大小:"+ mLists.size());
					mLists.remove(i-1);
					Log.v("", "--数组大小:"+ mLists.size());
				}
				if(entity.getSubLists()!= null && entity.getSubLists().size()>0 ){
					mLists.add(entity);
				}
				Log.v("", "++数组大小:"+ mLists.size());
		
				notifyDataSetChanged();	//此方法用来更新数据变化	
			}
		});
		
		return convertView;
	}
	public class ViewHolder {
		
		ListView columnList;
	}

}


 看我的各种Log大家可以知道,我在写的时候也遇到了一些问题,因为对于数组的操作并没有深入了解,基础知识太差,开始我是用for循环的 变量递增去实现,实验看Log会知道remove的时候肯定会造成数组下标越界,后来想其原理,才想通要递减移除,从后向前对数组进行移除操作,以及List数组中是允许有null对象的,所以 要判断子项包含的subList是否为空,也就是是否还有下级栏目,再进行追加, 以及最后 最重要的一个方法

notifyDataSetChanged:控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容。


其他的文件都是基本的自定义了,没有太多信息含量。

源码下载链接


你可能感兴趣的:(Android自定义控件)