剛開始學習android,下了個apk,發現它的menu很帥氣,而android自帶的menu非常醜,特別是4.0之後,menu變成了垂直的list,更醜,於是花了點時間模仿了一個
效果圖如下:
源碼下載地址:http://download.csdn.net/detail/cbxjj/7513471
點擊更多按鈕來進行換頁操作
代碼如下:
1.Activity
public class SlideActivity extends Activity {
private MyMenu_1 myMenu;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onResume() {
super.onResume();
myMenu = new MyMenu_1(SlideActivity.this);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_MENU:
if (myMenu.isShowing()) {
myMenu.dismiss();
} else {
//將彈出menu顯示到底部
myMenu.showAtLocation(findViewById(R.id.main_layout),
Gravity.BOTTOM, 0, 0);
}
break;
case KeyEvent.KEYCODE_BACK:
myMenu.dismiss();
break;
}
return super.onKeyDown(keyCode, event);
}
}
2.MyMenu_1
public class MyMenu_1 extends PopupWindow {
private static int menuSize = 1;
private Context mContext;
private RelativeLayout mLinearLayout;
private GridView mGridView;
private String[] titles = { "添加收藏夾", "查找短信", "新增短信", "定時任務", "發送報告", "更多", "設置", "關於", "幫助", "反饋", "返回" };
private int[] images = { R.drawable.icon_menu_favorite,
R.drawable.icon_menu_search, R.drawable.icon_menu_add,R.drawable.icon_menu_schedule_task,
R.drawable.icon_menu_view_sent_status,R.drawable.icon_menu_more,R.drawable.icon_menu_setting,
R.drawable.icon_menu_info,R.drawable.icon_menu_help,R.drawable.icon_menu_feedback,R.drawable.icon_menu_back};
private List<HashMap<String,Object>> itemList = new ArrayList<HashMap<String,Object>>();
private SimpleAdapter adapter;
private LayoutInflater inflater;
public MyMenu_1(Context context){
super(context);
mContext = context;
initDatas();
initViewInWin();
this.setWidth(LayoutParams.FILL_PARENT);
this.setHeight(LayoutParams.WRAP_CONTENT);
//這裏用上了我們在popupWindow中定義的animation了
this.setAnimationStyle(android.R.style.Animation_Dialog);
this.setContentView(mLinearLayout);
ColorDrawable dw = new ColorDrawable(-00000);
this.setBackgroundDrawable(dw);
/*設置觸摸外面時消失*/
this.setOutsideTouchable(true);
//這裏要設置爲true,否則將無法響應popupWindow中控件的點擊事件。
this.setFocusable(true);
// this.update();
this.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
menuSize = 1;
itemList.clear();
initDatas();
}
});
}
/**
* 初始化popupWindow中的內容
*/
public void initViewInWin(){
inflater = (LayoutInflater)mContext.getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
mLinearLayout = (RelativeLayout)inflater.inflate(R.layout.slide_menu, null);
//這裏需要設置成可以獲取焦點,否則無法響應OnKey事件
mLinearLayout.setFocusable(true);
mLinearLayout.setFocusableInTouchMode(true);
//在這裏設置,即可實現關閉的效果。
mLinearLayout.setOnKeyListener(new LayouOnKeyEvent());
mGridView = (GridView)mLinearLayout.findViewById(R.id.menu_gridView);
//設置item點擊響應的時間
mGridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if(menuSize == 1 && position == 5){
MyMenu_1.this.dismiss();
menuSize = 2;
itemList.clear();
initDatas();
MyMenu_1.this.showAtLocation(mGridView.findViewById(R.id.menu_item_layout), Gravity.BOTTOM, 0, 0);
}
if(menuSize == 2 && position == 4){
MyMenu_1.this.dismiss();
MyMenu_1.this.showAtLocation(mGridView.findViewById(R.id.menu_item_layout), Gravity.BOTTOM, 0, 0);
}
}
});
mGridView.setAdapter(adapter);
}
/**
* 初始化數據內容
*/
public void initDatas(){
int forStart = 0;
int forEnd = 5;
if(menuSize==1){
forStart = 0;
forEnd = 5;
}
if(menuSize==2){
forStart = 6;
forEnd = 6*2-1>titles.length-1?titles.length-1:6*2-1;
}
for(int i = forStart; i<=forEnd; i++){
HashMap<String,Object> map = new HashMap<String, Object>();
map.put("image", images[i]);
map.put("title", titles[i]);
itemList.add(map);
}
adapter = new SimpleAdapter(mContext, itemList, R.layout.my_menu_item,
new String[]{"image","title"}, new int[]{R.id.item_image,R.id.item_title});
}
class LayouOnKeyEvent implements OnKeyListener{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
menuSize = 1;
itemList.clear();
initDatas();
MyMenu_1.this.showAtLocation(mGridView.findViewById(R.id.menu_item_layout), Gravity.BOTTOM, 0, 0);
//判斷事件爲menu按鈕按下時,將popupWindow關閉
if(event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_MENU){
if(MyMenu_1.this.isShowing()){
MyMenu_1.this.dismiss();
}
}
return true;
}
}
}
3.slide_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/gdi_arrow_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/gdi_header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/gdi_arrow_up"
android:background="@drawable/quick_action_top_frame" />
<GridView
android:id="@+id/menu_gridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:fadingEdgeLength="0.0dip"
android:background="@drawable/quick_action_grid_bg"
android:horizontalSpacing="10dip"
android:listSelector="@drawable/quick_action_grid_selector"
android:numColumns="3"
android:padding="10dip"
android:stretchMode="columnWidth"
android:layout_below="@id/gdi_header"
android:verticalSpacing="10dip" >
</GridView>
<FrameLayout
android:id="@+id/gdi_footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/menu_gridView"
android:background="@drawable/quick_action_grid_bottom_frame" />
<ImageView
android:id="@+id/gdi_arrow_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/gdi_footer" />
</RelativeLayout>
4.my_menu_item.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/menu_item_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_centerHorizontal="true"
/>
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_below="@id/item_image"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
很順利的做出來了。效果和效果圖一致,基本和apk裏面的差不多,但是我覺得分頁操作不是很方便,覺得android的滾屏左右滑動效果不錯,
用到這個上面也還不錯,於是開始查資料,發現viewPager和viewgroup都可以做,先用viewgroup做了一晚上,各種bug,快崩潰了。
於是換viewPager,中間雖然出了很多次問題,但是還是做出來了,效果如下:
直接上代碼:
1.PopupMenuActivity
public class PopupMenuActivity extends Activity {
private MyMenu myMenu;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onResume() {
super.onResume();
myMenu = new MyMenu(PopupMenuActivity.this);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_MENU:
if (myMenu.isShowing()) {
myMenu.dismiss();
} else {
myMenu.showAtLocation(findViewById(R.id.main_layout),
Gravity.BOTTOM, 0, 0);
}
break;
case KeyEvent.KEYCODE_BACK:
myMenu.dismiss();
break;
}
return super.onKeyDown(keyCode, event);
}
}
2.Mymenu.java
public class MyMenu extends PopupWindow {
private Context mContext;
private LinearLayout mLinearLayout;
private LinearLayout pointLLayout;
private GridView mGridView1;
private GridView mGridView2;
private String[] titles = { "添加收藏夾", "查找短信", "新增短信", "定時任務", "發送報告", "更多",
"設置", "關於", "幫助", "反饋", "返回" };
private int[] images = { R.drawable.icon_menu_favorite,
R.drawable.icon_menu_search, R.drawable.icon_menu_add,
R.drawable.icon_menu_schedule_task,
R.drawable.icon_menu_view_sent_status, R.drawable.icon_menu_more,
R.drawable.icon_menu_setting, R.drawable.icon_menu_info,
R.drawable.icon_menu_help, R.drawable.icon_menu_feedback,
R.drawable.icon_menu_back };
private List<HashMap<String, Object>> itemList1 = new ArrayList<HashMap<String, Object>>();
private List<HashMap<String, Object>> itemList2 = new ArrayList<HashMap<String, Object>>();
private MySimpleAdapter adapter1;
private MySimpleAdapter adapter2;
private LayoutInflater inflater;
private ImageView[] imgs;
private int count;
private int currentItem;
private MyViewPagerAdapter adapter;
private MyViewPager viewPager;
private ArrayList<GridView> array = new ArrayList<GridView>();
public MyMenu(Context context) {
super(context);
mContext = context;
initDatas();
initViewInWin();
this.setWidth(LayoutParams.FILL_PARENT);
this.setHeight(LayoutParams.WRAP_CONTENT);
// 這裏用上了我們在popupWindow中定義的animation了
this.setAnimationStyle(android.R.style.Animation_Dialog);
this.setContentView(mLinearLayout);
//必須設置背景色爲透明,不然彈出窗口寬度不全屏
ColorDrawable dw = new ColorDrawable(-00000);
this.setBackgroundDrawable(dw);
/* 設置觸摸外面時消失 */
this.setOutsideTouchable(true);
// 這裏要設置爲true,否則將無法響應popupWindow中控件的點擊事件。
this.setFocusable(true);
this.update();
this.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
itemList1.clear();
itemList2.clear();
initDatas();
}
});
pointLLayout = (LinearLayout) mLinearLayout.findViewById(R.id.llayout);
viewPager = (MyViewPager) mLinearLayout.findViewById(R.id.myviewpager);
count = viewPager.getChildCount();
imgs = new ImageView[count];
for (int i = 0; i < count; i++) {
imgs[i] = (ImageView) pointLLayout.getChildAt(i);
imgs[i].setEnabled(true);
imgs[i].setTag(i);
}
currentItem = 0;
imgs[currentItem].setEnabled(false);
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int point) {
setcurrentPoint(point);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int point) {
}
});
adapter = new MyViewPagerAdapter(mContext, array);
viewPager.setAdapter(adapter);
}
protected void setcurrentPoint(int position) {
if (position < 0 || position > count - 1 || currentItem == position) {
return;
}
imgs[currentItem].setEnabled(true);
imgs[position].setEnabled(false);
currentItem = position;
}
public void initViewInWin() {
inflater = (LayoutInflater) mContext
.getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
mLinearLayout = (LinearLayout) inflater.inflate(R.layout.my_menu, null);
mLinearLayout.setFocusable(true);
mLinearLayout.setFocusableInTouchMode(true);
mLinearLayout.setOnKeyListener(new LayouOnKeyEvent());
mGridView1 = (GridView) mLinearLayout.findViewById(R.id.menu_gridView1);
mGridView2 = (GridView) mLinearLayout.findViewById(R.id.menu_gridView2);
mGridView1.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
System.out.println("點擊第一個第" + position + "個按鈕");
}
});
mGridView1.setAdapter(adapter1);
mGridView2.setAdapter(adapter2);
array.add(mGridView1);
array.add(mGridView2);
}
public void initDatas() {
int forStart = 0;
int forEnd = 5;
for (int i = forStart; i <= forEnd; i++) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("image", images[i]);
map.put("title", titles[i]);
itemList1.add(map);
}
adapter1 = new MySimpleAdapter(mContext, itemList1,
R.layout.my_menu_item, new String[] { "image", "title" },
new int[] { R.id.item_image, R.id.item_title });
forStart = 6;
forEnd = 6 * 2 - 1 > titles.length - 1 ? titles.length - 1 : 6 * 2 - 1;
for (int i = forStart; i <= forEnd; i++) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("image", images[i]);
map.put("title", titles[i]);
itemList2.add(map);
}
adapter2 = new MySimpleAdapter(mContext, itemList2,
R.layout.my_menu_item, new String[] { "image", "title" },
new int[] { R.id.item_image, R.id.item_title });
}
class LayouOnKeyEvent implements OnKeyListener {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
itemList1.clear();
itemList2.clear();
initDatas();
MyMenu.this.showAtLocation(
mLinearLayout.findViewById(R.id.menu_item_layout),
Gravity.BOTTOM, 0, 0);
// 判斷事件爲menu按鈕按下時,將popupWindow關閉
if (event.getAction() == KeyEvent.ACTION_DOWN
&& keyCode == KeyEvent.KEYCODE_MENU) {
if (MyMenu.this.isShowing()) {
MyMenu.this.dismiss();
}
}
return true;
}
}
}
3.MySimpleAdapter 不用SimpleAdapter 而是自己寫一個,因爲報了一個The observer is null.查了下問題,應該是關閉window的時候setAdapter的時候unregisterDataSetObserver沒判斷mDataSetObserver是否爲空,據說是因爲嵌套控件導致,這裏直接判斷下就完了
public class MySimpleAdapter extends SimpleAdapter {
public MySimpleAdapter(Context context,
List<? extends Map<String, ?>> data, int resource, String[] from,
int[] to) {
super(context, data, resource, from, to);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
if (observer != null) {
super.unregisterDataSetObserver(observer);
}
}
}
4.MyViewPager 繼承了android.support.v4.view.ViewPager,因爲這個控件高度自動全屏了 設置wrap_content也沒用,這裏集成了ViewPager重新設置了以下高度
public class MyViewPager extends ViewPager {
public MyViewPager(Context context) {
super(context);
}
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height)
height = h;
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height*2,
MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
5.MyViewPagerAdapter重寫了PagerAdapter
public class MyViewPagerAdapter extends PagerAdapter {
private List<GridView> array;
/**
* 供外部調用(new)的方法
*
* @param context
* 上下�?
* @param imageViews
* 添加的序列對�?
*/
public MyViewPagerAdapter(Context context, List<GridView> array) {
this.array = array;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return array.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
}
@Override
public Object instantiateItem(View arg0, int arg1) {
((ViewPager) arg0).addView(array.get(arg1));
return array.get(arg1);
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
if (observer != null) {
super.unregisterDataSetObserver(observer);
}
}
}
6.my_menu.xml 注意這裏最外層必須用LinearLayout,否則會報一個android.support.v4.view.ViewPager canot be cast to。。。。
轉換異常,用RelativeLayout狂報錯。
<?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="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/gdi_arrow_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/gdi_header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/quick_action_top_frame" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/renlayout"
android:background="@drawable/quick_action_grid_bg"
>
<com.cbxjj.myplugins.MyViewPager
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:scaleType="fitXY"
android:layout_gravity="center"
android:id="@+id/myviewpager">
<GridView
android:id="@+id/menu_gridView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fadingEdgeLength="0.0dip"
android:gravity="center"
android:horizontalSpacing="10dip"
android:listSelector="@drawable/quick_action_grid_selector"
android:numColumns="3"
android:padding="10dip"
android:stretchMode="columnWidth"
android:verticalSpacing="10dip" >
</GridView>
<GridView
android:id="@+id/menu_gridView2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fadingEdgeLength="0.0dip"
android:gravity="center"
android:horizontalSpacing="10dip"
android:listSelector="@drawable/quick_action_grid_selector"
android:numColumns="3"
android:padding="10dip"
android:stretchMode="columnWidth"
android:verticalSpacing="10dip" >
</GridView>
</com.cbxjj.myplugins.MyViewPager>
<LinearLayout
android:orientation="horizontal"
android:id="@+id/llayout"
android:layout_width="fill_parent"
android:layout_height="15dp"
android:layout_below="@id/myviewpager"
android:layout_centerHorizontal="true"
android:gravity="center"
android:visibility="visible">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="true"
android:padding="5.0dip"
android:src="@drawable/page_indicator_bg" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="true"
android:padding="5.0dip"
android:src="@drawable/page_indicator_bg" />
</LinearLayout>
</RelativeLayout>
<FrameLayout
android:id="@+id/gdi_footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/quick_action_grid_bottom_frame" >
</FrameLayout>
</LinearLayout>
以上。源碼下載地址:http://download.csdn.net/detail/cbxjj/7513471