关于Android UI 使用更快更高效方法
一、选择恰当的图像尺寸
视图背景图总是会填充整个视图区域,图像尺寸的不适合会导致图像的自动缩放,为了避免这种情况,我们可以先将图片进行缩放到视图的大小。
代码如下 | 复制代码 |
originalImage = Bitmap.createScaledBitmap( |
二、去掉不需要的默认窗口背景
在默认情况下,窗口有一个不透明的背景,有时候我们并不需要他,就可以去掉他。因为更新看不见的窗口是浪费时间的。
去掉的方法:
1.代码实现:
代码如下 | 复制代码 |
@Override |
2.xml里实现:
首先去顶你的res/xml/styles.xml里有
代码如下 | 复制代码 |
<resources> <activity android:name="MyActivity" android:theme="@style/NoBackGroundTheme"> |
三、尽可能的使用简单的布局和视图
如果一个窗口包含很多的视图,那么启动时间长、测量时间长、绘制时间长、布局时间长;
如果视图树深度太深,会导致StackOverflowException异常,和用户界面反映会很慢很慢。
解决的方法:
1.使用TextView的复合drawables,减少层次
如有这样的布局:
代码如下 | 复制代码 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
我们可以这样来取代他,从而来将少层次:
代码如下 | 复制代码 |
<TextView android:layout_width="fill_parent" |
2.使用ViewStub延迟展开视图
默认情况下,使用ViewStub包含的视图是不可见的。
代码如下 | 复制代码 |
<ViewStub android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/vs" android:layout="@layout/main"/> |
这个里面包含的main视图是不会展现出来的,如果需要展现出来需要代码的处理
代码如下 | 复制代码 |
findViewById(R.id.vs).setVisibility(View.VISIBLE); findViewById(R.id.vs).inflate(); |
3.使用<merge>合并视图
默认情况下,布局文件的根作为一个借点加入到父视图中,如果使用<merge>可以避免根节点。
如果最外层的布局是FrameLayout,那么可以使用merge替换掉,引用官方说明:
Obviously, using <merge /> works in this case because the parent of an activity's content view is always a FrameLayout. You could not apply this trick if your layout was using a LinearLayout as its root tag for instance.
代码如下 | 复制代码 |
<merge |
4.使用RelativeLayout减少层次
5.自定义布局
本文章简单的android游戏开发实例教程,有需要学习手机游戏开发的朋友可以参考一下下哈。地图我们创建好了接下来就是主角的出现。其实上文介绍了如何TiledMap和Stage的结合,角色的处理就简单了。
可以继承Actor类创建主角类,我就偷个懒,用Image代替。
编辑我们的TMX文件,添加一个对象层。
在主角要出现的地方加个形状
取名为play1
我们的主角是:
思路是我们遍历map中的所有Object,如果名字和我们设定的play1一致,那么就实例化一个Image,位置和Object一致,添加到舞台。
关键代码:
代码如下 | 复制代码 |
for (TiledObjectGroup group : map.objectGroups) { |
效果如下:
然后现在来试试让主角动起来。
首先是我们如何控制,android设备的话优先选用触控。如果我们按住前方不放,主角向前。按住上方不放,主角向上。
那么如何确定我们按住的是哪个方向呢?
如图所示,黄色的是Stage,粉红的边框是整个Map,有部分显示,有一部分没有显示。右下角的绿色点是主角的位置,我们假定红色的点是我们的触碰点。
认定红色的触碰点为向前,我在提供一个方案,但是方法不唯一哈,我这样确定方向也不一定是最符合用户体验的。
以主角的位置为原点重现建立坐标系,得到触碰点的新坐标x,y.
确定了在新坐标系下的触碰点的象限,在判断x,y的大小就可以知道方向了。
代码如下:
代码如下 | 复制代码 |
Vector3 tmp = new Vector3(x, y, 0); stage.getCamera().unproject(tmp); float newx = tmp.x - player.x; float newy = tmp.y - player.y; if (newx > 0 && newy > 0) { if (newx > newy) { ChangeDirect(4); } else { ChangeDirect(1); } } else if (newx > 0 && newy < 0) { if (newx > -newy) { ChangeDirect(4); } else { ChangeDirect(2); } } else if (newx < 0 && newy > 0) { if (-newx > newy) { ChangeDirect(3); } else { ChangeDirect(1); } } else { if (-newx > -newy) { ChangeDirect(3); } else { ChangeDirect(2); } } |
直接移动Camera位置可以移动地图,但是我们的主角却从地图上消失了…处理办法是将你希望仍然显示在地图上的Actor的坐标随着Camera一起移动。
代码如下:
代码如下 | 复制代码 |
private void CameraMove(Vector3 vector3) { |
完整代码:
代码如下 | 复制代码 |
package com.cnblogs.htynkn.game; import com.badlogic.gdx.ApplicationListener; public class firstGame implements ApplicationListener, InputProcessor { Stage stage; // Image image; @Override width = Gdx.graphics.getWidth(); for (TiledObjectGroup group : map.objectGroups) { InputMultiplexer inputMultiplexer = new InputMultiplexer(); @Override } @Override } @Override private void CameraMove(Vector3 vector3) { @Override } @Override } @Override @Override @Override @Override private void ChangeDirect(int typeId) { @Override @Override @Override @Override |
那么我们也可以定义自己的ContentProvider来使跨应用共享数据。数据具体的存贮方式可以为数据库、文件,持久化或非持久化存储的其他形式。在这里我们还是使用sqlite数据库存贮数据吧。
老规矩,先来点基础知识。
一.基础知识
1:URI是什么?统一资源标识符,用来标识某一资源的。
通常一个Uri主要由以三部分组成:scheme、Authority、path
1.scheme:ContentProvider(内容提供者)的scheme已经由Android系统规定为:content://
2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作persion表中id为5的记录,可以构建这样的路径:/persion/5
要操作persion表中id为20的记录的name字段, persion/name/10
要操作persion表中的所有记录,可以构建这样的路径:/persion
使用Uri类中的parse()方法获取Uri: Uri uri = Uri.parse("content://com.dongzi/persion")
上面Uri的scheme: content://
Authority: com.dongzi
path: /contact
2、UriMatcher、ContentUrist和ContentResolver
Android系统提供了两个用于操作Uri的工具类:UriMatcher 和ContentUris
UriMatcher:用于匹配Uri:
代码如下 | 复制代码 |
static final int CODES=2; static final int CODE=1; static final String AUTHORITY="com.dongzi"; //授权 static final UriMatcher uriMatcher; //Uri匹配 static { //注册匹配的Uri以及返回码 uriMatcher=new UriMatcher(UriMatcher.NO_MATCH); //不匹配任何路径返回-1 uriMatcher.addURI(AUTHORITY, "persion", CODES); //匹配content://com.dongzi/persion 返回2 uriMatcher.addURI(AUTHORITY, "persion/#", CODE); //匹配content://com.dongzi/persion/1234 返回1 } |
ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
• withAppendedId(uri, id)用于为路径加上ID部分
• parseId(uri)方法用于从路径中获取ID部分
代码如下 | 复制代码 |
//为Uri添加ID Uri uri=Uri.parse("content://"+AUTHORITY+"/persion"); ContentUris.withAppendedId(uri, 1234); //生成后的Uri为:content://com.dongzi/person/1234 //获取Uri后面的ID long id=ContentUris.parseId(Uri.parse("content://com.dongzi/person/1234")); //得到ID为:1234 |
ContentResolver提供了如下主要方法:
代码如下 | 复制代码 |
@Override |
这里主要说下Url所代表数据的MIME类型:
如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,
例如:要得到所有person记录的Uri为content://com.dongzi/person,那么返回的MIME类型字符串应该为:"vnd.android.cursor.dir/person"。
如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,
例如:得到id为1234的person记录,Uri为content://com.dongzi/person/1234,那么返回的MIME类型字符串为:"vnd.android.cursor.item/person"。
使用ContentResolver操作ContentProvider中的数据
当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查 询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。ContentResolver提供了ContentProvider对应的增、删、改、查方法。
监听ContentProvider中数据的变化
如果我们需要得到数据变化通知,可以使用ContentObserver对数据(数据采用uri描述)进行通知更改以及监听。
代码如下 | 复制代码 |
//通知内容以及发生改变,同时注册了内容监听,监听到内容变化,就调用onChange方法 |
二.实战
说了那么多,是时候了解ContentProvider的使用了,我们这里采用sqlite存贮数据。当然,我们直接采用联系人数据不是更好?
1:首先我们定义DBHelper继承SQLiteOpenHelper,并建表。
代码如下 | 复制代码 |
package com.dongzi; import android.content.Context; public class DBHelper extends SQLiteOpenHelper { static final String DB_NAME = "dongzi.db"; } @Override @Override } |
2:然后定义MyContentProvider继承ContentProvider,并且在类加载时候初始化UriMatcher匹配,以及授权AUTHORITY,同时,这个ContentProvider需要在AndroidManifest.xml中进行注册,并添加授权。
代码如下:
代码如下 | 复制代码 |
package com.dongzi; import android.content.ContentProvider; public class MyContentProvider extends ContentProvider { } |
如果我们基本了解了上述说的基础知识,那么这些代码不难看懂,其实也非常简单,不直接操作DBHelper类,而是通过ContentProvider间接操作,而操作ContentProvider又是太通过
ContentResolver这个类,实现不同应用都可以访问这些数据。
解决办法:
1.进入sdk的temp文件夹,下载好后会有一个tools_r15-windows.zip(版本号可能会不一样)
2.解压此文件,如解压成tools_r15-windows
3.进入tools_r15-windows文件夹,将tools_r15-windows里的文件复制
4.覆盖sdk根目录的tools文件夹中的文件
本文章来解决在android2.3.4没有google map的真机上增加google map,有需要的同学可以参考一下。
使用Google Map时需依赖以下:
system/app
Location.apk(2.3.4版本不需要这个了)
NetworkLocation.apk
Maps.apk
Street.apk(2.3.4版本不需要这个了)
system/etc/permissions
com.google.android.maps.xml
system/framework
com.google.android.maps.jar
1、通过工具获得root权限;
2、adb shell su回车 mount -o remount,rw /dev/block/mtdblock3 /system回车
3、adb -d push com.google.android.maps.jar /system/framework/ 或其它手机助手或豌豆夹等工具上传文件
同时还有文件/system/etc/permissions/com.google.android.maps.xml
NetworkLocation.apk放到system/app
4、把真机中/etc/permissions/platform.xml文件取出来编辑:<permissions>
<permissions>
相关文章
php 中file_get_contents超时问题的解决方法
file_get_contents超时我知道最多的原因就是你机器访问远程机器过慢,导致php脚本超时了,但也有其它很多原因,下面我来总结file_get_contents超时问题的解决方法总结。...2016-11-25- php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
- 有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
- 相信很多站长都遇到过这样一个问题,访问页面时出现408错误,下面一聚教程网将为大家介绍408错误出现的原因以及408错误的解决办法。 HTTP 408错误出现原因: HTT...2017-01-22
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。  ...2017-07-06
- ps软件是现在非常受大家喜欢的一款软件,有着非常不错的使用功能。这次文章就给大家介绍下ps把文字背景变透明的操作方法,喜欢的一起来看看。 1、使用Photoshop软件...2017-07-06
intellij idea快速查看当前类中的所有方法(推荐)
这篇文章主要介绍了intellij idea快速查看当前类中的所有方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-09-02- 1.在没有设置默认值的情况下: 复制代码 代码如下:SELECT userinfo.id, user_name, role, adm_regionid, region_name , create_timeFROM userinfoLEFT JOIN region ON userinfo.adm_regionid = region.id 结果:...2014-05-31
js导出table数据到excel即导出为EXCEL文档的方法
复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta ht...2013-10-13- 批量更新mysql更新语句很简单,更新一条数据的某个字段,一般这样写:复制代码 代码如下:UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value';如果更新同一字段为同一个值,mysql也很简单,修改下where即...2013-10-04
- ps软件是一款非常不错的图片处理软件,有着非常不错的使用效果。这次文章要给大家介绍的是ps怎么制作倒影,一起来看看设计倒影的方法。 用ps怎么做倒影最终效果̳...2017-07-06
- 许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
- 本文涉及的主题虽然很基础,在许多人看来属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题。这里会涉及到对象属性的封装、原型、构造函数、闭包以及立即执行表达式等知识。公有方法 公有方法就是能被外部访问...2015-11-08
安卓手机wifi打不开修复教程,安卓手机wifi打不开解决方法
手机wifi打不开?让小编来告诉你如何解决。还不知道的朋友快来看看。 手机wifi是现在生活中最常用的手机功能,但是遇到手机wifi打不开的情况该怎么办呢?如果手机wifi...2016-12-21- 最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误; (1)修改步骤如下,原因如下,原因是apache权限没开, (2)点击打开php.int., 搜索extension=ph...2013-10-04
使用insertAfter()方法在现有元素后添加一个新元素
复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 单个字符分割 string s="abcdeabcdeabcde"; string[] sArray=s.Split('c'); foreach(string i in sArray) Console.WriteLine(i.ToString()); 输出下面的结果: ab de...2020-06-25
jQuery 1.9使用$.support替代$.browser的使用方法
jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31