您的位置:首页 > 移动开发 > Android开发

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

2016-05-10 13:52 525 查看
    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);

}


至此就可以完成该功能,有些代码省略了,因为是公司的,有问题可以交流!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息