可能不秒用户会发现用css定义好的内容在手机中显示不那么标准了,下面小编来给大家介绍移动web开发无法正确按照响应样式显示解决办法。
记最近在做移动混合应用的开发,遇到的一个问题:android无法按照指定的响应样式正确显示。
首先说一下两次遇到此问题的环境:
1.使用jQuery Mobile写界面时,在测试机上(G7)字体和界面显示偏小。
2.在G7上使用自定义的响应样式进行布局时没有问题,界面显示正常。但在小米2S上,界面却显示错误。通过JS脚本获取了一下小米2S的屏幕宽度,发现获得的值并不是想像的720px,而是360px,所以响应的样式会发生错误。
在没有设置target-densitydpi时
在设置target-densitydpi时,得到正确的响应布局
原来在android上,会通过 target-densitydpi 来获取DPI。在不设置的情况下,默认选择的是 medium-dpi(160)。
上面的两个问题,可以通过给元标签添加target-densitydpi=device-dpi
来解决,代码如下。
代码如下 |
复制代码 |
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
本文章来给各位同学介绍一下Android开发之ImageView通过matrix实现手势缩放操作方法,我们知道安卓中ImageView本身有scaleType属性,通过设置android:scaleType=matrix 可以用很少的代码就实现缩放功能了,下面我们来看看。
关于ImageView的手势缩放,有很多种方法,绝大多数开源自定义缩放都是修改了ondraw函数来实现的。但是ImageView本身有scaleType属性,通过设置android:scaleType="matrix" 可以用很少的代码就实现缩放功能。缩放的优点是实现起来简单,同时因为没有反复调用ondraw函数,缩放过程中不会有闪烁现象。
MATRIX矩阵可以动态缩小放大图片来显示,缩小图片:
代码如下 |
复制代码 |
//获得Bitmap的高和宽
int bmpWidth=bmp.getWidth();
int bmpHeight=bmp.getHeight();
//设置缩小比例
double scale=0.8;
//计算出这次要缩小的比例
scaleWidth=(float)(scaleWidth*scale);
scaleHeight=(float)(scaleHeight*scale);
//产生resize后的Bitmap对象
Matrix matrix=new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizeBmp=Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, true);
|
下面将一个自定义的实现了手势缩放的ImageView代码拷贝如下:
代码如下 |
复制代码 |
package com.jcodecraeer.stargallerry;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.widget.ImageView;
public class ImageTouchView extends ImageView {
private PointF startPoint = new PointF();
private Matrix matrix = new Matrix();
private Matrix currentMaritx = new Matrix();
private int mode = 0;//用于标记模式
private static final int DRAG = 1;//拖动
private static final int ZOOM = 2;//放大
private float startDis = 0;
private PointF midPoint;//中心点
/**
* 默认构造函数
* @param context
*/
public ImageTouchView(Context context){
super(context);
}
/**
* 该构造方法在静态引入XML文件中是必须的
* @param context
* @param paramAttributeSet
*/
public ImageTouchView(Context context,AttributeSet paramAttributeSet){
super(context,paramAttributeSet);
}
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = DRAG;
currentMaritx.set(this.getImageMatrix());//记录ImageView当期的移动位置
startPoint.set(event.getX(),event.getY());//开始点
break;
case MotionEvent.ACTION_MOVE://移动事件
if (mode == DRAG) {//图片拖动事件
float dx = event.getX() - startPoint.x;//x轴移动距离
float dy = event.getY() - startPoint.y;
matrix.set(currentMaritx);//在当前的位置基础上移动
matrix.postTranslate(dx, dy);
} else if(mode == ZOOM){//图片放大事件
float endDis = distance(event);//结束距离
if(endDis > 10f){
float scale = endDis / startDis;//放大倍数
//Log.v("scale=", String.valueOf(scale));
matrix.set(currentMaritx);
matrix.postScale(scale, scale, midPoint.x, midPoint.y);
}
}
break;
case MotionEvent.ACTION_UP:
mode = 0;
break;
//有手指离开屏幕,但屏幕还有触点(手指)
case MotionEvent.ACTION_POINTER_UP:
mode = 0;
break;
//当屏幕上已经有触点(手指),再有一个手指压下屏幕
case MotionEvent.ACTION_POINTER_DOWN:
mode = ZOOM;
startDis = distance(event);
if(startDis > 10f){//避免手指上有两个茧
midPoint = mid(event);
currentMaritx.set(this.getImageMatrix());//记录当前的缩放倍数
}
break;
}
this.setImageMatrix(matrix);
return true;
}
/**
* 两点之间的距离
* @param event
* @return
*/
private static float distance(MotionEvent event){
//两根线的距离
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
return FloatMath.sqrt(dx*dx + dy*dy);
}
/**
* 计算两点之间中心点的距离
* @param event
* @return
*/
private static PointF mid(MotionEvent event){
float midx = event.getX(1) + event.getX(0);
float midy = event.getY(1) - event.getY(0);
return new PointF(midx/2, midy/2);
}
}
在xml中这样使用自定义的ImageView:
<com.jcodecraeer.stargallerry.ImageTouchView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"
/>
|
这里有个小细节, android:layout_width和android:layout_height这里都是="match_parent" ,如果我们换成wrap_content的话,你会发现图片只能在一个很小的区间缩放。而match_parent则可以很随意的在整个屏幕缩放。
但是match_parent导致了一个让人意外的问题:
如果将imageView的宽度和高度都设置为填充整个父控件,然后scaleType设置成Matrix,则图片不是居中显示的,整个图片靠上去了,这里我还没有找出原因,不过在网上找出了解决的办法:
“
先设置ImageView的ScaleType="CENTER"
要给控件添加拖动与放大缩水前。再把ScaleType设为:"Matric"
(即ImageView设置OnTouchListener前更改属性即可)
”
其中“ImageView设置OnTouchListener前更改属性”在我们这个例子中应替换为在caseMotionEvent.ACTION_MOVE://移动事件开始更改属性。在代码中更改ScaleType应该这样做:
this.setScaleType(ImageView.ScaleType.MATRIX);
说到ScaleType,我们看看ImageView.ScaleType 值的意义和区别:
CENTER /center 按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示
CENTER_CROP / centerCrop 按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽)
CENTER_INSIDE / centerInside 将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽
FIT_CENTER / fitCenter 把图片按比例扩大/缩小到View的宽度,居中显示
FIT_END / fitEnd 把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置
FIT_START / fitStart 把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置
FIT_XY / fitXY 把图片不按比例扩大/缩小到View的大小显示
MATRIX / matrix 用矩阵来绘制
本文章来给各位同学详细的介绍一下关于Android Ant命令行编译和APK签名详解一些实现方法,这是一个朋友在自己做安卓开发时写的,希望对大家会有所帮助呀。
最近在做Android开发时,需要引用第三方的代码进项目,一般情况下,直接在Eclipse下设置需要导入的代码的编译输出为library即可,但是很多代码在Eclipse下编译会出现很多莫名其妙的错误。因而只能使用命令行方式对代码进行编译。具体方法如下:
1.安装编译用的Java,安装Android Platform-tools,安装Ant,设置好各种环境变量。部分Linux下Ant已经默认集成,Windows下需要自行安装。
2.使用Android工具更新代码的编译配置。
3.使用Ant工具进行编译,可编译Debug版和Release版本。
4.生成代码签名用的私钥,并对APK进行签名。
5.对APK文件进行对齐,对大文件APK有不错的效果。
以下是参考Bash代码,可自己需要更改,执行时,sudo bash XXX.sh即可
代码如下 |
复制代码 |
# Setup Java Home
JAVA_HOME = "/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"
# Setup android Home
ANDROID_HOME="~/android-sdk-macosx"
# Setup path
PATH = "$ANDROID_HOME/tools:$JAVA_HOME/bin:$PATH"
# Update current project
android update project --path .
#android update project --path ./Library/lib1
#android update project --path ./Library/lib2
# Remove keystore
rm -f product.keystore
# Make keystone
keytool -genkey -alias product.keystore -keyalg RSA -validity 40000
-keystore product.keystore -storepass password -keypass password
-dname "CN=Product OU=Android Team O=Organization L=Hongkong ST=Hongkong C=China"
# Clean
ant clean
# Remove ant.properties
rm -f ant.properties
# Make ant.properties
echo "key.store=product.keystore" > ant.properties
echo "key.alias=product.keystore" >> ant.properties
# Build apk
ant release
# Sign APK
# jarsigner -verbose -keystore product.keystore -signedjar
# bin/product_signed.apk bin/product-release-unsigned.apk product.keystore
# Zip align apk
# zipalign -v 4 bin/product_signed.apk bin/product_final.apk
|
说明:
更新Android的ant编译配置,如果代码的结构发生变更,请执行,如果代码中包含引用的第三方库代码,需要分别对这些代码进行更新。
代码如下 |
复制代码 |
# Update current project
android update project --path .
#android update project --path ./Library/lib1
#android update project --path ./Library/lib2
|
生成签名用的Keystore文件,几个参数的说明
-genkey 生成秘钥证书
-alias 别名
-keyalg 秘钥的计算算法
-validity 有效期
-keystore 秘钥库文件路径
-storepass 秘钥库密码
-keypass 秘钥证书密码
-dname 发行者信息
CN= 发行者姓名 (个人姓名或产品名)
OU= 组织单元名 (团队名)
O= 组织机构名 (公司名)
L= 城市/地区
ST= 州/省
C= 国家代码
代码如下 |
复制代码 |
# Make keystone
keytool -genkey -alias product.keystore -keyalg RSA -validity 40000
-keystore product.keystore -storepass password -keypass password
-dname "CN=Product OU=Android Team O=Organization L=Hongkong ST=Hongkong C=cn"
|
生成ant自动编译用的ant.properties文件,设置key.store和key.alias两个变量后,ant release时会自动对生成的APK签名和对齐
代码如下 |
复制代码 |
echo "key.store=product.keystore" > ant.properties
echo "key.alias=product.keystore" >> ant.properties
|
手动对代码签名,几个参数的说明
-verbose 显示输出
-keystore keystore别名
-signedjar 签名apk文件,第一个参数为目标文件,第二个为未签名apk
代码如下 |
复制代码 |
# Sign APK
jarsigner -verbose -keystore product.keystore -signedjar bin/product_signed.apk bin/product-release-unsigned.apk product.keystore
|
手动对APK进行对齐
代码如下 |
复制代码 |
# Zip align apk
zipalign -v 4 bin/product_signed.apk bin/product_final.apk
|
网上找到听说Eclipse下Android插件报错Debug certificate expired是因为,Debug证书的有效期限是365天,那么不可避免的就会有证书过期的问题了。而Android SDK又比较呆板,发现证书过期了,不会给你换新的,只会给你Error提示。
前几天用Eclipse写程序的试试,突然就不能运行了,报了个奇怪的错误。
[2010-02-03 10:31:14 - androidVNC]Error generating final archive:
Debug certificate expired on 1/30/10 2:35 PM!
解决的办法比较简单:
将debug.keystore直接删除。Android SDK发现debug.keystore丢失了,就会自个生成一个新的。再运行SDK
不同系统位置不同
删除Android的debug certificate即可。
Linux/Mac OS : ~/.android/debug.keystore
Windows: %USERPROFILE%/.android
本文章来给大家介绍在android开发中我们要对EditText限制,只能让用户输入像数字 字母 邮箱地址,电话号之类的,其它的不能输入。
下面以数字、电话为例讲述EditText怎么设置输入类型,其他类型可以参考InputType类。
1) 只能输入数字
代码如下 |
复制代码 |
EditText et = (EditText) findViewById(R.id.etTest);
et.setInputType(InputType.TYPE_CLASS_NUMBER);
|
2) 只能输入电话号码
代码如下 |
复制代码 |
EditText et = (EditText) findViewById(R.id.etTest);
et.setInputType(InputType.TYPE_CLASS_PHONE);//电话
|
3) 邮箱地址
代码如下 |
复制代码 |
EditText et = (EditText) findViewById(R.id.etTest);
et.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
4) 禁止输入任何文本
代码如下 |
复制代码 |
EditText et = (EditText) findViewById(R.id.etTest);
et.setInputType(InputType.TYPE_NULL);
|
// 禁止输入(不弹出输入法)上述也是隐藏输入法的一种方式,还有另外一种隐藏办法,
可查看android隐藏IME(输入法)输入框
不让程序默认升起IME输入框有两种方法:
1.让EditText失去焦点,使用EditText的clearFocus方法
2.强制隐藏Android输入法窗口,在IME类中我们通过实例化输入法控制对象,通过hideSoftInputFromWindow来隐藏IME输入框。
代码
代码如下 |
复制代码 |
Toast.makeText(WindowBackgroundColorActivity.this, "焦点改变", Toast.LENGTH_SHORT).show();
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
//第一种方法
//imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_NOT_ALWAYS);
//第二种方法
imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); |
参考代码:
代码如下 |
复制代码 |
<EditText android:id="@+id/etTest" android:inputType="number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
|
标签:[!--infotagslink--]