android开发之正则表达式

 更新时间:2016年9月20日 20:00  点击:1924
本文章介绍了关于在android手机开发时的一些常用的正则表达式规则与用法,因为android开发和其它程序差不多,当然也需要正则表达式哦。

editText正则表达式的使用 检查输入是否符合规则

 代码如下 复制代码

import Android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

/**

* Class which shows how to validate user input with regular expression

*

* @author FaYnaSoft Labs

*/

public class Main extends Activity {

private EditText editText;

private Button button;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

editText = (EditText) findViewById(R.id.textId);

editText.setText("EditText element");

button = (Button) findViewById(R.id.btnId);

button.setText("Check");

button.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if(checkString(editText.getText().toString())) {

editText.setText("Corect");

}

}

});

}

/**

* This method checks if String is correct

* @param s - String which need to check

* @return value of matching

*/

private boolean checkString(String s) {

return s.matches("\w*[.](Java|cpp|class)");

}

}

 

正则表达式查找字符

 

文章分类:移动开发

String s_Result="Distance: 2.8km (about 9 mins)";

 

//Distance parsing

Pattern p = Pattern.compile("Distance: (\d+(\.\d+)?)(.*?)\b");

Matcher m = p.matcher(s_Result);

if(m.find()){

MatchResult mr=m.toMatchResult();

f_Distance=mr.group(1);//2.8

m_DistanceUnit=mr.group(3);//km

}

 

//Time parsing

p = Pattern.compile("about (\d+(\.\d+)?) (.*)\b");

m = p.matcher(s_Result);

if(m.find()){

MatchResult mr=m.toMatchResult();

f_timeEst=mr.group(1);//9

m_timeEstUnit=mr.group(3);//min

}

或者

String s_Result="Distance: 2.8km (about 9 mins)";

Pattern p = Pattern.compile("(\d+(\.\d+)?) ?(\w+?)\b");

Matcher m = p.matcher(s_Result);

while(m.find()){

MatchResult mr=m.toMatchResult();

String value=mr.group(1);//2.8 and 9 come here

String units=mr.group(3);//km and mins come here

}

 

正则表达式以过滤特殊字符

在网上找了好久也没找到个合适的正则表达式以过滤特殊字符;自己学习了下,写了两个,实现要求。

Java 代码

// 过滤特殊字符 

 代码如下 复制代码

public   static   String StringFilter(String   str)   throws   PatternSyntaxException   {    

// 只允许字母和数字      

// String   regEx  =  "[^a-zA-Z0-9]";                    

// 清除掉所有特殊字符 

String regEx="[`~!@#$%^&*()+=|{}':;',\[\].<>/?~!@#¥%……& amp;*()——+|{}【】‘;:”“’。,、?]"; 

Pattern   p   =   Pattern.compile(regEx);    

Matcher   m   =   p.matcher(str);    

return   m.replaceAll("").trim();    

}    

@Test        

public    void   testStringFilter()   throws   PatternSyntaxException   {    

String   str   =   "*adCVs*34_a _09_b5*[/435^*&城池()^$$&*). {}+.|.)%%*(*.中国}34{45[]12.fd'*&999下面是中文的字符¥……{}【】。,;’“‘”?";    

System.out.println(str);    

System.out.println(StringFilter(str));    

}   

// 过滤特殊字符

 代码如下 复制代码
public static String StringFilter(String str) throws PatternSyntaxException { // 只允许字母和数字 // String regEx = "[^a-zA-Z0-9]"; // 清除掉所有特殊字符 String regEx="[`~!@#$%^&*()+=|{}':;',\[\].<>/?~!@#¥%……&*()——+| {}【】‘;:”“’。,、?]"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(str); return m.replaceAll("").trim(); } @Test public void testStringFilter() throws PatternSyntaxException { String str = "*adCVs*34_a _09_b5*[/435^*&城池()^$$&*).{}+.|.)%%*(*.中国}34{45[]12.fd'*&999 下面是中文的字符¥……{}【】。,;’“‘”?"; System.out.println(str); System.out.println(StringFilter(str)); }

用的是JUnit测试的,当然你可以改成main

 

Java正则表达式学习:

因为正则表达式是一个很庞杂的体系,此例仅举些入门的概念,更多的请参阅相关书籍及自行摸索。

\ 反斜杠

t 间隔 ('u0009')

n 换行 ('u000A')

r 回车 ('u000D')

d 数字 等价于[0-9]

D 非数字 等价于[^0-9]

s 空白符号 [tnx0Bfr]

S 非空白符号 [^tnx0Bfr]

w 单独字符 [a-zA-Z_0-9]

W 非单独字符 [^a-zA-Z_0-9]

f 换页符

e Escape

b 一个单词的边界

B 一个非单词的边界

G 前一个匹配的结束

 

^为限制开头

^java     条件限制为以Java为开头字符

$为限制结尾

java$     条件限制为以java为结尾字符

. 条件限制除n以外任意一个单独字符

java..     条件限制为java后除换行外任意两个字符

 

 

加入特定限制条件「[]」

[a-z]     条件限制在小写a to z范围中一个字符

[A-Z]     条件限制在大写A to Z范围中一个字符

[a-zA-Z] 条件限制在小写a to z或大写A to Z范围中一个字符

[0-9]     条件限制在小写0 to 9范围中一个字符

[0-9a-z] 条件限制在小写0 to 9或a to z范围中一个字符

[0-9[a-z]] 条件限制在小写0 to 9或a to z范围中一个字符(交集)

 

[]中加入^后加再次限制条件「[^]」

[^a-z]     条件限制在非小写a to z范围中一个字符

[^A-Z]     条件限制在非大写A to Z范围中一个字符

[^a-zA-Z] 条件限制在非小写a to z或大写A to Z范围中一个字符

[^0-9]     条件限制在非小写0 to 9范围中一个字符

[^0-9a-z] 条件限制在非小写0 to 9或a to z范围中一个字符

[^0-9[a-z]] 条件限制在非小写0 to 9或a to z范围中一个字符(交集)

 

在限制条件为特定字符出现0次以上时,可以使用「*」

J*     0个以上J

.*     0个以上任意字符

J.*D     J与D之间0个以上任意字符

 

在限制条件为特定字符出现1次以上时,可以使用「+」

J+     1个以上J

.+     1个以上任意字符

J.+D     J与D之间1个以上任意字符

 

在限制条件为特定字符出现有0或1次以上时,可以使用「?」

JA?     J或者JA出现

 

限制为连续出现指定次数字符「{a}」

J{2}     JJ

J{3}     JJJ

文字a个以上,并且「{a,}」

J{3,}     JJJ,JJJJ,JJJJJ,???(3次以上J并存)

文字个以上,b个以下「{a,b}」

J{3,5}     JJJ或JJJJ或JJJJJ

两者取一「|」

J|A     J或A

Java|Hello     Java或Hello

 

「()」中规定一个组合类型

比如,我查询<a href="index.html">http://www.111cn.net </a>中<a href></a>间的数据,可写作<a.*href=".*">(.+?)</a>

 

在使用Pattern.compile函数时,可以加入控制正则表达式的匹配行为的参数:

Pattern Pattern.compile(String regex, int flag)

 

flag的取值范围如下:

Pattern.CANON_EQ     当且仅当两个字符的"正规分解(canonical decomposition)"都完全相同的情况下,才认定匹配。比如用了这个标志之后,表达式"au030A"会匹配"?"。默认情况下,不考虑"规 范相等性(canonical equivalence)"。

Pattern.CASE_INSENSITIVE(?i)     默认情况下,大小写不明感的匹配只适用于US-ASCII字符集。这个标志能让表达式忽略大小写进行匹配。要想对Unicode字符进行大小不明感的匹 配,只要将UNICODE_CASE与这个标志合起来就行了。

Pattern.COMMENTS(?x)     在这种模式下,匹配时会忽略(正则表达式里的)空格字符(译者注:不是指表达式里的"\s",而是指表达式里的空格,tab,回车之类)。注释从#开 始,一直到这行结束。可以通过嵌入式的标志来启用unix行模式。

Pattern.DOTALL(?s)     在这种模式下,表达式'.'可以匹配任意字符,包括表示一行的结束符。默认情况下,表达式'.'不匹配行的结束符。

Pattern.MULTILINE

(?m)     在这种模式下,'^'和'$'分别匹配一行的开始和结束。此外,'^'仍然匹配字符串的开始,'$'也匹配字符串的结束。默认情况下,这两个表达式仅仅匹 配字符串的开始和结束。

Pattern.UNICODE_CASE

(?u)     在这个模式下,如果你还启用了CASE_INSENSITIVE标志,那么它会对Unicode字符进行大小写不明感的匹配。默认情况下,大小写不敏感的 匹配只适用于US-ASCII字符集。

Pattern.UNIX_LINES(?d)     在这个模式下,只有'n'才被认作一行的中止,并且与'.','^',以及'$'进行匹配。

本文章分析了关于android手机开发时的ui应用中的 GridView和ImageView有需要的同学可以参考一下下哈。

GridView: A view that shows items in two-dimensional scrolling grid. The items in the grid come from the ListAdapter associated with this view. 简单说,GridView就是我们资源管理器平常见到的一个个文件的icon显示方式。
    上面提及到了,GridView的Item是来自ListAdapter的,所以一般在Activity的onCreate使用GridView的代码:

 代码如下 复制代码
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
 
    setContentView(R.layout.grid_2); 
 
    GridView g = (GridView) findViewById(R.id.myGrid); 
    g.setAdapter(new ImageAdapter(this)); 

    而ImageAdapter一般是extends BaseAdapter。BaseAdapter是implements ListAdapter SpinnerAdapter,但很多时候自定义的Adapter都是override ListAdapter的父类Adapter接口里面的方法:
   

 代码如下 复制代码
int     getCount()                   获取当前Adapter的Items数目
    Object getItem(int position)     获取相应position的Item
    long     getItemId(int position)  获取相应position的Item在List中的row id
    View    getView(int position, View convertView, ViewGroup parent)

获取在指定position所要显示的data的View
 
    这些方法函数和swing的差不多,都是基于MVC。大概原理过程是这样的:程序需要显示GridView,那么要把data一个一个地显示出来是通过一个for循环,首先call Adapter.getCount()得到有多少个data,然后position++地getItem,getView得到要显示的view,这样子逐一地显示出来!
 
下面是官方sample里面的Photo Grid的例子,本人省略了某些代码:

 代码如下 复制代码
public class ImageAdapter extends BaseAdapter { 
    public ImageAdapter(Context c) { 
        mContext = c; 
    } 
 
    public int getCount() { 
        return mThumbIds.length; 
    } 
 
    public Object getItem(int position) { 
        return position; 
    } 
 
    public long getItemId(int position) { 
        return position; 
    } 
 
    public View getView(int position, View convertView, ViewGroup parent) { 
        ImageView imageView; 
        if (convertView == null) { 
            imageView = new ImageView(mContext); 
            imageView.setLayoutParams(new GridView.LayoutParams(45, 45));//设置ImageView宽高 
            imageView.setAdjustViewBounds(false); 
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
            imageView.setPadding(8, 8, 8, 8); 
        } else { 
            imageView = (ImageView) convertView; 
        } 
 
        imageView.setImageResource(mThumbIds[position]); 
 
        return imageView; 
    } 
 
    private Context mContext; 
 
    private Integer[] mThumbIds = { 
            R.drawable.sample_thumb_0, R.drawable.sample_thumb_1, 
            R.drawable.sample_thumb_2, R.drawable.sample_thumb_3, 
            R.drawable.sample_thumb_4, R.drawable.sample_thumb_5, 
            R.drawable.sample_thumb_6, R.drawable.sample_thumb_7
    }; 

留意getView里面的代码,要判断convertView是否为null,以便重用,减少对象的创建,减少内存占用。
 
XML布局文件内容,原来就只是指明GridView:

 代码如下 复制代码
<?xml version="1.0" encoding="utf-8"?> 
<GridView xmlns:android="http://schemas.android.com/apk/res/android"  
    android:id="@+id/myGrid" 
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" 
    android:padding="10dp" 
    android:verticalSpacing="10dp" 
     
    android:horizontalSpacing="10dp" 
    android:numColumns="auto_fit" 
    android:columnWidth="60dp" 
    android:stretchMode="columnWidth" 
     
    android:gravity="center" 
    /> 
   

可以看到getView,和ImageView是重点,影响图片的显示效果。而且发现列数是不确定的,取决于每个ImageView的宽度和屏幕的宽度。接下来看看ImageView。
 
    ImageView:Displays an arbitrary image, such as an icon. The ImageView class can load images from various sources (such as resources or content providers), takes care of computing its measurement from the image so that it can be used in any layout manager, and provides various display options such as scaling and tinting。 ImageView就是用来显示Image,icon的。
    这里我们重点理解ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)。android:scaleType是控制图片如何resized/moved来匹对ImageView的size。ImageView.ScaleType / android: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 用矩阵来绘制
 
    一开始我不明白MATRIX矩阵,网上搜索后发现原来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的例子很多,看看上次FrameLayout里面的:
<ImageView 
    android:id="@+id/image" 
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" 
    android:scaleType="center" 
    android:src="@drawable/candle" 
    /> 
 


    ** 要注意一点,我发现Drawable文件夹里面的图片命名是不能大写的。

当一个应用的组件开始运行,并且这个应用没有其它的组件在运行,系统会为这个应用启动一个新的Linux进程,这个进程只有一个线程.默认情况下,一个应用的所有组件都运行在一个进程和线程(主线程)中.如果一个应用的线程开始运行,

并且已经存在这个应用的线程了(因为有这个应用程序的另一个组件已经运行了),于是这个组件就会在这个已有的进程中启动并且运行在同一个线程中.然而,你完全可以安排不同的组件运行于不同的进程,并且你可以为任何程序创建另外的线程.

进程

默认下,同一个程序的所有组件都运行在同一个进程中并且大多数程序不必改变这一状况.然而,如果你非要与众不同,也可以通过修改manifest文件实现.

manifest文件中的所有支持android:process属性的那些项(<activity>,<service>, <receiver>,和<provider>)都可以指定一个进程,于是这些组件就会在这个进程中运行.你可以设置这个属性使每个组件运行于其自己的进程或只是其中一些组件共享一个进程.你也可以设置android:process以使不同应用的组件们可以运行于同一个进程—假如这些应用共享同一个用户ID并且有相同的数字证书.

<application>元素也支持android:process属性,用于为所有的组件指定一个默认值.

Android可能在某些时刻决定关闭一个进程,比如内存很少了并且另一个进程更迫切的需要启动时.进程被关闭时,其中的组件们都被销毁.如果重新需要这些组件工作时,进程又会被创建出来.

当决定关闭哪些线程时,Android系统会衡量进程们与用户的紧密程度.例如,比起一个具有可见的activity的进程,那些所含activity全部不可见的进程更容易被关闭.如何决定一个进程是否被关闭,取决于进程中运行的组件们的状态.决定关闭进程的规则将在下面讨论.

进程的生命期

Android系统会尽量维持一个进程的生命,直到最终需要为新的更重要的进程腾出内存空间。为了决定哪个该杀哪个该留,系统会跟据运行于进程内的组件的和组件的状态把进程置于不同的重要性等级。当需要系统资源时,重要性等级越低的先被淘汰。

重要性等级被分为5个档。下面列出了不同类型的进程的重要性等级(第一个进程类型是最重要的,也是最后才会被杀的):

1前台进程

用户当前正在做的事情需要这个进程。如果满足下面的条件,一个进程就被认为是前台进程:

这个进程拥有一个正在与用户交互的Activity(这个Activity的onResume() 方法被调用)。

这个进程拥有一个绑定到正在与用户交互的activity上的Service。

这个进程拥有一个前台运行的Service — service调用了方法 startForeground().

这个进程拥有一个正在执行其任何一个生命周期回调方法(onCreate(),onStart(), 或onDestroy())的Service。

这个进程拥有正在执行其onReceive()方法的BroadcastReceiver。


通常,在任何时间点,只有很少的前台进程存在。它们只有在达到无法调合的矛盾时才会被杀--如果内存太小而不能继续运行时。通常,到了这时,设备就达到了一个内存分页调度状态,所以需要杀一些前台进程来保证用户界面的反应

2可见进程

一个进程不拥有运行于前台的组件,但是依然能影响用户所见。满足下列条件时,进程即为可见:

这个进程拥有一个不在前台但仍可见的Activity(它的onPause()方法被调用)。当一个前台activity启动一个对话框时,就出了这种情况。

3服务进程

一个可见进程被认为是极其重要的。并且,除非只有杀掉它才可以保证所有前台进程的运行,否则是不能动它的。

这个进程拥有一个绑定到可见activity的Service。

一个进程不在上述两种之内,但它运行着一个被startService()所启动的service。

尽管一个服务进程不直接影响用户所见,但是它们通常做一些用户关心的事情(比如播放音乐或下载数据),所以系统不到前台进程和可见进程活不下去时不会杀它。 4后台进程

一个进程拥有一个当前不可见的activity(activity的onStop()方法被调用)。

这样的进程们不会直接影响到用户体验,所以系统可以在任意时刻杀了它们从而为前台、可见、以及服务进程们提供存储空间。通常有很多后台进程在运行。它们被保存在一个LRU(最近最少使用)列表中来确保拥有最近刚被看到的activity的进程最后被杀。如果一个activity正确的实现了它的生命周期方法,并保存了它的当前状态,那么杀死它的进程将不会对用户的可视化体验造成影响。因为当用户返回到这个activity时,这个activity会恢复它所有的可见状态。

5空进程

一个进程不拥有入何active组件。

保留这类进程的唯一理由是高速缓存,这样可以提高下一次一个组件要运行它时的启动速度。系统经常为了平衡在进程高速缓存和底层的内核高速缓存之间的整体系统资源而杀死它们。


跟据进程中当前活动的组件的重要性,Android会把进程按排在其可能的最高级别。例如,如果一个进程拥有一个service和一个可见的activity,进程会被定为可见进程,而不是服务进程。

另外,如果被其它进程所依赖,一个进程的级别可能会被提高—一个服务于其它进程的进程,其级别不可能比被服务进程低。

因为拥有一个service的进程比拥有一个后台activitie的进程级别高,所以当一个activity启动一个需长时间执行的操作时,最好是启动一个服务,而不是简单的创建一个工作线程。尤其是当这个操作可能比activity的生命还要长时。例如,一个向网站上传图片的activity,应该启动一个service,从而使上传操作可以在用户离开这个activity时继续在后台执行。使用一个service保证了这个操作至少是在"服务进程"级别,而不用管activity是否发生了什么不幸。这同样是广播接收者应该使用service而不是简单地使用一个线程的理由。

 代码如下 复制代码

url: http://www.111cn.net/help/zt/21705.html


android进程与线程详解二:线程
线程

 


当一个应用被启动,系统创建一个执行线程,叫做"main"。这个线程是十分重要的,因为它主管向用户界面控件派发事件。其中包含绘图事件。它也是你的应用与界面工具包(android.widget和 android.view包中的组件)交互的地方。于是main线程也被称为界面线程。

 


系统不会为每个组件的实例分别创建线程。所有运行于一个进程的组件都在界面线程中被实例化,并且系统对每个组件的调用都在这个线程中派发。 结果,响应系统调用的方法(比如报告用户动作的onKeyDown()或一个生命周期回调方法)永远在界面线程中进程。

 


例如,当用户触摸屏幕上的一个按钮时,你的应用的界面线程把触摸事件派发给控件,然后控件设置它的按下状态再向事件队列发出一个自己界面变得无效的请求,界面线程从队列中取出这个请求并通知这个控件重绘它自己。


当你的应用在响应用户交互时需执行大量运算时,这种单线程的模式会带来低性能,除非你能正确的优化你的程序。特别的,如果所有事情都在界面线程中发生,执行比如网络连接或数据库请求这样的耗时操作,将会阻止整个界面的响应。当线程被阻塞时,就不能派发事件了,包括绘图事件。从用户的角度看,程序反应太慢了。甚至更糟的是,如果界面线程被阻塞几秒钟(大5秒钟吧),用户就户抱怨说程序没反应了,用户可能因而退出并删掉你的应用。


此外,Andoid界面不是线程安全的。所以你绝不能在一个工作线程中操作你的界面—你只能在界面线程中管理的你的界面。所以,对于单线程模式有两个简单的规则:

1 不要阻塞界面线程

2不要在界面线程之外操作界面。

 


工作线程

由于上述的单线程模式,不要阻塞你的界面线程以使你的应用的界面保持响应是非常重要的,那么如果你有不能很快完成的任务,你应把它们放在另一个线程中执行(后台线程或工作线程)。

例如,下面是的代码是响应click事件,在另外一个线程中下载一个图片并在一个ImageView中显示它:

 

 代码如下 复制代码
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);
}
}).start();
}

第一眼,这看起来能很好的工作,因为它创建了一个新线程来进行网络操作。然而它违反了第二条规则:不要在界面线程之外操作界面—它简单的在工作线程中修改了ImageView。这会导至未定义的异常出现,并且难以调试追踪。


为了能改正这个问题,Android提供了很多从其它线程来操作界面的方法。下面是可用的方法们:

 代码如下 复制代码

1 Activity.runOnUiThread(Runnable)

2 View.post(Runnable)

3 View.postDelayed(Runnable,long)


例如,你可以用View.post(Runnable)来修正上面的问题:

 

 代码如下 复制代码
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}

现在这个实现终于是线程安全的了:网络操作在另一个线程中并且ImageView 在界面线程中改变。

在xml布局文件中,我们既可以设置px,也可以设置dp(或者dip)。一般情况下,我们都会选择使用dp,这样可以保证不同屏幕分辨率的机器上布局一致。但是在代码中,如何处理呢?很多控件的方法中都只提供了设置px的方法,例如setPadding,并没有提供设置dp的方法。这个时候,如果需要设置dp的话,就要将dp转换成px了。

以下是一个应用类,方便进行px和dp之间的转换。

 代码如下 复制代码

import android.content.Context; 

 

public class DensityUtil { 

 

/** 

* 根据手机的分辨率从 dp 的单位 转成为 px(像素) 

*/ 

public static int dip2px(Context context, float dpValue) { 

final float scale = context.getResources().getDisplayMetrics().density; 

return (int) (dpValue * scale + 0.5f); 

 

/** 

* 根据手机的分辨率从 px(像素) 的单位 转成为 dp 

*/ 

public static int px2dip(Context context, float pxValue) { 

final float scale = context.getResources().getDisplayMetrics().density; 

return (int) (pxValue / scale + 0.5f); 

}

 

url:http://www.111cn.net/nokia/N97/

有一些场景,我们需要向用户展示一系列的页面。比如我们正在开发一个看漫画的应用,可能就需要向用户展示一张一张的漫画图片,用户使用手指滑动屏幕,可以在前一幅漫画和后一幅漫画之间切换。这个时候ViewFlipper就是一个很好的选择。

1)View切换的控件—ViewFlipper介绍

ViewFilpper类继承于ViewAnimator类。而ViewAnimator类继承于FrameLayout。

查看ViewAnimator类的源码可以看出此类的作用主要是为其中的View切换提供动画效果。该类有如下几个和动画相关的方法。

setInAnimation:设置View进入屏幕时候使用的动画。该方法有两个重载方法,即可以直接传入Animation对象,也可以传入定义的Animation文件的resourceID。

setOutAnimation:设置View退出屏幕时候使用的动画。使用方法和setInAnimation方法一样。

showNext:调用该方法可以显示FrameLayout里面的下一个View。

showPrevious:调用该方法可以来显示FrameLayout里面的上一个View。

查看ViewFlipper的源码可以看到,ViewFlipper主要用来实现View的自动切换。该类提供了如下几个主要的方法。

setFilpInterval:设置View切换的时间间隔。参数为毫秒。

startFlipping:开始进行View的切换,时间间隔是上述方法设置的间隔数。切换会循环进行。

stopFlipping:停止View切换。

setAutoStart:设置是否自动开始。如果设置为“true”,当ViewFlipper显示的时候View的切换会自动开始。

一般情况下,我们都会使用ViewFilpper类实现View的切换,而不使用它的父类ViewAnimator类。

2)实现滑动—GestureDetector介绍

如果想要实现滑动翻页的效果,就要了解另外一个类:android.view.GestureDetector类。GestureDetector类中可以用来检测各种手势事件。该类有两个回调接口,分别用来通知具体的事件。

GestureDetector.OnDoubleTapListener:用来通知DoubleTap事件,类似于PC上面的鼠标的双击事件。

GestureDetector.OnGestureListener:用来通知普通的手势事件,该接口有六个回调方法,具体的可以查看API。这里想要实现滑动的判断,就需要用到其中的onFling()方法。

3)具体的实现

下面的代码片段详细说明了如何实现滑动翻页。

 代码如下 复制代码

public class ViewFlipperActivity extends Activity implements OnGestureListener { 

 

private static final int FLING_MIN_DISTANCE = 100; 

private ViewFlipper flipper; 

private GestureDetector detector; 

 

@Override 

protected void onCreate(Bundle savedInstanceState) { 

super.onCreate(savedInstanceState); 

setContentView(R.layout.viewflipper); 

// 注册一个GestureDetector 

detector = new GestureDetector(this); 

flipper = (ViewFlipper) findViewById(R.id.ViewFlipper); 

ImageView image1 = new ImageView(this); 

image1.setBackgroundResource(R.drawable.image1); 

// 增加第一个view 

flipper.addView(image1); 

ImageView image2 = new ImageView(this); 

image2.setBackgroundResource(R.drawable.image2); 

// 增加第二个view 

flipper.addView(image2); 

 

@Override 

public boolean onTouchEvent(MotionEvent event) { 

// 将触屏事件交给手势识别类处理 

return this.detector.onTouchEvent(event); 

 

@Override 

public boolean onDown(MotionEvent e) { 

return false; 

 

@Override 

public void onShowPress(MotionEvent e) { 

 

@Override 

public boolean onSingleTapUp(MotionEvent e) { 

return false; 

 

@Override 

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, 

float distanceY) { 

return false; 

 

@Override 

public void onLongPress(MotionEvent e) { 

 

@Override 

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 

float velocityY) { 

if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE) { 

//设置View进入和退出的动画效果 

this.flipper.setInAnimation(AnimationUtils.loadAnimation(this, 

R.anim.left_in)); 

this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this, 

R.anim.left_out)); 

this.flipper.showNext(); 

return true; 

if (e1.getX() - e2.getX() < -FLING_MIN_DISTANCE) { 

this.flipper.setInAnimation(AnimationUtils.loadAnimation(this, 

R.anim.right_in)); 

this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this, 

R.anim.right_out)); 

this.flipper.showPrevious(); 

return true; 

return false; 


在这段代码里,创建了两个IamgeView(用来显示图片),加入到了ViewFlipper中。程序运行后,当用手指在屏幕上向左滑动,会显示前一个图片,用手指在屏幕上向右滑动,会显示下一个图片。实现滑动切换的主要代码都在onFling()方法中,用户按下触摸屏,快速移动后松开,就会触发这个事件。在这段代码示例中,对手指滑动的距离进行了计算,如果滑动距离大于100像素,就做切换动作,否则不做任何切换动作。

可以看到,onFling()方法有四个参数,e1和e2上面代码用到了,比较好理解。参数velocityX和velocityY是做什么用的呢?velocityX和velocityY实际上是X轴和Y轴上的移动速度,单位是像素/秒。结合这两个参数,可以判断滑动的速度,从而做更多的处理。

为了显示出滑动的效果,这里调用了ViewFlipper的setInAnimation()和setOutAnimation()方法设置了View进入和退出的动画。对于动画的使用,这里不再赘述,也不再给出具体的XML文件代码了。

本文章简单的介绍了关于android开发之aChartEngine图表显示 ,有需要手机开发时显示图表效果的朋友可以参考一下下哈。
 代码如下 复制代码
  对于数据的可视化,之前,是想直接用Canvas 来画,不过,评估了一下,工作量挺大的,因为,是一个人开发,而且是从零开始,如果写一个Canvas 画报表的方法,太费时间了,于是,上网找了一下,果然被我找到了…
AchartEngine
http://code.google.com/achartengine
绘制的基础
 代码如下 复制代码
  很多,使用这个引擎的同学,大多,会被它提供的例子的给吓到,因为,太多参数了!到最后,都不知道看到那里去了,其实,仔细研究,这个引擎的使用是非常简单…()
首先,我们整理一下思路,一般绘制一个图表需要:如下图所示
achart2
 
从图中,我们可以看出,绘制一个图表我们其实,我们只需要理解三个概念
1,ChartFactory ,传入XYMutilpleSeriesRenderer,XYMutilpleSeriesDataset,然后,我们只需用getXXXChartIntent(Context context,XYMutilpleSeriesRenderer,XYMutilpleSeriesDataset,)方法就可以进行图表的显示
2,XYMutilpleSeriesRenderer 用于进行绘制的设置,添加的XYSeriesRender对象,用于定义绘制的点集合设置,注意数量要和XYMutilpleSeriesDataset,添加的XYseries一致!!!
3,XYMutilpleSeriesDataset 用于数据的存放,添加的XYseries对象,用于提供绘制的点集合的数据
以下为一个小例子:
public class ShowExamActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		// 1, 构造显示用渲染图
		XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
		// 2,进行显示
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		// 2.1, 构建数据
		Random r = new Random();
		for (int i = 0; i < 2; i++) {
			XYSeries series = new XYSeries("test" + (i + 1));
			// 填充数据
			for (int k = 0; k < 10; k++) {
				// 填x,y值
				series.add(k, 20 + r.nextInt() % 100);
			}
			// 需要绘制的点放进dataset中
			dataset.addSeries(series);
		}
		// 3, 对点的绘制进行设置
		XYSeriesRenderer xyRenderer = new XYSeriesRenderer();
		// 3.1设置颜色
		xyRenderer.setColor(Color.BLUE);
		// 3.2设置点的样式
		xyRenderer.setPointStyle(PointStyle.SQUARE);
		// 3.3, 将要绘制的点添加到坐标绘制中
		renderer.addSeriesRenderer(xyRenderer);
		// 3.4,重复 1~3的步骤绘制第二个系列点
		xyRenderer = new XYSeriesRenderer();
		xyRenderer.setColor(Color.RED);
		xyRenderer.setPointStyle(PointStyle.CIRCLE);
		renderer.addSeriesRenderer(xyRenderer);

		// Intent intent = new LinChart().execute(this);
		Intent intent = ChartFactory
				.getLineChartIntent(this, dataset, renderer);
		startActivity(intent);

	}
}
这里有一点要注意,我们是用内置的activity进行我们的图表的显示:所以,我们要在AndroiManifest里面添加一句
<activity android:name="org.achartengine.GraphicalActivity" />
效果:
device-2012-01-18-000853
在稍后的一段时间里面,我会谈谈如何在xml布局文件里面嵌套我们的图表,有兴趣的朋友,可以进行关注
[!--infotagslink--]

相关文章

  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • PHP正则表达式取双引号内的内容

    取双引号内的内容我们如果一个字符串中只有一个可以使用explode来获得,但如果有多个需要使用正则表达式来提取了,具体的例子如下。 写程序的时候总结一点经验,如何只...2016-11-25
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
  • 深入理解Android中View和ViewGroup

    深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
  • PHP正则表达式之捕获组与非捕获组

    今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同...2015-11-08
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • Android设置TextView竖着显示实例

    TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
  • php 验证只能输入汉字、英语、数字的正则表达式

    正则表达式是一门非常有用的并且进行模糊判断的一个功能了,我们下面来看通过正则来验证输入汉字、英语、数字,具体如下。 收藏了正则表达式。可以验证只能输入数...2016-11-25
  • java正则表达式判断前端参数修改表中另一个字段的值

    这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
  • android.os.BinderProxy cannot be cast to com解决办法

    本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20
  • 常用的日期时间正则表达式

    常用的日期时间正则表达式 下面收藏了大量的日期时间正则匹配函数,包括分钟,时间与秒都能达到。 正则表达式 (?n:^(?=d)((?<day>31(?!(.0?[2469]|11))|30(?!.0?2)|29(...2016-11-25
  • Android 开发之布局细节对比:RTL模式

    下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
  • PHP正则表达式匹配验证提取网址URL实例总结

    网址规则是可寻的,所以我们可以使用正则表达式来提取字符串中的url地址了,下面一起来看看小编整理的几个PHP正则表达式匹配验证提取网址URL实例. 匹配网址 URL 的...2016-11-25
  • Android 实现钉钉自动打卡功能

    这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
  • Android中使用SDcard进行文件的读取方法

    首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20