当前位置:  编程技术>移动开发
本页文章导读:
    ▪保护模式预备知识-书中pm.inc代码详细注释        保护模式预备知识--书中pm.inc代码详细注释    描述符包括,存储段描述符(代码段,数据段,堆栈段),系统描述符(任务状态段TSS,局部描述符表LDT),门描述符(调用门,任务门,中断.........
    ▪ Ubuntu12.04下NFS Server安装使用过程        Ubuntu12.04上NFS Server安装使用过程原文链接:Ubuntu12.04上NFS Server安装使用过程 实现步骤: 1.服务器端:sudo apt-get install portmap 2.服务器端:sudo apt-get install nfs-kernel-server 3.客户端:sudo apt-get instal.........
    ▪ ActivityGroup的应用       ActivityGroup的使用ActivityGroup是Activity的子类,在Activity的基础上还扩充了一些东西,如可以让多个Activity程序在同一界面上运行且互不干扰。这种功能在menu比较多的地方使用起来会很方便,用.........

[1]保护模式预备知识-书中pm.inc代码详细注释
    来源: 互联网  发布时间: 2014-02-18
保护模式预备知识--书中pm.inc代码详细注释

    描述符包括,存储段描述符(代码段,数据段,堆栈段),系统描述符(任务状态段TSS,局部描述符表LDT),门描述符(调用门,任务门,中断门,陷阱门),注意门描述符和系统描述符都是DT=0时候,对应的状态。存储段描述符和系统描述符如图1,门描述符如图2。

                    

                                   图1 存储段描述符和系统描述符

                    

                                      图2 门描述符

    (1) P:存在(Present)位。

    P=1 表示描述符对地址转换是有效的,或者说该描述符所描述的段存在,即在内存中;
    P=0 表示描述符对地址转换无效,即该段不存在。使用该描述符进行内存访问时会引起异常。
    (2) DPL:  表示描述符特权级(Descriptor Privilege level),共2位。它规定了所描述段的特权级,用于特权检查,以决定对该段能否访问。 
    (3) DT:说明描述符的类型。
    对于存储段描述符而言,DT=1,以区别与系统段描述符和门描述符(DT=0)。 
    (4) TYPE: 说明存储段描述符所描述的存储段的具体属性。
    数据段类型 类型值说明
    ----------------------------------
    0 只读 
    1 只读、已访问 
    2 读/写 
    3 读/写、已访问 
    4 只读、向下扩展 
    5 只读、向下扩展、已访问 
    6 读/写、向下扩展 
    7 读/写、向下扩展、已访问 


    类型值 说明
    代码段类型 ----------------------------------
    8 只执行 
    9 只执行、已访问 
    A 执行/读 
    B 执行/读、已访问 
    C 只执行、一致码段 
    D 只执行、一致码段、已访问 
    E 执行/读、一致码段 
    F 执行/读、一致码段、已访问 


    系统段类型 类型编码说明
    ----------------------------------
    0 <未定义>
    1 可用286TSS
    2 LDT
    3 忙的286TSS
    4 286调用门
    5 任务门
    6 286中断门
    7 286陷阱门
    8 未定义
    9 可用386TSS
    A <未定义>
    B 忙的386TSS
    C 386调用门
    D <未定义>
    E 386中断门
    F 386陷阱门

    (5) G:段界限粒度(Granularity)位。
    G=0 表示界限粒度为字节;
    G=1 表示界限粒度为4K 字节。
    注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位。 
    (6) D:D位是一个很特殊的位,在描述可执行段、向下扩展数据段或由SS寄存器寻址的段(通常是堆栈段)的三种描述符中的意义各不相同。 
    在描述可执行段的描述符中,D位决定了指令使用的地址及操作数所默认的大小。
    ① D=1表示默认情况下指令使用32位地址及32位或8位操作数,这样的代码段也称为32位代码段;
    ② D=0 表示默认情况下,使用16位地址及16位或8位操作数,这样的代码段也称为16位代码段,它与80286兼容。可以使用地址大小前缀和操作数大小前缀分别改变默认的地址或操作数的大小。 
    在向下扩展数据段的描述符中,D位决定段的上部边界。
    ① D=1表示段的上部界限为4G;
    ② D=0表示段的上部界限为64K,这是为了与80286兼容。 
    在描述由SS寄存器寻址的段描述符中,D位决定隐式的堆栈访问指令(如PUSH和POP指令)使用何种堆栈指针寄存器。
    ① D=1表示使用32位堆栈指针寄存器ESP;
    ② D=0表示使用16位堆栈指针寄存器SP,这与80286兼容。 
    (7) AVL:软件可利用位。80386对该位的使用未左规定,Intel公司也保证今后开发生产的处理器只要与80386兼容,就不会对该位的使用做任何定义或规定。 
    (8) Dword Count:从调用者堆栈中将参数复制到被调用者堆栈(新堆栈)中,复制参数的个数由调用门中Dword Count一项来决定。如果Dword Count为0,那么不会复制参数。
    
    选择子图示:
         ┏━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┓
         ┃ 15 ┃ 14 ┃ 13 ┃ 12 ┃ 11 ┃ 10 ┃ 9  ┃ 8  ┃ 7  ┃ 6  ┃ 5  ┃ 4  ┃ 3  ┃ 2  ┃ 1  ┃ 0  ┃
         ┣━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━╋━━╋━━┻━━┫
         ┃                                 描述符索引                                 ┃ TI ┃   RPL    ┃
         ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━┻━━━━━┛
    RPL(Requested Privilege Level): 请求特权级,用于特权检查。
    TI(Table Indicator): 引用描述符表指示位
    TI=0 指示从全局描述符表GDT中读取描述符;
    TI=1 指示从局部描述符表LDT中读取描述符。 

    LDT中的描述符和GDT中的描述符除了选择子的bit3一个为0一个为1用于区分该描述符是在GDT中还是在LDT中外,描述符本身的结构完全一样。开始我考虑既然是这样,为什么要将LDT放在GDT中而不是像GDT那样找一个GDTR寄存器呢?

    后来终于明白了原因--很简单,GDT表只有一个,是固定的;而LDT表每个任务就可以有一个,因此有多个,并且由于任务的个数在不断变化其数量也在不断变化。如果只有一个LDTR寄存器显然不能满足多个LDT的要求。因此INTEL的做法是把它放在放在GDT中。


    pm.inc代码如下:

;----------------------------------------
; 描述符类型值说明
; 其中:
;       DA_  : Descriptor Attribute
;       D    : 数据段
;       C    : 代码段
;       S    : 系统段
;       R    : 只读
;       RW   : 读写
;       A    : 已访问
;       其它 : 可按照字面意思理解
G D 0 AVL 0 0 0 0 P DPL(2位) DT TYPE(4位)
;----------------------------------------
DA_32		EQU	4000h	; 32 位段 0100 0000 0000 0000

DA_DPL0		EQU	  00h	; DPL = 0 0000 0000
DA_DPL1		EQU	  20h	; DPL = 1 0010 0000
DA_DPL2		EQU	  40h	; DPL = 2 0100 0000
DA_DPL3		EQU	  60h	; DPL = 3 0110 0000
;----------------------------------------
; 存储段描述符类型值说明
;----------------------------------------
DA_DR		EQU	90h	; 存在的只读数据段类型值  1001 0000
DA_DRW		EQU	92h	; 存在的可读写数据段属性值 1001 0010
DA_DRWA		EQU	93h	; 存在的已访问可读写数据段类型值 1001 0011
DA_C		EQU	98h	; 存在的只执行代码段属性值 1001 1000
DA_CR		EQU	9Ah	; 存在的可执行可读代码段属性值 1001 1010
DA_CCO		EQU	9Ch	; 存在的只执行一致代码段属性值 1001 1100
DA_CCOR		EQU	9Eh	; 存在的可执行可读一致代码段属性值 1001 1110
;----------------------------------------
; 系统段描述符类型值说明
;----------------------------------------
DA_LDT		EQU	  82h	; 局部描述符表段类型值 1000 0010
DA_TaskGate	EQU	  85h	; 任务门类型值 1000 0101
DA_386TSS	EQU	  89h	; 可用 386 任务状态段类型值 1000 1001
DA_386CGate	EQU	  8Ch	; 386 调用门类型值 1000 1100
DA_386IGate	EQU	  8Eh	; 386 中断门类型值 1000 1110
DA_386TGate	EQU	  8Fh	; 386 陷阱门类型值 1000 1111
;----------------------------------------


;----------------------------------------
; 选择子类型值说明
; 其中:
;       SA_  : Selector Attribute


SA_RPL0		EQU	0	; ┓00
SA_RPL1		EQU	1	; ┣ RPL01
SA_RPL2		EQU	2	; ┃10
SA_RPL3		EQU	3	; ┛11


SA_TIG		EQU	0	; ┓TI 0000
SA_TIL		EQU	4	; ┛  0100
;----------------------------------------


; 宏 ------------------------------------------------------------------
;
; 描述符
; usage: Descriptor Base, Limit, Attr
;        Base:  dd
;        Limit: dd (low 20 bits available)低二十位可用
;        Attr:  dw (lower 4 bits of higher byte are always 0)高字节的低四位始终为0
%macro Descriptor 3 ;段界限为低地址 1代表Base 2代表Limit 3代表属性 
	dw	%2 & 0FFFFh				; 段界限 1				(2 字节)
	dw	%1 & 0FFFFh				; 段首地址 1				(2 字节)
	db	(%1 >> 16) & 0FFh			; 段首地址 2				(1 字节)
	dw	((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)	; 属性 1 + 段界限 2 + 属性 2		(2 字节)
	db	(%1 >> 24) & 0FFh			; 段首地址 3				(1 字节)
%endmacro ; 共 8 字节
;
; 门
; usage: Gate Selector, Offset, DCount, Attr
;        Selector:  dw
;        Offset:    dd
;        DCount:    db
;        Attr:      db
%macro Gate 4 ;1代表Selector 2代表Offset 3代表DCount 4代表Attr
	dw	(%2 & 0FFFFh)				; 偏移 1				(2 字节)
	dw	%1					; 选择子				(2 字节)
	dw	(%3 & 1Fh) | ((%4 << 8) & 0FF00h)	; 属性					(2 字节)
	dw	((%2 >> 16) & 0FFFFh)			; 偏移 2				(2 字节)
%endmacro ; 共 8 字节





    
[2] Ubuntu12.04下NFS Server安装使用过程
    来源: 互联网  发布时间: 2014-02-18
Ubuntu12.04上NFS Server安装使用过程

原文链接:Ubuntu12.04上NFS Server安装使用过程

实现步骤:

1.服务器端:sudo apt-get install portmap
2.服务器端:sudo apt-get install nfs-kernel-server
3.客户端:sudo apt-get install nfs-common
4.服务器端配置:sudo gedit /etc/exports

 

添加:/home/share 192.168.1.*(rw,sync,no_root_squash)
  (共享目录)         (允许IP)   
(rw权限是可擦写,还有ro只读,sync代表数据会同步写入到内存与硬盘中,async则代表数据会先暂存于内存当中,而非直接写入硬盘,开放客户端使用root身份来操作服务器的文件系统,那么开no_root_squash才行,root_squash不允许)
5.服务器端启动:sudo /etc/init.d/portmap restart
6.服务器端启动:sudo /etc/init.d/nfs-kernel-server restart
7.arm板连接时:

主机:sudo ifconfig eth0 192.168.1.101 netmask 255.255.255.0
    arm板:ifconfig eth0 192.168.1.102 netmask 255.255.255.0
8.arm板上mount:mount -t nfs 192.168.1.101:/home/share /mnt/hosts
       (主机IP和共享目录)         (arm板目录)
mount上之后arm板上文件自动同步

1.出现问题:
    reason given by server: Permission denied

解决:服务器端启动一定要sudo启动,不然启动失败,服务拒绝

2.出现问题:
svc: failed to register lockdv1 RPC service (errno 111). 
lockd_up: makesock failed, error=-111 
mount: mounting 192.168.1.101:/home/share on /mnt/hosts failed: Connection refused
则改成:
mount -t nfs -o nolock 192.168.1.101:/home/share /mnt/hosts
3.出现问题:
mount: mounting 192.168.1.101:/home/share on /mnt/hosts failed: Device or resource busy
解决:
mount上之后在进行mount命令会出现此提示,设备正在运行,不用再次mount
如果想再次mount可以先umount /mnt/hosts
)


    
[3] ActivityGroup的应用
    来源: 互联网  发布时间: 2014-02-18
ActivityGroup的使用

ActivityGroup是Activity的子类,在Activity的基础上还扩充了一些东西,如可以让多个Activity程序在同一界面上运行且互不干扰。这种功能在menu比较多的地方使用起来会很方便,用途也很广泛。下面是自己整理的一些代码供大家学习使用。

1.一般来说菜单一般都包含图片,实现这种功能一般都会用到适配器,该适配器继承BaseAdapter,代码如下

package org.lxh.activity;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;

public class MenuImageAdapter extends BaseAdapter{
    private Context context;
    //所有标签的图片显示
    private ImageView[] menuImg;
    //选中的ImageView索引
    private int selectedMenuImg;
	
    public MenuImageAdapter(Context context,int imgIds[],int width,int height,int selectedMenuImg){
    	this.context=context;
    	this.selectedMenuImg=selectedMenuImg;
    	this.menuImg=new ImageView[imgIds.length];
    	for(int x=0;x<imgIds.length;x++){
    		//实例化ImageView对象
    		this.menuImg[x]=new ImageView(this.context);
    		//定义图片的布局参数
    		this.menuImg[x].setLayoutParams(new GridView.LayoutParams(width,height));
    		this.menuImg[x].setAdjustViewBounds(false);
    		this.menuImg[x].setPadding(3, 3, 3, 3);
    		this.menuImg[x].setImageResource(imgIds[x]);
    	}
    }
	public int getCount() {
		// TODO Auto-generated method stub
		return this.menuImg.length;
	}

	
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return this.menuImg[position];
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ImageView imgView=null;
		if(imgView==null){
			imgView=this.menuImg[position];
		}else{
			imgView=(ImageView)convertView;
		}
		return imgView;
	}
   public void setFocus(int selid){
	   for(int x=0;x<this.menuImg.length;x++){
		   if(x!=selid){
			   this.menuImg[x].setBackgroundResource(0);
		   }
	   }
	   this.menuImg[selid].setBackgroundResource(this.selectedMenuImg);
   }
}

到这里第一个适配器就好了,下面为了把功能做好一些,顺便加个弹出菜单,该菜单包含标题和内容。此类弹出菜单也需要写适配器,分别是标题适配器,内容适配器。标题适配器比较简单,只需做一下点击的效果和标题内容的显示就OK,代码如下

package org.lxh.activity;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class PopupMenuTitleAdapter extends BaseAdapter {
	private TextView menuTitle[] = null; // 文字显示组件
	private int fontColor;
	private int selectedColor;
	private int unSelectedColor;

	public PopupMenuTitleAdapter(Context context, int[] titleIds,
			int fontColor, int fontSize, int selectedColor, int unSelectedColor) {
		this.fontColor = fontColor;
		this.selectedColor = selectedColor;
		this.unSelectedColor = unSelectedColor;
		this.menuTitle = new TextView[titleIds.length];
		for (int x = 0; x < titleIds.length; x++) {
			this.menuTitle[x] = new TextView(context);
			this.menuTitle[x].setText(titleIds[x]);
			this.menuTitle[x].setTextSize(fontSize);
			this.menuTitle[x].setGravity(Gravity.CENTER);
			this.menuTitle[x].setPadding(10, 10, 10, 10);
		}
	}

	@Override
	public int getCount() {
		return this.menuTitle.length;
	}

	@Override
	public Object getItem(int position) {
		return this.menuTitle[position];
	}

	@Override
	public long getItemId(int position) {
		return this.menuTitle[position].getId();
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view = null;
		if (convertView == null) {
			view = this.menuTitle[position];
		} else {
			view = convertView;
		}
		return view;
	}

	public void setFocus(int index) {
		for (int x = 0; x < this.menuTitle.length; x++) {
			if (x != index) {
				this.menuTitle[x].setBackgroundDrawable(new ColorDrawable(
						this.unSelectedColor));
				this.menuTitle[x].setTextColor(fontColor);
			}
		}
		this.menuTitle[index].setBackgroundColor(0x00);
		this.menuTitle[index].setTextColor(this.selectedColor);
	}
}
下面是弹出菜单的内容适配器,里面包含了多个Activity.

package org.lxh.activity;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

public class PopupMenuBodyAdapter extends BaseAdapter {
	private ImageView[] menuImg = null ;

	public PopupMenuBodyAdapter(Context context, int [] picIds) {
		this.menuImg = new ImageView[picIds.length];
		for (int x = 0; x < this.menuImg.length; x++) {
			this.menuImg[x] = new ImageView(context) ;
			this.menuImg[x].setImageResource(picIds[x]) ;
		}
	}
	@Override
	public int getCount() {
		return this.menuImg.length;
	}

	@Override
	public Object getItem(int position) {
		return this.menuImg[position];
	}

	@Override
	public long getItemId(int position) {
		return this.menuImg[position].getId();
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view = null ;
		if (convertView == null) {
			view = this.menuImg[position];
		} else {
			view = convertView;
		}
		return view;
	}

}

2.之后便是标题和内容的顶层了,这一层就是PopupMenu了,这个弹出菜单就包含了标题和内容

package org.lxh.activity;

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

public class PopMenu extends PopupWindow {
	private GridView popTitle ;	// 表示标题
	private GridView popBody ;	// 标题主体
	private PopupMenuTitleAdapter titleAdapter = null ;
	private LinearLayout layout = null ;

	public PopMenu(Context context, int titleIds[],int backgroundColor,
			OnItemClickListener titleCallback, OnItemClickListener bodyCallback) {
		super(context); // 还是需要创建弹出的组件
		this.titleAdapter = new PopupMenuTitleAdapter(context, titleIds,
				0xFF222222, 16, Color.LTGRAY, Color.WHITE);
		this.layout = new LinearLayout(context) ;
		this.layout.setOrientation(LinearLayout.VERTICAL) ;
		this.popTitle = new GridView(context);
		this.popTitle.setLayoutParams(new LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 
		this.popTitle.setNumColumns(titleIds.length) ;
		this.popTitle.setHorizontalSpacing(1) ;
		this.popTitle.setVerticalSpacing(1) ;
		this.popTitle.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); // 拉申列宽
		this.popTitle.setAdapter(this.titleAdapter) ;
		this.popTitle.setOnItemClickListener(titleCallback) ;
		
		this.popBody = new GridView(context) ;
		this.popBody.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.WRAP_CONTENT));
		this.popBody.setNumColumns(5) ;
		this.popBody.setHorizontalSpacing(1) ;
		this.popBody.setVerticalSpacing(1) ;
		this.popBody.setPadding(10, 10, 10, 10) ;
		this.popBody.setGravity(Gravity.CENTER) ;
		this.popBody.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); // 拉申列宽
		this.popBody.setOnItemClickListener(bodyCallback) ;
		
		this.layout.addView(this.popTitle) ;
		this.layout.addView(this.popBody) ;
		super.setContentView(this.layout) ;
		super.setWidth(LayoutParams.FILL_PARENT) ;
		super.setHeight(LayoutParams.WRAP_CONTENT) ;
		super.setBackgroundDrawable(new ColorDrawable(backgroundColor)) ;
		super.setFocusable(true) ;	// 允许获得焦点
	}
	
	public void setPopupMenuBodyAdapter(PopupMenuBodyAdapter adapter) {
		this.popBody.setAdapter(adapter) ;
	}
	
	public void setPopTitleSelected(int postion) {
		this.popTitle.setSelection(postion) ;
		this.titleAdapter.setFocus(postion) ;
	}
	
	public void setPopBodySelected(int position,int selectedColor) {	// 设置选中后的颜色
		int count = this.popBody.getChildCount() ;
		for (int x = 0; x < count; x++) {
			if (x != position) {
				ImageView img = (ImageView) this.popBody.getChildAt(x) ;
				img.setBackgroundColor(Color.TRANSPARENT) ;
			}
		}
		ImageView img = (ImageView) this.popBody.getChildAt(position) ;
		img.setBackgroundColor(selectedColor) ;
	}
}

这里呢顺便加了点击效果,点击后背景变为灰色

3.后面就是主要的activity了。此时我们需要显示一个菜单,之后给第四个菜单加弹出式菜单,并在弹出菜单切换程序

package org.lxh.activity;

import android.app.ActivityGroup;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.Toast;

public class PopMenuActivity extends ActivityGroup {
	private GridView gridviewToolbar; // 工具菜单栏
	private MenuImageAdapter menu = null; // 图片适配器
	private LinearLayout content = null; // 填充内容
	private int menu_img[] = new int[] { R.drawable.menu_main,
			R.drawable.menu_news, R.drawable.menu_sms, R.drawable.menu_more,
			R.drawable.menu_exit }; // 填充的图片的资源
	private int width = 0; // 求出平均的宽度
	private int height = 0; // 求出平均的高度,定位显示
	private Intent intent = null;
	private boolean isShow = false ;
	
	private int commonItemIds[] = new int[] { R.drawable.common_account,
			R.drawable.common_addmark, R.drawable.common_download,
			R.drawable.common_exit, R.drawable.common_fullscreen,
			R.drawable.common_history, R.drawable.common_night,
			R.drawable.common_refresh };
	private int setItemIds[] = new int[] { R.drawable.set_button,
			R.drawable.set_mode, R.drawable.set_nophoto,
			R.drawable.set_rotation, R.drawable.set_scroll,
			R.drawable.set_skin, R.drawable.set_system, R.drawable.set_time };
	private int totleItemids[] = new int[] { R.drawable.tool_back,
			R.drawable.tool_copy, R.drawable.tool_file, R.drawable.tool_help,
			R.drawable.tool_report, R.drawable.tool_report,
			R.drawable.tool_save, R.drawable.tool_share };
	
	private int titleIds[] = new int[] { R.string.popmenu_common,
			R.string.popmenu_set, R.string.popmenu_tool };
	private PopMenu popMenu = null ;
	private PopupMenuBodyAdapter commonAdapter = null ;
	private PopupMenuBodyAdapter setAdapter = null ;
	private PopupMenuBodyAdapter toolAdapter = null ;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.requestWindowFeature(Window.FEATURE_NO_TITLE); // 取消标题
		super.setContentView(R.layout.main);
		this.gridviewToolbar = (GridView) super.findViewById(R.id.gridviewbar);
		this.content = (LinearLayout) super.findViewById(R.id.content);

		// 定义工具栏的一些信息显示
		this.gridviewToolbar.setNumColumns(this.menu_img.length); // 求出可以保存的个数
		this.gridviewToolbar.setSelector(new ColorDrawable(Color.TRANSPARENT));
		this.gridviewToolbar.setGravity(Gravity.CENTER);
		this.gridviewToolbar.setVerticalSpacing(0);

		this.width = super.getWindowManager().getDefaultDisplay().getWidth()
				/ this.menu_img.length;
		this.height = super.getWindowManager().getDefaultDisplay().getHeight() / 8;

		this.menu = new MenuImageAdapter(this, this.menu_img, this.width,
				this.height, R.drawable.menu_selected);
		this.gridviewToolbar.setAdapter(this.menu);
		this.switchActivity(0); // 第一个被选中
		this.gridviewToolbar
				.setOnItemClickListener(new OnItemClickListenerImpl());
		
		this.popMenu = new PopMenu(this, this.titleIds, 0x55123456, new PopupTitleOnItemClickListenerCallback(),
				new PopupBodyOnItemClickListenerCallback());
		this.commonAdapter = new PopupMenuBodyAdapter(this, this.commonItemIds);
		this.setAdapter = new PopupMenuBodyAdapter(this, this.setItemIds);
		this.toolAdapter = new PopupMenuBodyAdapter(this, this.totleItemids);
		
		this.popMenu.setPopupMenuBodyAdapter(this.commonAdapter) ;
		this.popMenu.setPopTitleSelected(0) ;
	}

	private class OnItemClickListenerImpl implements OnItemClickListener {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			PopMenuActivity.this.switchActivity(position);
		}
	}

	private void switchActivity(int id) { // 切换选中的操作
		this.menu.setFocus(id); // 设置选中图片的背景
		this.content.removeAllViews(); // 删除所有的内容
		switch (id) {
		case 0:
			this.intent = new Intent(PopMenuActivity.this, MyActivity.class);
			break;
		case 1:
			this.intent = new Intent(PopMenuActivity.this, MyActivity.class);
			break;
		case 2:
			this.intent = new Intent(PopMenuActivity.this, MyActivity.class);
			break;
		case 3:
			this.showPopupMenu() ;
			break;
		case 4:
			this.exitDialog() ;
			return;
		}
		this.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		Window subActivity = super.getLocalActivityManager().startActivity(
				"subActivity", this.intent);
		this.content.addView(subActivity.getDecorView(),
				LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
	}

	private void exitDialog() {
		Dialog dialog = new AlertDialog.Builder(this).setIcon(R.drawable.pic_m)
				.setTitle("程序退出? ").setMessage("您确定要退出本程序吗?")
				.setPositiveButton("确定", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						PopMenuActivity.this.finish() ;
					}
				})
				.setNegativeButton("取消", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						PopMenuActivity.this.switchActivity(0);
					}
				}).create();

		dialog.show();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_BACK) {
			this.exitDialog() ;
		}
		return false ;
	}

	private void showPopupMenu() {
		if (this.isShow) { // 已经显示了
			this.popMenu.dismiss();
			this.isShow = false;
		} else {
			this.popMenu.showAtLocation(
					PopMenuActivity.this.gridviewToolbar, Gravity.BOTTOM,
					0, this.height);
			this.isShow = true;
		}
	}

	private class PopupBodyOnItemClickListenerCallback implements
			OnItemClickListener {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			PopMenuActivity.this.popMenu.setPopBodySelected(position, Color.GRAY) ;
			Toast.makeText(PopMenuActivity.this, "执行选项 - " + position, Toast.LENGTH_SHORT).show() ;
		}
	}
	private class PopupTitleOnItemClickListenerCallback implements OnItemClickListener {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			PopMenuActivity.this.popMenu.setPopTitleSelected(position) ;
			switch(position) {
			case 0:
				PopMenuActivity.this.popMenu
						.setPopupMenuBodyAdapter(PopMenuActivity.this.commonAdapter);
				break;
			case 1:
				PopMenuActivity.this.popMenu
						.setPopupMenuBodyAdapter(PopMenuActivity.this.setAdapter);
				break;
			case 2:
				PopMenuActivity.this.popMenu
						.setPopupMenuBodyAdapter(PopMenuActivity.this.toolAdapter);
				break;
			}
		}}
}

到这里就大功告成了,下面是效果图

这些图片是我从教程里拿的,下面看看弹出菜单的效果。




    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
建站其它 iis7站长之家
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3