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; } }} }
到这里就大功告成了,下面是效果图
这些图片是我从教程里拿的,下面看看弹出菜单的效果。
微信SDK中会用到主要类的类图
上面这张类图中显示的是与微信通信过程中的请求类和响应类,第三方应用通过他们
附带的message字段来携带消息传输给微信进程。其中BaseResp有个内部类是ErrCode,
它里面定义了几个常量字段,当我们向微信发送请求后它会作为返回字段
返回到我们的应用中来,我们可以根据这个做相应的处理,在后面的时序图中将会提
到。接下来就是SDK中的message对象了
上面这个类图主要是消息对象,里面有一个字段来引用媒体对象,这些媒体对象就
是我们所能传给微信的对象。有了消息对象和媒体对象,接下来要给出的就是将消
息对象送出去的通信类了。
上面的IWXAPI就是所说的通信类,所有与微信进行通信的工作都是他在做,而他的
生成是由下面的工厂类来完成。旁边的IWXAPIEventHandler接口是需要第三方应用
来实现的,如果我们想处理微信的请求信息或是我们向他发请求后他返回的标识字段。
说明,本文是来自脚本之家,发到这里主要是分享一下,大家一起学习下。1.搭建开发环境
开发环境(主要指linux、虚拟机的安装和交叉编译环境的搭建)完全按照mini6410用户手册4.3节操作,在此不再赘述。
2.根文件系统的目录说明
根文件系统是Linux启动的时候使用的第一个文件系统,没有它系统将无法正常的启动,然而在这个根文件系统中又包含了一系列的目录,接下来对这些目录做一个简单的介绍。
bin 存放所有用户都可以使用的、基本的命令。
sbin 存放的是基本的系统命令,它们用于启动系统、修复系统等。
Usr 里面存放的是共享、只读的程序和数据。
proc 这是个空目录,常作为proc 文件系统的挂载点。
dev 该目录存放设备文件和其它特殊文件。
etc 存放系统配置文件,包括启动文件。
lib 存放共享库和可加载块(即驱动程序),共享库用于启动系统、运行根文件系统中的可执行程序
boot 引导加载程序使用的静态文件。
home 用户主目录,包括供服务账号锁使用的主目录,如FTP。
mnt 用于临时挂接某个文件系统的挂接点,通常是空目录。也可以在里面创建空的子目录。
opt 给主机额外安装软件所摆放的目录。
root root 用户的主目录
tmp 存放临时文件,通常是空目录。
var 存放可变的数据,如日志等。
3 建立根文件系统的目录
进入到自己要放置文件系统的目录,采用《mini2440 Linux移植开发实战指南》,新根文件系统目录的脚本文件create_rootfs_bash,使用命令chmod +x create_rootfs_bash ,改变文件的可执行权限,执行“./create_rootfs_bash ”运行脚本,就完成了根文件系统目录的创建。脚本create_rootfs_bash文件的内容为:
在脚本中改变了tmp 目录的使用权,让它开启sticky 位,为tmp 目录的使用权开启此位,可确保tmp 目录底下建立的文件,只有建立它的用户有权删除。尽管嵌入式系统多半是单用户,不过有些嵌入式应用不一定用root 的权限来执行,因此需要遵照根文件系统权限位的基本规定来设计。
4.建立动态链接库(即lib目录)
动态链接库直接用友善之臂的,先解压友善之臂的根文件包,拷贝lib的内容到新建的根文件目录lib内。
6.交叉编译busybox(即根文件系统内bin,sbin等目录)
Busybox 是一个遵循GPL v2 协议的开源项目,它在编写过程总对文件大小进行优化,并考虑了系统资源有限(比如内存等)的情况,使用Busybox 可以自动生成根文件系统所需的bin、sbin、usr 目录和linuxrc 文件。具体介绍可以参考韦东山完全手册的346页。
(1)、解压busybox
cd /opt/FriendlyARM
tar –zxvf busybox-1.17.2-20101120.tgz
(2)、进入源码,修改Makefile 文件:(这个地方是很重要的一步,必须做,有的教程或者文章参考内核的配置与编译,即在make menuconfig和make后面添加ARCH、CROSS_COMPILE等,而对此不做修改,将可能会导致“request_module: runaway loop modprobe binfmt-464c”等错误出现)
cd /opt/studyarm/busybox-1.17.2
修改:
CROSS_COMPILE ?=arm-linux- //第164 行
ARCH ?=arm //第189 行
(3)、配置busybox
提示:友善之臂已经在光盘中提供了busybox 的源代码包,在光盘\linux 目录中,busybox-1.17.2-20101120.tgz解压后里面包含了友善之臂提供的缺省配置文件:fa_config (输入命令“cp fa.config .config”可以调用该配置),一般用户直接使用缺省文件就可以了,这样生成的busybox 和root_qtopia_qt4 中的是完全一致的。但为了对它的配置了解 更多一些,可以参考 《mini2440 Linux移植开发实战指南》 的如下步骤:
输入 make menuconfig进行配置
下面的配置和busybox1.17.2的配置基本一样,部分地方不太一样。
5.dev设备文件的制作
设备文件较多,而且比较繁杂,因此其制作一般包括两个部分:静态创建设备文件和使用mdev创建设备文件
(1).静态创建设备文件
其实在刚开始制作文件系统的目录里已经静态制作创建了两个必须的设备的设备文件:console和null,内核在引导时这两个设备节点必须存在。
udev:它是个用户程序,能根据系统中硬件设备的状态动态的更新设备文件,包括设备文件的创建、删除等。它的操作相对复杂,但灵活性很高。
mdev是busybox自带的一个简化版的udev,适合于嵌入式的应用埸合。其具有使用简单的特点。它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动 程序所需的节点文件。在以busybox为基础构建嵌入式linux的根文件系统时,使用它是最优的选择。在busybox的配置中,下面的选项将增加对mdev的支持。
在6,7两步的配置结束后,就可以编译并安装busybox。
编译:make ARCH=arm CROSS_COMPILE=arm-linux,其实仅执行make即可,我在这里添加了ARCH和CROSS_COMPILE,其实没什么作用,只是为了保险。因为如果编译的不是ARM版的busybox,系统时无法运行的。
安装:make install CONFIG_PREFIX=/opt/FriendlyARM/mini6410/rootfs/。CONFIG_PREFIX中安装的位置也可以在配置的时候设置,具体位置为:
在第5步中,安装动态链接库后,lib/modules目录下已经有内核模块了,但是这个内核模块和我采用的内核不是一个版本,因此重新编译安装。
进入内核的目录,在编译安装内核模块之前必须保证内核已经正确无误的配置及编译过一次。在这里假设还没有编译过。
(1)我们要使得Linux-2.6.38的缺省目标平台成为ARM 的平台。
修改总目录下的Makefile
原
(2)配置、编译内核模块
在此不具体说明怎么配置,可以将内核里友善自带的配置文件拷贝。然后执行:
a、新建etc/mdev.conf文件,内容为空。
b、拷贝主机etc目录下的passwd、group、shadow文件到rootfs/etc目录下。
c、etc/sysconfig目录下新建文件HOSTNAME,内容写自己喜欢的名字。
d、etc/inittab文件:
9.制作根文件系统镜像
执行以下命令:
这将会在/usr/sbin目录下创建生成相应的工具集
然后执行