Android 长按Listview 每个item底部弹出菜单

android界面中,有一个功能是点击listview的每个item,下方弹出两个菜单,可以点击进入别的界面,这个功能可以使用开源项目expandablelistview,的确是可以实现,但发现导入的代码过多,显得很臃肿,经过师傅指点,我采用的是如下方法,步骤如下:

1.新建一个listview,需要在外层套一层scrollview,不过使用scrollview会导致listview的高度只有一个item,需要使用自定义的listview,代码如下:

package allone.verbank.apad.client.component.fixedListView;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View.MeasureSpec;
import android.widget.ListView;

public class PriceListViewScroll extends ListView {

	public PriceListViewScroll(Context context) {
		super(context);
	}

	public PriceListViewScroll(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public PriceListViewScroll(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	@Override
	public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
				MeasureSpec.AT_MOST);
		super.onMeasure(widthMeasureSpec, expandSpec);
	}

}

listview的界面文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/background"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="***"
        android:textColor="@color/white"
        android:textSize="16sp" />

    <ScrollView
        android:id="@+id/price_scroll"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@color/background" >

        <allone.verbank.apad.client.component.fixedListView.PriceListViewScroll
            android:id="@+id/price_quote_list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:divider="@color/white" >
       </allone.verbank.apad.client.component.fixedListView.PriceListViewScroll>
    </ScrollView>

</LinearLayout>

2.每个item下方的菜单,其实原来是一开始隐藏一段view,有一定的高度,防止菜单,菜单则是使用popuwindow来弹出,item的xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/below_layout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_margin="10dp"
    android:background="@color/background"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/price_quote_inst"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.98"
                android:gravity="right"
                android:singleLine="true"
                android:text="WYB/TEST"
                android:textColor="@color/white"
                android:textSize="20dp" >
            </TextView>

        </LinearLayout>

    <View
        android:layout_width="fill_parent"
        android:layout_height="1.2px"
        android:layout_marginLeft="14dp"
        android:layout_marginRight="14dp"
        android:layout_marginTop="5dp"
        android:background="@color/white" />

    <TextView
        android:id="@+id/hidepricemenu"
        android:layout_width="fill_parent"
        android:layout_height="30dp"
        android:visibility="gone" /><!--这是非常关键,菜单弹出来的时候,显示,没有菜单的时候为隐藏的 -->

</LinearLayout>

3.下一步就是在代码中,当长按listview时就显示hidepricemenu这个textview,以便于弹出菜单,菜单是使用popuwindow来显示,如下关键代码:

list.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View sourView,
					final int arg2, long arg3) {
				hidepricemenu = (TextView) sourView
						.findViewById(R.id.hidepricemenu);
				hidepricemenu.setVisibility(View.VISIBLE);

				String selectIntrument = maps.get(arg2).get(PRICE_TC_INST)
						.toString();

				buysellLongClickAction(sourView, selectIntrument, hidepricemenu);
				return true;

			}
		});

		private void buysellLongClickAction(final View inner,
			final String instname, final TextView hide_PriceMenu_copy) {
		StaticContext.TRADE_INST = instname;

		if (popupMenu != null) {
			popupMenu.destroyPopupMenu();
		}
		// 浮出菜单
		popupMenu = PopupMenuFactory.createPopupWindow(getSelfActivity(),
				inner, IPopupMenu.MENU_ID_PRICE, instname);
		popupMenu.showPopupMenu();

		popupMenu.createPupupWindow().setOnDismissListener(
				new PopupWindow.OnDismissListener() {

					@Override
					public void onDismiss() {
						hide_PriceMenu_copy.setVisibility(View.GONE);
					}
				});

		// 当为最后一行的时候,弹出的菜单会被隐藏,这里使用scroll向上移动
		handler.post(new Runnable() {
			@Override
			public void run() {
				if (price_scroll.getScrollY() > 40) {
					price_scroll.scrollTo(0, price_scroll.getScrollY() + 200);
				}

			}
		});

	}

创建popuwindow的代码如下:

package allone.verbank.apad.client.component.menu.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import allone.verbank.apad.client.R;
import allone.verbank.apad.client.StaticContext;
import allone.verbank.apad.client.component.menu.IPopupMenu;
import allone.verbank.apad.client.doc.DocCaptain;
import allone.verbank.apad.client.doc.IBundleCommData;
import allone.verbank.apad.client.event.IStationEventName;
import allone.verbank.apad.client.event.StationEventCaptain;
import allone.verbank.apad.client.event.StationEventData;
import allone.verbank.apad.client.frame.main.MainActivity;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.PopupWindow;

public class PriceTradePopupMenu implements IPopupMenu {

	private ArrayList<Map<String, Integer>> dataMap = new ArrayList<Map<String, Integer>>();
	public static final String TABLE_COLUMNID_ORDERTRADE = "ORDERTRADE";
	public static final String TABLE_COLUMNID_PRICEWARNING = "PRICEWARNING";
	private ListView listview;
	private PopupWindow popupMenu;
	private MainActivity activity;
	private View sourceView;

	private String instrument;

	public PriceTradePopupMenu(Activity activity, View sourceView, Object data) {
		this.activity = (MainActivity) activity;
		this.sourceView = sourceView;
		instrument = data.toString();
		initComponent();
	}

	private void initComponent() {
		View view = activity.getLayoutInflater().inflate(
				R.layout.popup_price_menu, null);
		listview = (ListView) view.findViewById(R.id.price_menu_list);
		addRowData();
		PriceTradeAdapter listAdapter = new PriceTradeAdapter();
		listview.setAdapter(listAdapter);

		// 创建弹出窗口
		// 窗口内容为layoutLeft,里面包含一个ListView
		// 窗口宽度跟tvLeft一样
		WindowManager wm = activity.getWindowManager();
		int width = wm.getDefaultDisplay().getWidth();// width -
														// sourceView.getWidth()
		popupMenu = new PopupWindow(view, sourceView.getWidth(),
				LayoutParams.WRAP_CONTENT);

		ColorDrawable cd = new ColorDrawable(R.color.white);
		popupMenu.setBackgroundDrawable(cd);
		// popupMenu.setAnimationStyle(R.style.AnimationFade);
		popupMenu.update();
		popupMenu.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
		popupMenu.setTouchable(true); // 设置popupwindow可点击
		popupMenu.setOutsideTouchable(true); // 设置popupwindow外部可点击
		popupMenu.setFocusable(true); // 获取焦点
		popupMenu.setTouchInterceptor(new View.OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// 如果点击了popupwindow的外部,popupwindow也会消失
				StationEventCaptain.getInstance().fireEventDataChange(
						new StationEventData(
								IStationEventName.EVENT_NAME_PRICE_MENU_CHANGE,
								instrument));
				if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
					popupMenu.dismiss();
					return true;
				}
				return false;
			}
		});
	}

	private void addRowData() {
		dataMap.add(addRowItemData());
	}

	private HashMap<String, Integer> addRowItemData() {
		HashMap<String, Integer> mapTemp = new HashMap<String, Integer>();
		mapTemp.put(TABLE_COLUMNID_ORDERTRADE,
				IBundleCommData.MENU_PRICE_ORDERTRADE);
		mapTemp.put(TABLE_COLUMNID_PRICEWARNING,
				IBundleCommData.MENU_PRICE_PRICEWARNING);
		return mapTemp;
	}

	@Override
	public PopupWindow createPupupWindow() {
		return popupMenu;
	}

	@Override
	public void destroyPopupMenu() {
		if (popupMenu != null && popupMenu.isShowing()) {
			popupMenu.dismiss();
		}
	}

	@SuppressLint("NewApi")
	@Override
	public void showPopupMenu() {
		if (popupMenu != null && popupMenu.isShowing()) {
			popupMenu.dismiss();
		} else {
			popupMenu.showAsDropDown(sourceView, 10,
					-50 + (int) sourceView.getRotationY());
		}
	}

	public class PriceTradeAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return dataMap.size();
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

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

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder viewHolder = null;
			if (convertView == null) {
				viewHolder = new ViewHolder();
				convertView = activity.getLayoutInflater().inflate(
						R.layout.popup_price_menu_item, null);
				viewHolder.orderTradeView = (Button) convertView
						.findViewById(R.id.price_menu_item_ordertrade);
				viewHolder.orderTradeView
						.setOnClickListener(new OnClickListener() {

							@Override
							public void onClick(View v) {
								if (popupMenu != null) {
									popupMenu.setAnimationStyle(0);
									popupMenu.dismiss();
								}

							}
						});

				convertView.setTag(viewHolder);
			} else {
				viewHolder = (ViewHolder) convertView.getTag();
			}

			int orderTrade = Integer.parseInt(dataMap.get(position)
					.get(TABLE_COLUMNID_ORDERTRADE).toString());
			viewHolder.orderTradeView
					.setText(orderTrade == IBundleCommData.MENU_PRICE_ORDERTRADE ? activity
							.getString(R.string.pricetradepopupmenu_order) : "");
			int priceWarning = Integer.parseInt(dataMap.get(position)
					.get(TABLE_COLUMNID_PRICEWARNING).toString());
			viewHolder.priceWarningView
					.setText(priceWarning == IBundleCommData.MENU_PRICE_PRICEWARNING ? activity
							.getString(R.string.pricetradepopupmenu_pricewarnning)
							: "");

			return convertView;
		}

		private class ViewHolder {
			Button orderTradeView;
			Button priceWarningView;
		}
	}

}

4.使用这种方式的时候,当最后一个item,会出现弹出的菜单在listview的下方的,位置被遮挡住了,所以需要前面scrollview,判断下方的高度,然后进行listview的移动,使用scrollto的方法,如下代码:

	// 当为最后一行的时候,弹出的菜单会被隐藏,这里使用scroll向上移动
		if (price_scroll.getScrollY() > 10) {
price_scroll.scrollTo(0, price_scroll.getScrollY() + 200);
}
if (price_scroll.getScrollY() == 0) {
price_scroll.scrollTo(0, price_scroll.getScrollY() + 50);

}

至此就可以完成该功能,有些代码省略了,因为是公司的,有问题可以交流!!!

时间: 2024-10-07 11:59:37

Android 长按Listview 每个item底部弹出菜单的相关文章

【转】微信中MMAlert(半透明底部弹出菜单)的使用介绍

原文地址:http://blog.csdn.net/singwhatiwanna/article/details/8892930 果大家时常用过微信或者用过iphone,就会发现有种从底部弹出的半透明菜单,这种菜单风格优美并且用户体验良好,先看一下效果. MMAlert来自微信开放平台的sdk示例,其示例的代码有点乱,我做了删减和整理,只保留了MMAlert这个类的一部分功能,即只保留了实现上述效果的那个函数,因为其他函数比较简单,就是普通的AlertDialog,我觉得大家都懂,所以直接删掉了

iOS_21团购_顶部菜单和弹出菜单联动

最后效果图: 各控件关系图1: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >\ 各控件关系图2: 点击Dock上面的buttonDockItem, 创建经导航控制器包装的DealListController, 而且加入到主控制器的右側空间 // // Deal

Android ListView两种长按弹出菜单方式

* 知识点1:ListView item:两种长按弹出菜单方式* 知识点2:ListView SimpleAdapter的使用*  知识点 3:在java代码中创建一个ListView*/ -----------------------------------------------------Activity[mw_shl_code=java,true]package org.gxl.com; public class ListOnLongClickActivity extends Activ

Android ListView 长按列表弹出菜单

Android ListView 长按列表弹出菜单 设置长按菜单 listView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { menu.add(0, 0, 0, "删除单号"); menu.add

Android——长按弹出菜单、获取当前所按的item的信息

ListView 中有多个选项,长按每个选项,都能弹出一个上下文菜单,并能获取所按选项的详细信息. 关键步骤: private static final int DELETE_ID = Menu.FIRST + 1;//使用Menu.FIRST常量而不使用其他常量的原因:程序封装的变量 用起来不占内存 程序读的快 不容易出错 private static final int EDIT_ID=Menu.FIRST + 2; private static final int VIEW_ID=Menu

Android学习----------长按列表项弹出菜单,给菜单项添加事件,获取上下文

这里是先显示一个listview,长按listview的一个列表项,弹出一个菜单来,菜单有两个条目, "更新该条"和"删除该条",并且这两条都有监听事件,整体就像微信好友对话操作一样. 其中菜单项有一个获取上下文的操作:AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 这句也是用于列表项的. 具体代码如下: protected void onCreate(Bundle

Android — 长按ListView 利用上下文菜单(ActionMode) 进行批量事件处理

好久没写博客拉``````` 近期最终略微闲一点了``````` 无聊拿手机清理短信.发现批量事件的处理还是挺管用的`````` 那么自己也来山寨一记看看效果吧````` 闲话少说,首先,我们来看下手机自带的短信功能里运行批量删除时的效果: 然后  是我们自己简单山寨的效果:       模拟的操作过程非常easy,但也非常有代表性. 我们假定我们所处的场景为.进入一个存放联系人列表的界面. 于是,首先我们定义了一个进度框,模拟提示正在从网络上下载数据. 接着.当网络数据成功下载到移动设备上后,

[Android] 底部菜单布局+PopupWindows实现弹出菜单功能(初级篇)

    这篇文章主要是自己研究如何对底部菜单进行布局,并简单的实现点击不同"按钮"实现图片切换和背景切换的功能,最后通过PopupWindows实现弹出菜单,点击不同按钮能实现不同方法,相当于美图秀秀编辑图片的功能吧!它并没有涉及到Fragment碎片切换页面的功能,因为页面始终显示被处理的图片.这是我初学Android的一篇基础性文章和在线思想笔记,网上有很多更优秀的demo,不过也希望对大家有用~ 首先介绍两种方法实现底部菜单点击不同图标显示选中状态的效果. (可参考简短文章:An

转 android 从底部弹出一个popuwindow,渐入渐出效果。我这里是用在购物车需要选择购买选项的操作。

最近要改客户端,需要实现一个从底部弹出的popuwindow,像我这种渣渣android技术,能整出popuwindow但是整不出动画,百度之,记录一下. 从下面这个地址转的 http://blog.csdn.net/yxhuang2008/article/details/42617805 最近因为要用到PopupWindow,所以,就在网上搜索了一下,发现挺多关于这样的文章,现在我把它们整理了一下. 1.Android PopupWindow 的使用技巧,http://www.cnblogs.