自定义子菜单的ListView

来源:互联网 发布:紫鸟数据库 编辑:程序博客网 时间:2024/05/16 05:09

前言:好久没有没有没有在博客上发东西了,前段时间做了很多需要自定义控件的东西,现在想自己写一个点击ListView的Item之后,然后弹出一个对列表Item进行操作的menu,刚开始我是直接在onItemClick里面实现了,但是感觉这样不方便以后的复用,因此花了1天的时间,重新写了一个,当然个人水平有限啊,写的时候逻辑也比较混乱,大家凑合看把。下面看下效果图






下面上代码

1、主界面的布局 activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.tata.main.ExpandableMenuListView        android:id="@+id/listView1"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_alignParentRight="true"        android:layout_alignParentTop="true" /></RelativeLayout>

2、列表项布局 list_item.xml


<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:descendantFocusability="blocksDescendants"    android:orientation="vertical" >    <TextView        android:id="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="48dp"        android:layout_gravity="center_vertical"        android:gravity="center"        android:text="Large Text"        android:textAppearance="?android:attr/textAppearanceLarge" /></LinearLayout>
3、列表项菜单布局 view_list_menu.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="@drawable/shape_list_item_menu"    android:orientation="vertical" >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <Button            android:id="@+id/btn_menu_ok"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="ok" />        <Button            android:id="@+id/btn_menu_exit"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="exit" />        <Button            android:id="@+id/btn_menu_cancel"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="cancel" />    </LinearLayout></LinearLayout>

4、主界面 MainActivity.java

package com.tata.main;import java.util.ArrayList;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Toast;import com.tata.main.ExpandableMenuListView.OnMenuItemClickListener;public class MainActivity extends Activity implements OnMenuItemClickListener {ArrayList<ViewModel> listModels;MyAdapter adapter;ExpandableMenuListView mExpandableListView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initListData();initListView();}/** * 初始化数据 */private void initListView() {mExpandableListView = (ExpandableMenuListView) findViewById(R.id.listView1);adapter = new MyAdapter(this, listModels);mExpandableListView.setAdapter(adapter);mExpandableListView.setOnMenuItemClickListener(this);}/** * 得到数据 *  * @return */private void initListData() {ArrayList<ViewModel> listModel = new ArrayList<ViewModel>();for (int i =0 ; i<20 ; i++) {listModel.add(new ViewModel("item"+i, false));}listModels = listModel;}@Overridepublic void onMenuItemClick(View v, int pos) {switch (v.getId()) {case R.id.btn_menu_ok:t("OK");break;case R.id.btn_menu_cancel:t("cancel");break;case R.id.btn_menu_exit:t("exit");break;default:break;}}void t(String s) {Toast.makeText(this, s, Toast.LENGTH_SHORT).show();}}
4、自定义ExpandableMenuListView.java

package com.tata.main;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.ViewStub;import android.widget.AdapterView;import android.widget.Button;import android.widget.LinearLayout;import android.widget.ListView;/** *  *  * 名称:ExpandableMenuListView *  * 描述:自定义弹出菜单listview *  * 修改时间:2013-12-3 下午5:32:52 *  * @author tata *  */public class ExpandableMenuListView extends ListView implementsandroid.widget.AdapterView.OnItemClickListener {private static final String TAG = "ExpandableMenuListView";OnMenuItemClickListener onMenuItemClickListener;private Context context;/** * 设置菜单事件监听 *  * @param listener * @modifiedTime 上午10:24:57 * @author lzt */public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {this.onMenuItemClickListener = listener;}public ExpandableMenuListView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubinit(context);this.context = context;}public ExpandableMenuListView(Context context, AttributeSet attrs,int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stubinit(context);this.context = context;}public ExpandableMenuListView(Context context) {super(context);// TODO Auto-generated constructor stubinit(context);this.context = context;}private LayoutInflater mInflater;private LinearLayout mMenu;private Button mMenuButtonOK;private Button mMenuButtonCancel;private Button mMenuButtonExit;private ViewStub mMenuStub; // 用于显示自定义菜单的控件private static final int mInflateId = 0x0000018;private static final int mStubId = 0x0000019;onMenuButtonClickListener mMenuBtnClickListener;private void init(Context context) {mInflater = LayoutInflater.from(context);initViewStubMenu();super.setOnItemClickListener(this);mCurrentState = MENU_CLOSED;}private void setButtonMenuListener(View v, int pos) {// bind viewmMenuButtonOK = (Button) v.findViewById(R.id.btn_menu_ok);mMenuButtonCancel = (Button) v.findViewById(R.id.btn_menu_cancel);mMenuButtonExit = (Button) v.findViewById(R.id.btn_menu_exit);// set listenermMenuButtonOK.setOnClickListener(new onMenuButtonClickListener(pos));mMenuButtonCancel.setOnClickListener(new onMenuButtonClickListener(pos));mMenuButtonExit.setOnClickListener(new onMenuButtonClickListener(pos));}private ViewStub initViewStubMenu() {ViewStub mMenuStub = new ViewStub(context, R.layout.view_list_menu);mMenuStub.setId(mStubId);mMenuStub.setInflatedId(mInflateId);return mMenuStub;}class onMenuButtonClickListener implements OnClickListener {private int pos;public onMenuButtonClickListener(int pos) {super();this.pos = pos;}@Overridepublic void onClick(View v) {if (onMenuItemClickListener != null) {onMenuItemClickListener.onMenuItemClick(v,pos);}}}private int mOldPos = -1;// record the old menu 's positionprivate int mCurrentState; // record the current menu's stateprivate int mOldState;// record the old menu's stateprivate static final int MENU_CLOSED = 0;// menu closedprivate static final int MENU_OPENED = 1;// menu openedboolean hasAttached = true; // tagViewGroup itemView = null;@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {final int mCurPos = position;ViewGroup mItemView = (ViewGroup) view;this.itemView = mItemView;if (mItemView.findViewById(mInflateId) == null) {mMenuStub = initViewStubMenu();mItemView.addView(mMenuStub);}mMenuStub = (ViewStub) mItemView.findViewById(mStubId);if (mMenuStub != null && mMenuStub.getTag() == null) {View inflateView = mMenuStub.inflate();setButtonMenuListener(inflateView, mCurPos);mMenuStub.setTag(hasAttached);}if (mOldPos == -1) {mOldPos = position;}// Close the previous menu if it has not been closed.if (mCurPos != mOldPos && mOldState == MENU_OPENED) {if (getChildAt(mOldPos) != null) {View oldView = getChildAt(mOldPos).findViewById(mInflateId);if (oldView != null) {oldView.setVisibility(View.GONE);}}mOldState = MENU_CLOSED;mCurrentState = MENU_CLOSED;mOldPos = position;}// show or hideif (mCurrentState == MENU_CLOSED) {showItemView(true);mCurrentState = MENU_OPENED;mOldState = MENU_OPENED;mOldPos = mCurPos;} else {showItemView(false);mCurrentState = MENU_CLOSED;mOldState = MENU_CLOSED;}}/** * show *  * @param isShow * @modifiedTime 下午5:36:28 * @author lzt */private void showItemView(boolean isShow) {if (isShow) {this.itemView.findViewById(mInflateId).setVisibility(View.VISIBLE);} else {this.itemView.findViewById(mInflateId).setVisibility(View.GONE);}}interface OnMenuItemClickListener {/** *  *@param v * @param pos TODO *@modifiedTime 下午5:39:13 *@author lzt */void onMenuItemClick(View v, int pos);}}

6、自定义Adapter MyAdapter.java

package com.tata.main;import java.util.ArrayList;import java.util.HashMap;import java.util.Set;import android.content.Context;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.CompoundButton.OnCheckedChangeListener;import android.widget.TextView;public class MyAdapter extends BaseAdapter {private Context context;public ArrayList<ViewModel> listModel;private LayoutInflater inflater;public HashMap<Integer, Boolean> isCheckedMap;private boolean isAllChecked;public MyAdapter(Context context, ArrayList<ViewModel> listModel) {super();this.context = context;this.listModel = listModel;inflater = LayoutInflater.from(context);isCheckedMap = new HashMap<Integer, Boolean>();}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn listModel.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn listModel.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubView view = convertView;final int pos = position;final ViewHolder viewHolder;if (view == null) {viewHolder = new ViewHolder();view = inflater.inflate(R.layout.list_item, null);viewHolder.textView = (TextView) view.findViewById(R.id.textView1);view.setTag(viewHolder);} else {viewHolder = (ViewHolder) view.getTag();}viewHolder.textView.setText(listModel.get(position).getText());return view;}static class ViewHolder {public TextView textView;}}

7、 数据模型

<span style="font-family:Microsoft YaHei;">package com.tata.main;public class ViewModel {private String text;private boolean isCheck;public ViewModel(String text, boolean isCheck) {super();this.text = text;this.isCheck = isCheck;}public String getText() {return text;}public void setText(String text) {this.text = text;}public boolean isCheck() {return isCheck;}public void setCheck(boolean isCheck) {this.isCheck = isCheck;}}</span>
附件链接