实现如上图所示的二级菜单:
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);
}
}
}
}
相关推荐
在Android应用开发中,ListView是一种常用的视图组件,它能够以列表的形式展示大量数据,而“multiListView 通过listview实现二级菜单”则是一个利用ListView的特性来构建多级导航菜单的技术。这篇内容将深入探讨...
每个节点代表一级菜单,其子节点为二级菜单,二级菜单的子节点为三级菜单。 3. 自定义适配器: - 创建`CustomExpandableListAdapter`,继承`BaseExpandableListAdapter`。 - 实现`getGroupCount()`,`...
在Windows Presentation Foundation(WPF)框架中,创建自定义二级菜单是实现用户界面(UI)交互性和美观性的重要部分。WPF提供了丰富的功能和灵活性,允许开发者构建动态且具有高度定制性的界面。以下是对"wpf...
通过以上步骤,我们就可以实现一个功能完备的ListView二级菜单。在实际项目中,可能还需要根据需求进行定制,如增加搜索功能、添加更多交互效果等。在给定的"DoubleList"文件中,包含了实现这一功能的具体代码,...
总的来说,实现Android中的ListView二级下拉菜单效果,需要结合数据模型、适配器、视图构建、事件处理和布局设计等多个方面的工作。虽然过程可能稍显复杂,但通过合理的设计和代码组织,可以创建出高效且功能丰富的...
4. **二级ListView适配器**:创建另一个适配器,如`LevelTwoAdapter`,用于填充二级菜单的数据。当一级菜单的点击事件发生时,根据一级菜单的子项列表来初始化或更新这个适配器。 5. **更新ListView**:在点击事件...
标题"listview二级菜单"描述的正是这种实现方式,即通过Button触发一个ListView的弹出,然后在ListView的每个条目上再次点击以显示第二个级别的ListView。这样的设计可以为用户提供更丰富的交互体验,特别是在导航和...
首先,我们可以在最外层使用一个ListView,每个列表项都是一个第二级菜单的ExpandableListView。然后,在ExpandableListView中,每个父项可以展开为一个第三级的ListView。这样,当用户点击第一级菜单时,会显示对应...
通过合理的数据结构和自定义视图,可以打造出符合业务需求的二级菜单。例如,一个应用的侧滑菜单可能包含多个一级分类(如“设置”、“帮助”),而每个一级分类下又有多个二级选项(如“账户设置”、“隐私政策”)...
在Android开发中,实现二级菜单通常涉及到多个列表视图(ListView)的交互,以及自定义适配器(Adapter)和事件监听。"android 二级菜单、双ListView 仿美团、购物二级菜单"这个项目旨在创建一个类似美团应用中的购物...
同时,需要在`getView()`方法中设置`Level2Adapter`,将二级列表的数据绑定到二级列表的`ListView`中。类似地,`Level2Adapter`也需要在`getView()`方法中设置`Level3Adapter`,并将三级列表的数据绑定到三级列表的`...
它允许用户滚动查看内容,而"listview下拉二级列表"则是ListView的一个高级应用,通常指的是在ListView中实现可展开和收起的子列表,也称为ExpandableListView。这种功能在很多应用中都非常常见,比如导航菜单、分类...
本项目"Android高级应用源码-Listview实现三级菜单列表.zip"就是基于ExpandableListView来创建一个具有三层菜单的示例。 首先,我们要了解ExpandableListView的基本使用。它的工作原理是通过Group(父项)和Child...
QML 中没有直接提供类似 android 的ExpandableListView二级列表控件,treeView,但是用 treeView 实在是有些不方便,并且达不到想要的效果,所以干脆用 ListView 来扩展一个。
实现二级联动菜单,通常需要监听一级菜单的点击事件,并根据事件动态创建和显示二级菜单。在这个Util类中,开发者已经考虑到了这种情况,使得创建这样的交互变得更加容易。 利用这个PopupWindowUtil类,开发者可以...
"android 二级菜单"的实现通常涉及到ListView的嵌套使用,就像QQ应用程序中好友列表的展示方式,通过点击一级菜单展开二级菜单,展示更多详细信息。 一级菜单通常是主要的功能类别,而二级菜单则是这些类别的子项或...
"android实现listView多级菜单"这个主题就是关于如何在Android应用中创建这种结构化视图的知识点。 首先,我们来理解ListView的基础。ListView是一个可以动态加载并显示大量数据的视图,它通过适配器(Adapter)将...
本教程将详细讲解如何实现这样一个仿美团的二级菜单,主要涉及的技术点包括自定义View、事件处理以及布局设计。 首先,我们需要了解二级菜单的基本结构。在美团应用中,一级菜单通常是一些大类,如“美食”、“电影...