实现如上图所示的二级菜单:
1上面是通过两个ListView实现的,父LIstView控制子ListView,其中配置文件如下
<cn.doublemenu.com.view.CategoryList
android:orientation="vertical" android:background="#88000000"
android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/categorylist"
android:visibility="gone">
<ImageView android:layout_height="wrap_content"
android:layout_width="wrap_content" android:src="@drawable/trangle_indicate"
android:layout_marginBottom="-22.0dip" android:layout_marginLeft="40.0dip" />
<RelativeLayout android:layout_height="fill_parent"
android:layout_width="fill_parent" android:background="@drawable/addresslist_bg"
android:layout_marginRight="15.0dip" android:layout_marginLeft="15.0dip"
android:layout_marginTop="15.0dip" android:layout_marginBottom="40.0dip">
<LinearLayout android:layout_height="fill_parent"
android:layout_width="fill_parent" android:orientation="horizontal"
android:paddingTop="2.0dip" android:paddingLeft="1.0dip"
android:paddingRight="1.0dip" android:paddingBottom="1.0dip">
<ListView android:id="@+id/list_group" android:scrollbars="none"
android:background="#00000000" android:layout_width="0.0px"
android:layout_height="fill_parent" android:cacheColorHint="#00000000"
android:divider="#ffbbbab7" android:dividerHeight="1.0px"
android:layout_weight="1.0" />
<ListView android:id="@+id/list_child" android:background="#f4f4f4"
android:layout_width="0.0px" android:layout_height="fill_parent"
android:cacheColorHint="#00000000" android:divider="@null"
android:layout_weight="1.0" />
</LinearLayout>
</RelativeLayout>
</cn.doublemenu.com.view.CategoryList>
2自定义的cn.doublemenu.com.view.CategoryList如下:
package cn.doublemenu.com.view;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import cn.doublemenu.com.activity.R;
import cn.doublemenu.com.bean.Category;
import cn.doublemenu.com.db.GenericDAO;
public class CategoryList extends LinearLayout {
private List<Category> topCategories;
private Map<Integer, List<Category>> categoriesMap;
private GenericDAO dao;
private Context context;
private Listener listener;
private ListView groupListView;
private ListView childListView;
private ChildAdapter adapter;
private int positionOut;
public interface Listener {
public void onSelected(Category category, Category parentCategory);
public void onScroll(Category category);
}
public CategoryList(Context c, AttributeSet attrs) {
super(c, attrs);
dao = GenericDAO.getInstance(c);
context = c;
}
public void init(final Listener listener, Category category) {
topCategories = dao.listCategories();
categoriesMap = new HashMap<Integer, List<Category>>();
this.listener = listener;
adapter = new ChildAdapter(new ArrayList<Category>());
groupListView = (ListView) findViewById(R.id.list_group);
childListView = (ListView) findViewById(R.id.list_child);
groupListView.setCacheColorHint(0);
groupListView.setAdapter(new GroupAdapter());
childListView.setAdapter(adapter);
List<Category> childCategoryList = getCategories(0);
adapter.setCategoryList(childCategoryList);
adapter.notifyDataSetChanged();
groupListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
positionOut = position;
List<Category> childList = getCategories(position);
adapter.setCategoryList(childList);
adapter.notifyDataSetChanged();
GroupAdapter adapt = (GroupAdapter) parent.getAdapter();
adapt.setmCurSelectPosition(position);
adapt.notifyDataSetChanged();
}
});
childListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
listener.onSelected(adapter.getCategoryList().get(position),
topCategories.get(positionOut));
}
});
}
private List<Category> getCategories(int groupPosition) {
List<Category> categories = categoriesMap.get(groupPosition);
if (categories == null) {
Category parent = topCategories.get(groupPosition);
categories = dao.listCategories(parent);
categoriesMap.put(groupPosition, categories);
}
return categories;
}
private class ViewHolder {
public ImageView imgView;
public TextView textView;
}
class GroupAdapter extends BaseAdapter {
private ViewHolder mSelectHolder;
private int mCurSelectPosition = 0;
public ViewHolder getmSelectHolder() {
return mSelectHolder;
}
public void setmSelectHolder(ViewHolder mSelectHolder) {
this.mSelectHolder = mSelectHolder;
}
public int getmCurSelectPosition() {
return mCurSelectPosition;
}
public void setmCurSelectPosition(int mCurSelectPosition) {
this.mCurSelectPosition = mCurSelectPosition;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
if (topCategories != null) {
return topCategories.size();
} else {
return 0;
}
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
if (topCategories != null && topCategories.size() > position - 1) {
return topCategories.get(position);
} else {
return null;
}
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(
R.layout.address_item_layout, null);
viewHolder = new ViewHolder();
viewHolder.textView = (TextView) convertView
.findViewById(R.id.city_item_title);
viewHolder.imgView = (ImageView) convertView
.findViewById(R.id.img_tag);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (position == mCurSelectPosition) {
convertView.setBackgroundColor(getResources().getColor(
R.color.address_child));
upDateItemUi(viewHolder.imgView, true);
} else {
convertView.setBackgroundColor(getResources().getColor(
R.color.white));
upDateItemUi(viewHolder.imgView, false);
}
Category category = topCategories.get(position);
viewHolder.textView.setText(category.name);
return convertView;
}
}
private void upDateItemUi(ImageView imgView, boolean b) {
if (b) {
imgView.setVisibility(View.VISIBLE);
} else {
imgView.setVisibility(View.INVISIBLE);
}
}
class ChildAdapter extends BaseAdapter {
private List<Category> categoryList;
public List<Category> getCategoryList() {
return categoryList;
}
public void setCategoryList(List<Category> categoryList) {
this.categoryList = categoryList;
}
public ChildAdapter(List<Category> childList) {
super();
this.categoryList = childList;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
if (categoryList != null) {
return categoryList.size();
} else {
return 0;
}
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
if (categoryList != null && categoryList.size() > position - 1) {
return categoryList.get(position);
} else {
return null;
}
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
if (view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.address_textview_layout,
null);
}
TextView cityChildTextView = (TextView) view
.findViewById(R.id.single_textview);
cityChildTextView.setText(categoryList.get(position).name);
return view;
}
}
}
3两个ListView包括两个Itemlayout,其中父ListView的Item是address_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_height="wrap_content"
android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="horizontal"
android:layout_alignParentTop="true">
<ImageView android:layout_height="fill_parent"
android:layout_width="5.0dip" android:background="#ff6600"
android:visibility="invisible" android:id="@+id/img_tag"></ImageView>
<TextView android:layout_height="fill_parent"
android:layout_width="fill_parent" android:textSize="16dp"
android:layout_marginLeft="6dp" android:layout_marginTop="9.0dip"
android:layout_marginBottom="9.0dip" android:id="@+id/city_item_title"
android:textColor="#505050" android:singleLine="true"
android:ellipsize="end" />
</LinearLayout>
</RelativeLayout>
子ListView的Item是address_textview_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent" android:layout_width="wrap_content"
android:paddingTop="9.0dip" android:paddingBottom="9.0dip">
<TextView android:id="@+id/single_textview"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_alignParentLeft="true" android:paddingLeft="6dp"
android:textSize="16dip" android:singleLine="true" android:ellipsize="end"
android:background="@null" android:textColor="#707070" />
</RelativeLayout>
3在程序中初始化数据通过SQLite来实现
package cn.doublemenu.com.db;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import cn.doublemenu.com.activity.R;
import cn.doublemenu.com.bean.Category;
public class GenericDAO extends SQLiteOpenHelper {
private static Object lock = new Object();
private static SQLiteDatabase db;
public static final String KEY_ID = "id";
public static final int DATABASE_VERSION = 7;
private Context context;
private final static String DATABASE_NAME = "category";
private static volatile GenericDAO instance;
private GenericDAO(Context ctx) {
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
context = ctx;
}
/*
* public static GenericDAO getInstance() { return
* getInstance(ActivityManager.getCurrent()); }
*/
public static GenericDAO getInstance(Context ctx) {
try {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = new GenericDAO(ctx);
db = instance.getWritableDatabase();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return instance;
}
private void onDown() {
// TODO Auto-generated method stub
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.beginTransaction();
Log.e("test", "onCreate execute");
load(db, R.raw.category);
db.setTransactionSuccessful();
} catch (Exception ee) {
ee.printStackTrace();
Log.e("test", ee.toString());
} finally {
if (db != null) {
db.endTransaction();
}
}
}
private void load(SQLiteDatabase db, int fileId)
throws UnsupportedEncodingException, IOException {
BufferedReader bufferedReader = null;
try {
String temp;
InputStream in = context.getResources().openRawResource(fileId);
bufferedReader = new BufferedReader(new InputStreamReader(in,
"utf-8"));
while ((temp = bufferedReader.readLine()) != null) {
db.execSQL(temp);
temp = null;
}
} catch (Exception e) {
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (Exception e) {
}
}
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
db.beginTransaction();
db.delete("category", null, null);
db.setTransactionSuccessful();
} catch (SQLException e) {
e.printStackTrace();
} finally {
db.endTransaction();
}
}
public long insert(String table, ContentValues values) {
long ret = db.insert(table, null, values);
return ret;
}
public Category getCategory(int id) {
return Category.get(db, id);
}
public List<Category> listCategories() {
try {
List<Category> ret = Category.list(db);
if (ret == null || ret.isEmpty()) {
onCreate(db);
return Category.list(db);
}
return ret;
} catch (Exception e) {
e.printStackTrace();
onCreate(db);
return Category.list(db);
}
}
public List<Category> listCategories(Category category) {
return Category.list(db, category);
}
}
CateGory定义如下、
package cn.doublemenu.com.bean;
import java.util.ArrayList;
import java.util.List;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class Category {
public int id;
public Integer pid;
public String name;
public static Category get(SQLiteDatabase db, int id) {
if (id == 255) {
Category category = new Category();
category.pid = 0;
category.id = 255;
category.name = "全部分类";
return category;
}
Cursor cursor = db.rawQuery("SELECT * FROM category WHERE id = " + id,
null);
cursor.moveToFirst();
Category ret = toCategory(cursor);
cursor.close();
return ret;
}
public static List<Category> list(SQLiteDatabase db) {
List<Category> ret = new ArrayList<Category>();
Cursor cursor = null;
try {
ret.add(get(db, 255));
cursor = db.rawQuery("SELECT * FROM category WHERE pid IS NULL",
null);
if (cursor.moveToFirst()) {
do {
ret.add(toCategory(cursor));
} while (cursor.moveToNext());
}
} catch (Exception e) {
} finally {
if (cursor != null) {
try {
cursor.close();
} catch (Exception ee) {
ee.printStackTrace();
}
}
}
return ret;
}
public static List<Category> list(SQLiteDatabase db, Category parent) {
List<Category> ret = new ArrayList<Category>();
ret.add(parent);
Cursor cursor = db.rawQuery(
"SELECT id,pid,name FROM category WHERE pid = " + parent.id,
null);
if (cursor.moveToFirst()) {
do {
ret.add(toCategory(cursor));
} while (cursor.moveToNext());
}
cursor.close();
return ret;
}
private static Category toCategory(Cursor cursor) {
Category category = new Category();
category.id = cursor.getInt(0);
category.pid = cursor.getInt(1);
category.name = cursor.getString(2);
return category;
}
@Override
public boolean equals(Object o) {
return o instanceof Category && ((Category) o).id == id;
}
}
在程序中使用二级菜单:
package cn.doublemenu.com.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import cn.doublemenu.com.bean.Category;
import cn.doublemenu.com.db.GenericDAO;
import cn.doublemenu.com.view.CategoryList;
public class MainActivity extends Activity {
protected Category category;
private CategoryList categoryList;
private Button categoryButton;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GenericDAO.getInstance(this).getWritableDatabase();
categoryButton = (Button) findViewById(R.id.show);
categoryButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
boolean visible = (categoryList.getVisibility() == View.VISIBLE);
hideList(visible);
}
});
initCategoryList(255);
}
protected void initCategoryList(int cat) {
category = GenericDAO.getInstance(this).getCategory(cat);
categoryList = (CategoryList) findViewById(R.id.categorylist);
categoryList.init(new CategoryList.Listener() {
public void onSelected(Category c, Category parentCategory) {
categoryList.setVisibility(View.GONE);
}
public void onScroll(Category category) {
}
}, category);
}
protected void hideList(boolean vis) {
if (categoryList != null) {
if (vis) {
categoryList.setVisibility(View.GONE);
} else {
categoryList.setVisibility(View.VISIBLE);
}
}
}
}
下载地址 :http://download.csdn.net/detail/hahahacff/5280992