先看效果,上圖展示了最近在開發的項目經常用到的pop案例,包括一般的選項,下拉選項,menu等,佈局就不貼了,很簡單
相信都能秒懂,貼下pop的核心代碼
/**
*
* @author yaguang.wang
*
*/
public class MenuPop extends PopupWindow {
private int resId;
private Context mContext;
private View popView;
private LayoutInflater inflater;
public MenuPop(int resId,Context context) {
super(context);
this.resId = resId;
mContext = context;
inflater=(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
init();
}
@SuppressWarnings("deprecation")
public void init(){
popView = inflater.inflate(this.resId, null);
popView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
setContentView(popView);
setWidth(LayoutParams.FILL_PARENT);
setHeight(LayoutParams.WRAP_CONTENT);
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setFocusable(true);
Button btn1 = (Button) popView.findViewById(R.id.menu_btn1);
Button btn2 = (Button) popView.findViewById(R.id.menu_btn2);
Button btn3 = (Button) popView.findViewById(R.id.menu_btn3);
Button btn4 = (Button) popView.findViewById(R.id.menu_btn4);
btn1.setOnClickListener(new ButtonListener());
btn2.setOnClickListener(new ButtonListener());
btn3.setOnClickListener(new ButtonListener());
btn4.setOnClickListener(new ButtonListener());
popView.setFocusableInTouchMode(true);
popView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_MENU && isShowing()){
dismiss();
return true;
}
return false;
}
});
}
private class ButtonListener implements View.OnClickListener{
@Override
public void onClick(View v) {
Toast.makeText(mContext, "view id is"+v.getId(), Toast.LENGTH_SHORT).show();
if (isShowing()) {
dismiss();
}
}
}
}
上面就是menupop的源代碼。能實現pop按Menu鍵可以彈出,再次menu鍵消失,點擊其他區域,或按下返回鍵,或者pop的view有點擊事件的時候pop消失。這裏具體借鑑了http://blog.csdn.net/admin_/article/details/7278402 這篇文章,這篇文章寫的不錯。剛開始也遇到了pop彈出來不消失的情況,
setFocusable(true);
popView.setFocusableInTouchMode(true);
這兩個方法很關鍵。pop在彈出的之後就變成了殭屍View,但是Pop裏面的View還是可以接收事件的,但是這時候要先把焦點傳給pop的view,這樣View是可以響應onkeydown事件和onClick事件的。問題得到解決。
/**
*
* @author yaguang.wang
*
*/
public class GridPop extends PopupWindow {
private Context context;
private LayoutInflater layoutInflater;
public View allView;
private int resId;
private GridView allItemGrid;
public GridPop(Context context,int resourceId) {
super(context);
this.context = context;
this.resId=resourceId;
initAllPop();
}
public void initAllPop() {
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
allView = layoutInflater.inflate(resId, null);
allView.setFocusable(true);
allView.setFocusableInTouchMode(true);
allItemGrid = (GridView) allView.findViewById(R.id.pop_grid);
allView.setFocusableInTouchMode(true);
allView.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (isShowing()) {
dismiss();
return true;
}
return false;
}
});
DisplayMetrics dm=new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
setContentView(allView);
setWidth(dm.widthPixels/2);
setHeight(LayoutParams.WRAP_CONTENT);
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setTouchable(true);
setFocusable(true);
setOutsideTouchable(true);
}
/**
*
* @return 返回該pop中GridView,可以其他地方設置該GridView
*/
public GridView getAllItemGrid() {
return allItemGrid;
}
}
上面是gridpop的代碼。裏面是gridview,其實pop裏面可以填很多View的。不再贅述,在封裝pop之後,只需要改下佈局文件,改下數據,在其他地方就可以方便的new出來不同需求的pop。比如在基類activity做了popmenu的popwindow的操作,那麼其他子activity就可以很方便的繼承。
來看下MainActivity
/**
*
* @author yaguang.wang
*
*/
public class Activity_Main extends Activity {
private Button btn1,btn2;
private MenuPop popMenu;
private DefaultPop defaultPop;
private GridPop gridpop;
private ArrayList<String> stringArray;
private GridView gv;
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.main);
initView();
super.onCreate(savedInstanceState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("xx");//觸發onMenuOpened
return super.onCreateOptionsMenu(menu);
}
/**
* popMenu
*/
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
if (popMenu!=null) {
if (popMenu.isShowing()) {
popMenu.dismiss();
}
else {
View v=this.getLayoutInflater().inflate(R.layout.pop_menu, null);
popMenu.showAtLocation(v, Gravity.BOTTOM, 0, 0);
}
}
//爲false時,才能屏蔽menu add的xx
return false;
}
private void initView(){
//彈出pop1 比較醜見諒
btn1 = (Button) this.findViewById(R.id.main_btn1);
//彈出pop2 比較醜見諒
btn2 = (Button) this.findViewById(R.id.main_btn2);
btn1.setOnClickListener(new ClickListener());
btn2.setOnClickListener(new ClickListener());
popMenu = new MenuPop(R.layout.pop_menu, Activity_Main.this);
//list傳值
stringArray = new ArrayList<String>();
for (int i = 1; i <= 20; i++) {
stringArray.add("item"+i);
}
defaultPop = new DefaultPop(Activity_Main.this, R.layout.default_popwin);
gridpop = new GridPop(Activity_Main.this, R.layout.pop_list);
gv = gridpop.getAllItemGrid();
gv.setAdapter(new GridViewAdapter(Activity_Main.this, stringArray));
gv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//TODO DO SOMETHING
Toast.makeText(getApplicationContext(), "item on clicked"+position, Toast.LENGTH_SHORT).show();
if (gridpop.isShowing()) {
gridpop.dismiss();
}
}
});
}
private class ClickListener implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
/**
* pop1 簡單控件
*/
case R.id.main_btn1:
if (defaultPop!=null) {
if (defaultPop.isShowing()) {
defaultPop.dismiss();
} else {
defaultPop.showAsDropDown(v);
}
}
break;
/**
* pop2 複雜控件
*/
case R.id.main_btn2:
if (gridpop!=null) {
if (gridpop.isShowing()) {
gridpop.dismiss();
} else {
gridpop.showAsDropDown(v);
}
}
break;
}
}
}
}
其他部分的代碼就不貼出了。共同學習,源碼,在http://download.csdn.net/detail/wangyg1990/7317203