首页 > 编程技术 > android

Android开发时无法正确按照响应样式显示解决办法

发布时间:2016-9-20 19:59

可能不秒用户会发现用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--]

您可能感兴趣的文章: