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