前言:好久没有没有没有在博客上发东西了,前段时间做了很多需要自定义控件的东西,现在想自己写一个点击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;
@Override
public 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;
}
@Override
public 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 implements
android.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 stub
init(context);
this.context = context;
}
public ExpandableMenuListView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init(context);
this.context = context;
}
public ExpandableMenuListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init(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 view
mMenuButtonOK = (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 listener
mMenuButtonOK.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;
}
@Override
public void onClick(View v) {
if (onMenuItemClickListener != null) {
onMenuItemClickListener.onMenuItemClick(v,pos);
}
}
}
private int mOldPos = -1;// record the old menu 's position
private int mCurrentState; // record the current menu's state
private int mOldState;// record the old menu's state
private static final int MENU_CLOSED = 0;// menu closed
private static final int MENU_OPENED = 1;// menu opened
boolean hasAttached = true; // tag
ViewGroup itemView = null;
@Override
public 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 hide
if (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>();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return listModel.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return listModel.get(position);
}
@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;
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>
附件链接