您的位置:首页 > 移动开发 > Android开发

Android 自定义菜单

2012-12-09 17:38 281 查看
Android 自定义菜单

分类:
android应用开发 2012-03-05 14:12
1328人阅读 评论(0)
收藏
举报

Android2.2版本中,如果你要修改菜单默认的背景颜色,网络上有许多的方法。在此就不说了。但是,如果要在2.2以上的版本修改菜单的样式,例如修改背景颜色,图片等,使用这些方法是没有任何作用的。因此自己写了一个自定义的菜单控件,可以自由定义菜单的样式,使得菜单的样式更加丰富。本文参考了这篇文章而写的:/article/1363066.html

程序运行效果:



MyMenu本身是一个PopupWindow,PopupWindow上放了一个GridView。给GridView配了一个MyMenuAdapter,于是有了菜单的样子。

1: 在工程的res文件夹下添加目录anim子目录,在anim文件夹中,新建了两个文件:

popup_enter.xml

[html]
view plaincopyprint?

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="500"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="500"/>

</set>

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="500"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="500"/>

</set>
popup_exit.xml

[html]
view plaincopyprint?

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate android:fromYDelta="0" android:toYDelta="100%p" android:duration="1000"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="1000"/>

</set>

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate android:fromYDelta="0" android:toYDelta="100%p" android:duration="1000"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="1000"/>

</set>


2: 在工程的values文件夹下新建popup_animation.xml文件。

[html]
view plaincopyprint?

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="PopupAnimation" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/popup_enter</item>
<item name="android:windowExitAnimation">@anim/popup_exit</item>
</style>

</resources>

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="PopupAnimation" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/popup_enter</item>
<item name="android:windowExitAnimation">@anim/popup_exit</item>
</style>

</resources>


3: main.xml代码如下:

[html]
view plaincopyprint?

<?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:orientation="vertical"
android:id="@+id/linearLayout01">

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />

</LinearLayout>

<?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:orientation="vertical"
android:id="@+id/linearLayout01">

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />

</LinearLayout>


4: MyMenu的源码如下:

[java]
view plaincopyprint?

package com.haozi.demo.menu3.wiget;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

/**
* 我的菜单
* @author haozi
*
*/
public class MyMenu extends PopupWindow {

private GridView gvTitle; // 标题

private LinearLayout mLayout; // PopupWindow的布局

private MyMenuAdapter myMenuAdapter; // 自定义菜单的适配器

/**
* 构造方法
* @param context 调用方的上下文
* @param titleClick 菜单点击事件
* @param myMenuAdapter 菜单适配器
* @param myMenuBackgroundColor 菜单背景颜色
* @param myMenuAnim 菜单需要的动画效果
*/
public MyMenu(Context context, OnItemClickListener titleClick,
int myMenuBackgroundColor, int myMenuAnim){
super(context);

// 创建适配器
myMenuAdapter = new MyMenuAdapter(context,
new String[]{"目录", "书签", "摘要", "设置"},
16,
Color.argb(255, 139, 106, 47), // 未选中字体颜色

Color.argb(255, 247, 246, 234), // 选中字体颜色

Color.argb(255, 247, 246, 234), // 未选中背景颜色

Color.argb(255, 139, 106, 47)); // 选中背景颜色

mLayout = new LinearLayout(context);
mLayout.setOrientation(LinearLayout.VERTICAL);
// 菜单选项栏
gvTitle = new GridView(context);
gvTitle.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// 设置列数
gvTitle.setNumColumns(myMenuAdapter.getCount());
// 设置宽度自适应
gvTitle.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
gvTitle.setVerticalSpacing(1);
gvTitle.setHorizontalSpacing(1);
gvTitle.setGravity(Gravity.CENTER);
gvTitle.setOnItemClickListener(titleClick);
// 选中的时候为透明色
gvTitle.setSelector(new ColorDrawable(Color.TRANSPARENT));
gvTitle.setAdapter(myMenuAdapter);
// 把gvTitle放在layout上
this.mLayout.addView(gvTitle);

// 设置菜单的特征
setContentView(this.mLayout);
setWidth(LayoutParams.FILL_PARENT);
setHeight(LayoutParams.WRAP_CONTENT);
setBackgroundDrawable(new ColorDrawable(myMenuBackgroundColor));
setAnimationStyle(myMenuAnim);
setFocusable(true);

mLayout.setFocusableInTouchMode(true);
mLayout.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;
}
});
}

public void setTitleSelect(int index)
{
gvTitle.setSelection(index);
this.myMenuAdapter.setFocus(index);
}

/**
* 适配器
* @author haozi
*
*/
class MyMenuAdapter extends BaseAdapter{

private Context context;
private TextView[] tvTitles;
private int fontUnSelColor;
private int fontSelColor;
private int bgUnSelColor;
private int bgSelColor;

/**
* 设置 title
* @param context 调用方的上下文
* @param titles 数据
* @param fontSize 字体大小
* @param fontUnSelColor 未选中字体颜色
* @param fontSelColor 选中字体颜色
* @param bgUnSelColor 未选中背景颜色
* @param bgSelColor 选中背景颜色
*/
public MyMenuAdapter(Context context, String[] titles,
int fontSize, int fontUnSelColor, int fontSelColor, int bgUnSelColor, int bgSelColor){
this.context = context;
this.fontUnSelColor = fontUnSelColor;
this.fontSelColor = fontSelColor;
this.bgUnSelColor = bgUnSelColor;
this.bgSelColor = bgSelColor;
// 根据传递进来的titles创建menu上的textView。

tvTitles = new TextView[titles.length];
for(int i=0; i<titles.length; i++){
tvTitles[i] = new TextView(context);
tvTitles[i].setText(titles[i]);
tvTitles[i].setTextSize(fontSize);
tvTitles[i].setTextColor(fontUnSelColor);
tvTitles[i].setGravity(Gravity.CENTER);
tvTitles[i].setPadding(10, 30, 10, 30);
}
}

@Override
public int getCount() {
// TODO Auto-generated method stub

return tvTitles.length;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub

return tvTitles[position];
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub

return tvTitles[position].getId();
}

/**
* 设置选中效果
*
* @param index
*
* @project:
*
* @author haozi on 2012-3-5
*/
public void setFocus(int index){

for(int i=0; i<tvTitles.length; i++){

if(i != index){// 如果未选中

this.tvTitles[i].setBackgroundColor(this.bgUnSelColor);
this.tvTitles[i].setTextColor(this.fontUnSelColor);
}else{// 如果选中

this.tvTitles[i].setBackgroundColor(this.bgSelColor);
this.tvTitles[i].setTextColor(this.fontSelColor);
}
}
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

View v = null;
if(convertView == null){
v = tvTitles[position];
}else{
v = convertView;
}
return v;
}
}
}

package com.haozi.demo.menu3.wiget;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

/**
* 我的菜单
* @author haozi
*
*/
public class MyMenu extends PopupWindow {

private GridView gvTitle;                 // 标题
private LinearLayout mLayout;             // PopupWindow的布局
private MyMenuAdapter myMenuAdapter;      // 自定义菜单的适配器

/**
* 构造方法
* @param context 调用方的上下文
* @param titleClick 菜单点击事件
* @param myMenuAdapter 菜单适配器
* @param myMenuBackgroundColor 菜单背景颜色
* @param myMenuAnim 菜单需要的动画效果
*/
public MyMenu(Context context, OnItemClickListener titleClick,
int myMenuBackgroundColor, int myMenuAnim){
super(context);

// 创建适配器
myMenuAdapter = new MyMenuAdapter(context,
new String[]{"目录", "书签", "摘要", "设置"},
16,
Color.argb(255, 139, 106, 47),  // 未选中字体颜色
Color.argb(255, 247, 246, 234), // 选中字体颜色
Color.argb(255, 247, 246, 234), // 未选中背景颜色
Color.argb(255, 139, 106, 47)); // 选中背景颜色

mLayout = new LinearLayout(context);
mLayout.setOrientation(LinearLayout.VERTICAL);
// 菜单选项栏
gvTitle = new GridView(context);
gvTitle.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// 设置列数
gvTitle.setNumColumns(myMenuAdapter.getCount());
// 设置宽度自适应
gvTitle.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
gvTitle.setVerticalSpacing(1);
gvTitle.setHorizontalSpacing(1);
gvTitle.setGravity(Gravity.CENTER);
gvTitle.setOnItemClickListener(titleClick);
// 选中的时候为透明色
gvTitle.setSelector(new ColorDrawable(Color.TRANSPARENT));
gvTitle.setAdapter(myMenuAdapter);
// 把gvTitle放在layout上
this.mLayout.addView(gvTitle);

// 设置菜单的特征
setContentView(this.mLayout);
setWidth(LayoutParams.FILL_PARENT);
setHeight(LayoutParams.WRAP_CONTENT);
setBackgroundDrawable(new ColorDrawable(myMenuBackgroundColor));
setAnimationStyle(myMenuAnim);
setFocusable(true);

mLayout.setFocusableInTouchMode(true);
mLayout.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;
}
});
}

public void setTitleSelect(int index)
{
gvTitle.setSelection(index);
this.myMenuAdapter.setFocus(index);
}

/**
* 适配器
* @author haozi
*
*/
class MyMenuAdapter extends BaseAdapter{

private Context context;
private TextView[] tvTitles;
private int fontUnSelColor;
private int fontSelColor;
private int bgUnSelColor;
private int bgSelColor;

/**
* 设置 title
* @param context 调用方的上下文
* @param titles 数据
* @param fontSize 字体大小
* @param fontUnSelColor 未选中字体颜色
* @param fontSelColor 选中字体颜色
* @param bgUnSelColor 未选中背景颜色
* @param bgSelColor 选中背景颜色
*/
public MyMenuAdapter(Context context, String[] titles,
int fontSize, int fontUnSelColor, int fontSelColor, int bgUnSelColor, int bgSelColor){
this.context = context;
this.fontUnSelColor = fontUnSelColor;
this.fontSelColor = fontSelColor;
this.bgUnSelColor = bgUnSelColor;
this.bgSelColor = bgSelColor;
// 根据传递进来的titles创建menu上的textView。
tvTitles = new TextView[titles.length];
for(int i=0; i<titles.length; i++){
tvTitles[i] = new TextView(context);
tvTitles[i].setText(titles[i]);
tvTitles[i].setTextSize(fontSize);
tvTitles[i].setTextColor(fontUnSelColor);
tvTitles[i].setGravity(Gravity.CENTER);
tvTitles[i].setPadding(10, 30, 10, 30);
}
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return tvTitles.length;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return tvTitles[position];
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return tvTitles[position].getId();
}

/**
* 设置选中效果
*
* @param index
*
* @project:
*
* @author haozi on 2012-3-5
*/
public void setFocus(int index){

for(int i=0; i<tvTitles.length; i++){

if(i != index){// 如果未选中
this.tvTitles[i].setBackgroundColor(this.bgUnSelColor);
this.tvTitles[i].setTextColor(this.fontUnSelColor);
}else{// 如果选中
this.tvTitles[i].setBackgroundColor(this.bgSelColor);
this.tvTitles[i].setTextColor(this.fontSelColor);
}
}
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

View v = null;
if(convertView == null){
v = tvTitles[position];
}else{
v = convertView;
}
return v;
}
}
}


5: demo的Activity的源码如下,是在这里创建MyMenu。

[java]
view plaincopyprint?

/**
* 入口Activity
* @author haozi
*
*/
public class _04MyMenuDemo3Activity extends Activity {

private MyMenu myMenu;
private int setTitle;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myMenu = new MyMenu(this,
new TitleClickEvent(),
Color.argb(255, 139, 106, 47),
R.style.PopupAnimation);

myMenu.update();
myMenu.setTitleSelect(0);
}

class TitleClickEvent implements OnItemClickListener{

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
setTitle=arg2;
myMenu.setTitleSelect(setTitle);
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

menu.add("menu");
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onMenuOpened(int featureId, Menu menu) {

if (myMenu != null) {
if (myMenu.isShowing())
myMenu.dismiss();
else {
myMenu.showAtLocation(findViewById(R.id.linearLayout01),
Gravity.BOTTOM, 0, 0);
}
}
return false;// 返回为true 则显示系统menu

}
}

/**
* 入口Activity
* @author haozi
*
*/
public class _04MyMenuDemo3Activity extends Activity {

private MyMenu myMenu;
private int setTitle;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myMenu = new MyMenu(this,
new TitleClickEvent(),
Color.argb(255, 139, 106, 47),
R.style.PopupAnimation);

myMenu.update();
myMenu.setTitleSelect(0);
}

class TitleClickEvent implements OnItemClickListener{

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
setTitle=arg2;
myMenu.setTitleSelect(setTitle);
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

menu.add("menu");
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onMenuOpened(int featureId, Menu menu) {

if (myMenu != null) {
if (myMenu.isShowing())
myMenu.dismiss();
else {
myMenu.showAtLocation(findViewById(R.id.linearLayout01),
Gravity.BOTTOM, 0, 0);
}
}
return false;// 返回为true 则显示系统menu
}
}


demo下载链接地址:http://download.csdn.net/detail/hello_haozi/4291200
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: