实现如上图所示的二级菜单:
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);
}
}
}
}
相关推荐
通过listview很方便的实现二级菜单,在开发中可以直接的进行使用。
wpf自定义漂亮的二级菜单,数据加载方便,可扩展,适合企业及项目
ListView的二级菜单,使用ExpandableListView
ListView的二级菜单——doublelist的源码,详情看http://blog.csdn.net/jiang89125/article/details/49963725
点击一级ListView,子级的ListView更新相应的条目内容。可实现win7开始菜单。
listview的二级下拉菜单,实现简单,最近网上找到的,需要的拉走
这是一个通过button点击弹出listview,点击listview的item再弹出个listview,很实用哦,然后通过你点击的二级菜单的item,获取该值并显示出来。
android 二级菜单、双ListView 仿美团、购物二级菜单
android实现listView多级菜单
QML 中没有直接提供类似 android 的ExpandableListView二级列表控件,treeView,但是用 treeView 实在是有些不方便,并且达不到想要的效果,所以干脆用 ListView 来扩展一个。
popupwindow下拉布局为:listView、Gridview、二级菜单listview。将其写成Util类,只要将数据源和在哪个控件弹出的对象传入就可以直接引用并且设置item的点击事件。
每个一级listview菜单下面可以打开二级listview菜单。类似QQ的好友显示方法
对原来通过ExpandableListview实现的PinnedHeaderExpandableListView进行修改,实现一级菜单悬浮顶部,图标上划缩小等功能
使用PopupWindow + 2个ListView实现仿 美团/淘宝/百度糯米 多级分类菜单效果 使用PopupWindow + 2个ListView实现仿 美团/淘宝/百度糯米 多级分类菜单效果
这种横向的二级菜单在很多的app都有所应用.效果看起来还是非常的美观的.也算是项目需要,自己也就学了一下这个效果,首先说一下逻辑.实现的方式其实并不是很难..只不过逻辑上可能有点复杂.原理其实就是一个按钮.当...
二级菜单类似饿了么,下拉刷新上拉加载 listView
Android开发二级下拉菜单,自定义listview
这是一个简单的两级listview,有需要的朋友可以看看,相信只要你会用listview肯定也会用expandablelistView。