文档章节

android底层实现鼠标状态的图标

blackylin
 blackylin
发布于 2012/08/09 11:09
字数 1982
阅读 1205
收藏 0

今天这里贴出从应用层传出一个id或图片byte[]数组,通过aidl与service交互调用JNI,最后到Cursor.c实现画不同状态的光标。下面就给出Cursor.c的实现画图,前面的过程就不全给出了:

Cursor.c

#include <stdio.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <linux/fb.h>
#include <hifb.h>

#include <cutils/ashmem.h>
#include <cutils/log.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include "hardware_legacy/cursor.h"

#define LOG_TAG "CursorHW"

typedef struct{
	int id;
	int width;
	int height;
	char *buf;
}CURSOR_BITMPA_S;

static CURSOR_BITMPA_S g_cursor_data[ID_MAX_BITMAP_NO];

static char g_cursor_name[ID_MAX_BITMAP_NO][32] = {
	"cursor_normal.bmp",
	"cursor_help.bmp",
	"cursor_bg.bmp",
	"cursor_busy.bmp",
	"cursor_accpos.bmp",
	"cursor_edit.bmp",
	"cursor_wait.bmp",
	"cursor_handwrite.bmp",
	"cursor_link.bmp",
	"cursor_disable.bmp",
};

static int s_cursorfd = -1;

//光标的绝对位置
static int s_cursor_x = 0;
static int s_cursor_y = 0;
static int s_screen_width = 0;

static int  s_memp_size = 0;
static char *s_memp_start = NULL;

#define CHECK_FD() do { if (s_cursorfd < 0) return -1; } while(0) 

#define HI_CURSOR_W  	32
#define HI_CURSOR_H  	32
#define HI_CURSOR_BPP 	32
#define HI_CURSOR_STRIDE (HI_CURSOR_BPP*HI_CURSOR_W/8)

static char s_Cursordata[12*20*4] = 
{
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, \
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, \
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \
};

static int cursor_load_bitmap(int id);
static int cursor_unload_bitmap();

int cursor_open()
{
    int size = 0;
    int i;
    HIFB_ALPHA_S as;
    struct fb_fix_screeninfo finfo;
    struct fb_var_screeninfo info;

    /*我们让光标显示在高清图层,为了DDMS截图正确*/
    int fd = open("/dev/graphics/fb2", O_RDWR, 0);
    if(fd > 0)
    {
        LOGI("open fb0 ok. fd=%d\n", fd);
    }
    else
    {
        LOGE("open fb error:\n");
        return 1;
    }
    
    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
    {
        LOGE("info error.\n");
        goto quit;
    }

    //设置光标大小,像素格式
    info.xres = info.xres_virtual = 12;
    info.yres = info.yres_virtual = 20;
    info.bits_per_pixel = HI_CURSOR_BPP;

    info.transp.length = 8;
    info.transp.msb_right = 0;
    info.transp.offset = 24;

    info.red.length = 8;
    info.red.msb_right = 0;
    info.red.offset = 16;

    info.green.length = 8;
    info.green.msb_right = 0;
    info.green.offset = 8;

    info.blue.length = 8;
    info.blue.msb_right = 0;
    info.blue.offset = 0;
	
    if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
    {
        LOGE("info error.\n");
        goto quit;
    }

    if (ioctl(fd, FBIOGET_ALPHA_HIFB, &as) < 0)
    {
        LOGE("get alpha error.\n");
        goto quit;
    }

    as.bAlphaEnable = HI_TRUE;
    if (ioctl(fd, FBIOPUT_ALPHA_HIFB, &as) < 0)
    {
        LOGE("get alpha error.\n");
        goto quit;
    }

    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
    {
        LOGE("finfo error.\n");
        goto quit;
    }
	
    //size = info.xres * info.yres * info.bits_per_pixel/8;  //----->12*20*32/8=960
    size = finfo.smem_len;
	LOGI("*******size = %d*******", size);
    s_memp_start = (char*)mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if((char*)-1 == s_memp_start)
    {
        LOGE("mmap error:\n");
        goto quit;
    }

    s_memp_size = size;
    s_cursorfd = fd;
    s_screen_width = finfo.line_length;
	
    //copy 光标位图到framebuffer上
    cursor_set_visible(0);

    memset(s_memp_start, 0x0, size);
    
    for (i= 0; i<20; i++)
	{
	   memcpy(s_memp_start + i*s_screen_width, s_Cursordata + 48*i, 48);
	}
	
    cursor_set_visible(1);
	
    return 0;
  
quit:
    cursor_close();
    return -1;    
}

int cursor_close()
{
   if (s_cursorfd > 0)
   {
   	  close(s_cursorfd);
	  s_cursorfd = -1;
   }
   
   cursor_unload_bitmap();
   
   return 0;
}

int cursor_set_visible(int flag)
{
	CHECK_FD();
	
    //需要考虑范围不要超过屏幕 todo
	
    if (ioctl(s_cursorfd, FBIOPUT_SHOW_HIFB, &flag) < 0)
    {
       LOGE("failed to %s cursor! \n", flag ? "show":"hide");
    }

   return 0;     
}

int cursor_set_sharp(const char *buf,int w,int h)
{
	int i=0;
    int width=w,height=h;
    char *buffer = (char*)buf;
    char *start = s_memp_start;

    if(width > HI_CURSOR_W)
        width = HI_CURSOR_W;

    if(height > HI_CURSOR_H)
        height = HI_CURSOR_H;

	LOGI("width=%d,height=%d",width,height);

	/* 1、先将光标隐藏掉 */
    cursor_set_visible(0);

    /* 2、将光标数据定入到fb中进行显示(操作共享区) */
	
    memset(s_memp_start, 0x00, s_memp_size);
    for (i=0; i<HI_CURSOR_H; i++)
	{
	   memcpy(s_memp_start + i*s_screen_width, buf + HI_CURSOR_STRIDE*i, HI_CURSOR_STRIDE);
	}
	
    /* 3、将光标重新显示 */
    cursor_set_visible(1);
    
    return 0;
}

int cursor_set_sharpID(const int id)
{
	int ret = -1;

	LOGI("cursor_set_sharpID:cursor_set_sharpID param: id=%d",id);

	if(id < 0 || id > ID_DISABLE_BITMAP){
		LOGE("cursor_set_sharpID error param: id=%d",id);
		return -1;
	}
	
	ret = cursor_load_bitmap(id);
	if(ret < 0){
		LOGE("cursor_load_bitmap load bitmap failed(id = %d)",id);
		return -1;
	}

	ret = cursor_set_sharp(g_cursor_data[id].buf,g_cursor_data[id].width,g_cursor_data[id].height);
	if(ret < 0){
		LOGE("cursor_set_sharpID set sharp failed");
		return -1;
	}
	
	return ret;
}

static int cursor_bitmpa_format_convert(CURSOR_BITMPA_S *cs,char *src){
	int i ,j ;
	int width = cs->width,height = cs->height;
	char *psrc = src ;
	char *pdst = cs->buf;
	char *p = psrc;
	int value = 0x00;

	/* 由于bmp存储是从后面往前面,所以需要倒序进行转换 */
	pdst += (width * height * 4);
	for(i=0;i<height;i++){
		p = psrc + (i+1) * width * 3;
		for(j=0;j<width;j++){
			pdst -= 4;
			p -= 3;
			pdst[0] = p[0];
			pdst[1] = p[1];
			pdst[2] = p[2];
			//pdst[3] = 0x00;

			value = *((int*)pdst);
			value = pdst[0];
			if(value == 0x00){
				pdst[3] = 0x00;
			}else{
				pdst[3] = 0xff;
			}
		}
	}

	return 0;
}



static int cursor_load_util_read(FILE *fp,char *buf,int len){
	int ret;
	if (len <= 0)
		return len;

	while ((ret = fread(buf,1,len,fp)) >= 0) {
		if (ret == 0) {
			cursor_sleep_millis(1);
			continue;
		}
		if ((len -= ret) == 0)
			return 0;
		buf = ((char*) buf) + ret;
	}
	return -1;
}

static int cursor_load_bitmap(int id){
	int ret = -1;
	char *cursor_path = "/system/usr/cursor";
	char file_path[128];
	FILE *fp = NULL;
	char bmp_header[54];
	int  flen , total_length = 0;
	char *bmp_buf = NULL;
	int n = 0;

	if(g_cursor_data[id].buf != NULL){
		LOGV("cursor_load_bitmap already load,success!");
		return 0;
	}

	memset(bmp_header,0x00,sizeof(bmp_header));

	/* 读取位图的前面开始的54字节数据 */
	snprintf(file_path,128,"%s/%s",cursor_path,g_cursor_name[id]);
	LOGI("file path = %s",file_path);

	fp = fopen(file_path,"rb");
	if(fp == NULL){
		LOGE("load > cursor file open failed");
		return -1;
	}

	/* 求解文件长度 */
	fseek(fp,0,SEEK_SET);
	fseek(fp,0,SEEK_END);
	flen = ftell(fp);

	bmp_buf = (char*)calloc(1,flen - 54);
	if(bmp_buf == NULL){
		LOGE("load > malloc bmp out of memory!");
		goto BAIL;
	}

	/* 再移位到文件头部 */
	fseek(fp,0,SEEK_SET);

	n = fread(bmp_header,1,54,fp);
	if(n != 54){
		LOGE("load > read bmp header failed failed");
		goto BAIL;
	}

	g_cursor_data[id].width  = bmp_header[18];
	g_cursor_data[id].height = bmp_header[22];
	LOGV("cursor_load_bitmap:load > bmp width = %d,heigth = %d",g_cursor_data[id].width,g_cursor_data[id].height);

	/* 24位位图 */
	total_length = g_cursor_data[id].width * g_cursor_data[id].height * 3;
	ret = cursor_load_util_read(fp,bmp_buf,total_length);
	if(ret != 0) {
		LOGE("load > read bmp body data failed");
		goto BAIL;
	}

	/* 32位显示 */
	total_length = g_cursor_data[id].width * g_cursor_data[id].height * 4;
	g_cursor_data[id].buf = (char*)calloc(1,total_length);
	if(g_cursor_data[id].buf == NULL){
		LOGE("load > malloc curosr buf failed");
		goto BAIL;
	}

	ret = cursor_bitmpa_format_convert(&g_cursor_data[id],bmp_buf);
	if(ret < 0){
		LOGE("load > convert bmp to cursor data failed");
		goto BAIL;
	}

	g_cursor_data[id].id = id;

	if(bmp_buf != NULL){
		free(bmp_buf);
		bmp_buf = NULL;
	}

	if(fp != NULL){
		fclose(fp);
		fp = NULL;
	}

	LOGI("cursor_load_bitmap:load > load bitmap success");
	return 0;

BAIL:
	if(bmp_buf != NULL){
		free(bmp_buf);
		bmp_buf = NULL;
	}

	if(fp != NULL){
		fclose(fp);
		fp = NULL;
	}

	LOGE("cursor_load_bitmap load bitmap failed");
	return -1;
}

static int cursor_unload_bitmap(){
	int i = 0,rid = -1;
	
	for(i=0;i<ID_MAX_BITMAP_NO;i++){
		rid = g_cursor_data[i].id;
		if(rid < 0)
			continue;
		
		g_cursor_data[i].id = -1;
		free(g_cursor_data[i].buf);
		g_cursor_data[i].buf = NULL;
	}
	
	return 0;
}

 注:

1.图片为32*32*24的bmp位图,字节长位3126byte,前54byte为头部信息,其中第16-19个和20-23个字节位为长和高

2.因为这里定义的是32位有透明色的位图,所以加载的24位位图需要转换成32位的-- cursor_bitmpa_format_convert这个方法

3.android java层也可以解析位图,然后传byte[]数据下来,cursor里面直接读取位图byte[]数据。android中的解析方法如下:

 

private void loadBmpData(){
		pic_Curs=new Pic_Cur[10];
		String[] cur_name=new String[]{
	    		"cursor_normal.bmp",
	    		"cursor_help.bmp",
	    		"cursor_bg.bmp",
	    		"cursor_busy.bmp",
	    		"cursor_accpos.bmp",
	    		"cursor_edit.bmp",
	    		"cursor_wait.bmp",
	    		"cursor_handwrite.bmp",
	    		"cursor_link.bmp",
	    		"cursor_disable.bmp"
	    };
		for(int i=0;i<pic_Curs.length;i++){
			String cur_path="/res/drawable-mdpi/"+cur_name[i];		
			try {
				InputStream in = getClass().getResourceAsStream(cur_path);
				// 获取文件的字节数
				int length = in.available();
				//System.out.println(length+"--bmp--"+i);
				// 创建byte数组
				byte[] buffer = new byte[length];
				// 将文件中的数据读到byte数组中
				in.read(buffer);
				pic_Curs[i]=new Pic_Cur();//初始化对象
				//在前54个字节中第16-19个和第20-23个字节表示长和宽
				int width=buffer[18];
				pic_Curs[i].setWidth(width);
				int height=buffer[22];
				pic_Curs[i].setHeight(height);
				//System.out.println("width is:"+pic_Curs[i].getWidth()+"height is:"+pic_Curs[i].getHeight());
				//buffer第54个后的为图像数据
				byte[] by1=Arrays.copyOfRange(buffer, 54, buffer.length);
				
				//24位图转32位,由于bmp存储是从后面往前面,所以需要倒序进行转换
				byte[] by2=new byte[width*height*4];
				for(int j=0;j<height;j++){
					for(int k=0;k<width;k++){
						by2[(height-j-1)*width*4+4*k]=by1[(j*width*3+3*k)];
						by2[(height-j-1)*width*4+4*k+1]=by1[(j*width*3+3*k+1)];
						by2[(height-j-1)*width*4+4*k+2]=by1[(j*width*3+3*k+2)];
						if(by2[(height-j-1)*width*4+4*k]==(byte) 0x00 &&
								by2[(height-j-1)*width*4+4*k+1]==(byte) 0x00 &&
								by2[(height-j-1)*width*4+4*k+2]==(byte) 0x00){
							by2[(height-j-1)*width*4+4*k+3]=(byte) 0x00;
						}else{
							by2[(height-j-1)*width*4+4*k+3]=(byte) 0xff;
						}
					}
				}			
				//System.out.println("data length is:"+by1.length+"buf length is:"+by2.length);
				
				pic_Curs[i].setCur_data(by2);
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		
	}

 中间省略aidl与service的交互、jni调用等;之后会在cursor.c里的

int cursor_set_sharp(const char *buf,int w,int h)

 把光标显示出来

注:bmp位图可以参考后面的一篇文章:bmp位图分析

……O(∩_∩)O~

© 著作权归作者所有

blackylin
粉丝 48
博文 46
码字总数 27849
作品 0
深圳
Android工程师
私信 提问
请教android开发的问题

最近我想实现悬浮图标点击返回主程序的功能。 具体的实现方法是在主程序中的Switch被开启的时候 开启一个Service,通过Service建立一个float窗口,这个窗口我就用一个小图片显示,这样就做成...

Bllose
2014/03/10
204
4
requestWindowFeature(featrueId)简述

我们在开发程序是经常会需要软件全屏显示、自定义标题(使用按钮等控件)和其他的需求,今天这一讲就是如何控制Android应用程序的窗体显示.   首先介绍一个重要方法那就是requestWindowFe...

聂磊
2013/05/26
87
0
Android电池电量监控初步

引言 ,学习了包括Activity、Service、AppWidget、Broadcast、Intent、Notification、XML布局、XML配置等基础知识之后,尝试着做一个小玩意儿——电池监控,期间也是阻挠多多,现在基本完成了...

鉴客
2012/01/29
3.7K
1
Android实现不重复启动APP的方法

类似QQ、微信这样的APP,一般都不会打开两个实例。   比如:打开QQ客户端,进入到好友聊天界面,然后按HOME返回桌面 这时候有两种情况:   1、如果你在最近任务中切换会QQ客户端,那么还...

莫铭
2015/11/14
1K
1
动态显示和隐藏状态栏(包括底部虚拟按键)

小米Launcher有一个细节上的功能效果:在长按桌面应用图标时,会隐藏状态栏,然后在状态栏原有的布局上显示卸载或删除的操作栏。放手后,操作栏隐藏,状态栏显示出来。也就是说,这个过程是涉...

不正经啊不正经
2015/07/29
4.9K
1

没有更多内容

加载失败,请刷新页面

加载更多

vue入门--简单路由配置

本文转载于:专业的前端网站➜vue入门--简单路由配置   在初始化vue init webpack <工程名>时,有一步是询问是否安装vue-router,选择yes,如果没有安装的话,后面需要自己安装。然后在目录...

前端老手
13分钟前
2
0
怎么给视频配音

很多刚开始尝试视频制作的小伙伴,帮助到怎么给制作完成的视频配音,其实给视频配音的方法非常简单,在手机上可以进行制作,下面一起来看看给视频配音的方法吧! 具体步骤如下: 1、首先在手...

白米稀饭2019
22分钟前
1
0
windows批处理bat脚本编写

什么是bat脚本 .bat结尾的文件其实就是windows上的批处理脚本,Windows中的bat文件相当于 Linux中shell编程的.sh脚本,批量执行DOS命令。 其最简单的例子,是逐行书写在命令行中会用到的各种...

孙幼凌
30分钟前
1
0
华为手机翻译功能怎么使用?这三种方法请务必收藏

华为手机翻译功能怎么使用?在我们的生活中会经常遇到翻译问题,许多外语不好的朋友该怎么办呢?华为手机已经为我们解决了这个问题,今天小编就教大家学会使用华为手机中的三种翻译技巧,需要...

翻译小天才
38分钟前
4
0
企业服务软件开发中需要注意的三个问题

在开发企业服务软件时,我们需要分为:业务需求、用户需求、产品需求,三大需求层次,三个层次互相关联,企业服务软件开发首先要服务业务,需要满足业务的需求,再关注用户体验,也就是用户需...

积木创意科技
40分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部