动态设置全屏、取消全屏的方法,以及切换全屏保持内容位置不变的方法

时间:2016-12-23   作者:   分类: Android   热度:33°  评论:0  
时间:2016-12-23   分类: Android    热度:33   评论:0

有两种形式设置、取消全屏的方法,之所以称作两种形式而不是两种方法,是因为这两种方式只是写法不同,实质是一样的。


形式一:

//设置全屏

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

//取消全屏

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);


形式二:

//设置全屏

WindowManager.LayoutParams attr = getWindow().getAttributes();
attr.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attr);

//取消全屏

WindowManager.LayoutParams attr = getWindow().getAttributes();
attr.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attr);



全屏状态改为非全屏保持内容位置不变:
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);


这里有一个问题:

当设置了该flag之后取消全屏,部分内容被状态栏挡住(忽略状态栏高度,以屏幕右上角为原点计算布局)

加上代码getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);可以解决该问题,但再次设置全屏的时候状态栏不消失。

startActivityForResult和setResult

时间:2016-10-27   作者:   分类: Android   热度:122°  评论:0  
时间:2016-10-27   分类: Android    热度:122   评论:0

startActivityForResult与startActivity的不同之处在于:
1. startActivity( )
仅仅是跳转到目标页面,若是想跳回当前页面,则必须再使用一次startActivity( )。
2. startActivityForResult( )
可以一次性完成这项任务,当程序执行到这段代码的时候,假若从T1Activity跳转到下一个Text2Activity,而当这个 Text2Activity调用了finish()方法以后,程序会自动跳转回T1Activity,并调用前一个T1Activity中的 onActivityResult( )方法。

相关函数:
startActivityForResult(Intent intent, Int requestCode)
setResut(int resultCode, Intent intent)
onActivityResult(int requestCode, int resultCode, Intent intent)

简单例子介绍:

1.跳转的时候不是采用startActivity(intent) 这个方法,而是startActivityForResult(intent, 0)

Intent intent=new Intent();
intent.setClass(A.this, B.class);
Bundle bundle=new Bundle();
String str1="aaaaaa";
bundle.putString("str1", str1);
intent.putExtras(bundle);
startActivityForResult(intent, 0);//这里采用startActivityForResult来做跳转,此处的0为一个依据,可以写其他的值,但一定要>=0

2.重写onActivityResult方法,用来接收B回传的数据。

protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (resultCode) { //resultCode为回传的标记,我在B中回传的是RESULT_OK case RESULT_OK:
    Bundle b=data.getExtras(); //data为B中回传的Intent String str=b.getString("str1");//str即为回传的值 break; default: break;
    }
}

3.在B中回传数据时采用setResult方法,并且之后要调用finish方法。

setResult(RESULT_OK, intent); //intent为A传来的带有Bundle的intent,当然也可以自己定义新的Bundle
finish();//此处一定要调用finish()方法

Android activity的setResult()在什么时候调用(重点也是难点)

如果在startActivityForResult起来的Activity里面设置setResult,结果并不会马上返回给parent的 Activity,只有当前Activity被finish,结果才会被发送给parent的onActivityResult去处理!

如果一个activity要返回数据到启动它的那个activity,可以调用setResult()方法。那什么时候去调用setResult()方法返回数据呢?
看一下源码就明白了:

public final void setResult(int resultCode, Intent data) { synchronized (this) {
            mResultCode = resultCode;
            mResultData = data;
        }
    } public void finish() { if (mParent == null) { int resultCode;
            Intent resultData; synchronized (this) {
                resultCode = mResultCode;
                resultData = mResultData;
            } if (Config.LOGV) Log.v(TAG, "Finishing self: token=" + mToken); try { if (ActivityManagerNative.getDefault()
                    .finishActivity(mToken, resultCode, resultData)) {
                    mFinished = true;
                }
            } catch (RemoteException e) { // Empty }
        } else {
            mParent.finishFromChild(this);
        }
    }

这段代码可以看出activity返回result是在被finish的时候,也就是说调用setResult()方法必须在finish()之前。
那么如果在如下方法中调用setResult()也有可能不会返回成功: onPause(), onStop(), onDestroy(),
因为这些方法调用不一定是在finish之前的,当然在onCreate()就调用setResult肯定是在finish之前的

按BACK键从一个Activity退出来的,一按BACK,android就会自动调用Activity的finish()方法,然后设置resultCode为RESULT_CANCELED,也就不会返回任何数据了 .
解决方法就是在Activity里面捕获按BACK的事件,捕获到之后先setResult,然后自己来调用finish,就搞定了……把BACK事件直接自己给吞了

@Override public void onBackPressed() {
        Log.i(TAG, "onBackPressed");
        setResult(Const.LIVE_OK); super.onBackPressed();
    }

当然还可以在onCreate()就调用setResult,不过我觉得这种方法没有重写onBackPressed()方法好.

献给写作者的 Markdown 新手指南

时间:2016-10-21   作者:   分类: 其它   热度:69°  评论:0  
时间:2016-10-21   分类: 其它    热度:69   评论:0

Markdown 是一种「电子邮件」风格的「标记语言」,我们强烈推荐所有写作者学习和掌握该语言。为什么?可以参考:

在此,我们总结 Markdown 的优点如下:

  • 纯文本,所以兼容性极强,可以用所有文本编辑器打开。
  • 让你专注于文字而不是排版。
  • 格式转换方便,Markdown 的文本你可以轻松转换为 html、电子书等。
  • Markdown 的标记语法有极好的可读性。

当然,我们既然如此推崇 Markdown ,也必定会教会你使用 Markdown ,这也是本文的目的所在。不过,虽然 Markdown 的语法已经足够简单,但是现有的 Markdown 语法说明更多的是写给 web 从业者看的,对于很多写作者来说,学习起来效率很低,现在,我们特地为写作者量身定做本指南,从写作者的实际需求出发,介绍写作者真正实用的常用格式,深入浅出、图文并茂地让您迅速掌握 Markdown 语法。

为了使您更好地学习,我们建议您登录「简书」,将您的编辑器切换至 Markdown 编辑器,新建一篇空白笔记,然后点击右上角的预览模式:



此时,您的界面应当如下图所示,左侧为编辑区域,右侧为预览区域,您在左侧输入 Markdown 语法的文本,右侧会立即帮您呈现最终结果,好了,让我们开始学习吧~


标题

这是最为常用的格式,在平时常用的的文本编辑器中大多是这样实现的:输入文本、选中文本、设置标题格式。

而在 Markdown 中,你只需要在文本前面加上 # 即可,同理、你还可以增加二级标题、三级标题、四级标题、五级标题和六级标题,总共六级,只需要增加 # 即可,标题字号相应降低。例如:

# 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题

注:# 和「一级标题」之间建议保留一个字符的空格,这是最标准的 Markdown 写法。

你可以你的编辑器中尝试输入这六级标题,可以参考下方的截图:


一级标题至六级标题



列表

列表格式也很常用,在 Markdown 中,你只需要在文字前面加上 - 就可以了,例如:

- 文本1 - 文本2 - 文本3

如果你希望有序列表,
也可以在文字前面加上 1. 2. 3. 就可以了,例如:

1. 文本1 2. 文本2 3. 文本3

注:-1.和文本之间要保留一个字符的空格。

列表案例截图如下:


链接和图片

在 Markdown 中,插入链接不需要其他按钮,你只需要使用 [显示文本](链接地址) 这样的语法即可,例如:

[简书](http://www.jianshu.com)

在 Markdown 中,插入图片不需要其他按钮,你只需要使用 ![](图片链接地址) 这样的语法即可,例如:

![](http://ww4.sinaimg.cn/bmiddle/aa397b7fjw1dzplsgpdw5j.jpg)

注:插入图片的语法和链接的语法很像,只是前面多了一个 

插入链接和图片的案例截图:


引用

在我们写作的时候经常需要引用他人的文字,这个时候引用这个格式就很有必要了,在 Markdown 中,你只需要在你希望引用的文字前面加上 > 就好了,例如:

> 一盏灯, 一片昏黄; 一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。

注:> 和文本之间要保留一个字符的空格。

最终显示的就是:

一盏灯, 一片昏黄; 一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。

引用的案例截图:


粗体和斜体

Markdown 的粗体和斜体也非常简单,用两个 * 包含一段文本就是粗体的语法,用一个 * 包含一段文本就是斜体的语法。例如:

 *一盏灯*, 一片昏黄;**一简书**, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。

最终显示的就是下文,其中「一盏灯」是斜体,「一简书」是粗体:

一盏灯, 一片昏黄;一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。

粗体和斜体的案例截图:


代码引用

需要引用代码时,如果引用的语句只有一段,不分行,可以用 ` 将语句包起来。
如果引用的语句为多行,可以将```置于这段代码的首行和末行。
代码引用的案例截图:


表格

相关代码:

| Tables | Are | Cool |
| ------------- |:-------------:| -----:| | col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      | $12 |
| zebra stripes | are neat      | $1 |

显示效果:

Tables Are Cool
col 3 is right-aligned $1600
col 2 is centered $12
zebra stripes are neat $1


相关代码:

dog | bird | cat ----|------|---- foo | foo  | foo
bar | bar  | bar
baz | baz  | baz

显示效果:
dog | bird | cat
----|------|----
foo | foo | foo
bar | bar | bar
baz | baz | baz

显示链接中带括号的图片


代码如下:

![][1] [1]: http://latex.codecogs.com/gif.latex?\prod%20\(n_{i}\)+1

结语

以上几种格式是比较常用的格式,所以我们针对这些语法做了比较详细的说明。除这些之外,Markdown 还有其他语法,如想了解和学习更多,可以参考这篇『Markdown 语法说明』



常用数据库数据类型及大小

时间:2016-10-10   作者:   分类: SQL   热度:98°  评论:0  
时间:2016-10-10   分类: SQL    热度:98   评论:0
常用数据库数据类型及大小

Microsoft Access 数据类型
数据类型 描述 存储
Text 用于文本或文本与数字的组合。最多 255 个字符。
Memo Memo 用于更大数量的文本。最多存储 65,536 个字符。
注释:无法对 memo 字段进行排序。不过它们是可搜索的。

Byte 允许 0 到 255 的数字。 1 字节
Integer 允许介于 -32,768 到 32,767 之间的数字。 2 字节
Long 允许介于 -2,147,483,648 与 2,147,483,647 之间的全部数字 4 字节
Single 单精度浮点。处理大多数小数。 4 字节
Double 双精度浮点。处理大多数小数。 8 字节
Currency 用于货币。支持 15 位的元,外加 4 位小数。
提示:您可以选择使用哪个国家的货币。
8 字节
AutoNumber AutoNumber 字段自动为每条记录分配数字,通常从 1 开始。 4 字节
Date/Time 用于日期和时间 8 字节
Yes/No 逻辑字段,可以显示为 Yes/No、True/False 或 On/Off。
在代码中,使用常量 True 和 False (等价于 1 和 0)
注释:Yes/No 字段中不允许 Null 值
1 比特
Ole Object 可以存储图片、音频、视频或其他 BLOBs (Binary Large OBjects) 最多 1GB
Hyperlink 包含指向其他文件的链接,包括网页。
Lookup Wizard 允许你创建一个可从下列列表中进行选择的选项列表。 4 字节
MySQL 数据类型
在 MySQL 中,有三种主要的类型:文本、数字和日期/时间类型。
Text 类型:
数据类型 描述
CHAR(size) 保存固定长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的长度。最多 255 个字符。
VARCHAR(size) 保存可变长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的最大长度。最多 255 个字符。
注释:如果值的长度大于 255,则被转换为 TEXT 类型。
TINYTEXT 存放最大长度为 255 个字符的字符串。
TEXT 存放最大长度为 65,535 个字符的字符串。
BLOB 用于 BLOBs (Binary Large OBjects)。存放最多 65,535 字节的数据。
MEDIUMTEXT 存放最大长度为 16,777,215 个字符的字符串。
MEDIUMBLOB 用于 BLOBs (Binary Large OBjects)。存放最多 16,777,215 字节的数据。
LONGTEXT 存放最大长度为 4,294,967,295 个字符的字符串。
LONGBLOB 用于 BLOBs (Binary Large OBjects)。存放最多 4,294,967,295 字节的数据。
ENUM(x,y,z,etc.) 允许你输入可能值的列表。可以在 ENUM 列表中列出最大 65535 个值。如果列表中不存在插入的值,则插入空值。
注释:这些值是按照你输入的顺序存储的。
可以按照此格式输入可能的值:ENUM('X','Y','Z')
SET 与 ENUM 类似,SET 最多只能包含 64 个列表项,不过 SET 可存储一个以上的值。
Number 类型:
数据类型 描述
TINYINT(size) -128 到 127 常规。0 到 255 无符号*。在括号中规定最大位数。
SMALLINT(size) -32768 到 32767 常规。0 到 65535 无符号*。在括号中规定最大位数。
MEDIUMINT(size) -8388608 到 8388607 普通。0 to 16777215 无符号*。在括号中规定最大位数。
INT(size) -2147483648 到 2147483647 常规。0 到 4294967295 无符号*。在括号中规定最大位数。
BIGINT(size) -9223372036854775808 到 9223372036854775807 常规。0 到 18446744073709551615 无符号*。在括号中规定最大位数。
FLOAT(size,d) 带有浮动小数点的小数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。
DOUBLE(size,d) 带有浮动小数点的大数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。
DECIMAL(size,d) 作为字符串存储的 DOUBLE 类型,允许固定的小数点。
* 这些整数类型拥有额外的选项 UNSIGNED。通常,整数可以是负数或正数。如果添加 UNSIGNED 属性,那么范围将从 0 开始,而不是某个负数。
Date 类型:
数据类型 描述
DATE() 日期。格式:YYYY-MM-DD
注释:支持的范围是从 '1000-01-01' 到 '9999-12-31'
DATETIME() *日期和时间的组合。格式:YYYY-MM-DD HH:MM:SS
注释:支持的范围是从 '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59'
TIMESTAMP() *时间戳。TIMESTAMP 值使用 Unix 纪元('1970-01-01 00:00:00' UTC) 至今的描述来存储。格式:YYYY-MM-DD HH:MM:SS
注释:支持的范围是从 '1970-01-01 00:00:01' UTC 到 '2038-01-09 03:14:07' UTC
TIME() 时间。格式:HH:MM:SS 注释:支持的范围是从 '-838:59:59' 到 '838:59:59'
YEAR() 2 位或 4 位格式的年。
注释:4 位格式所允许的值:1901 到 2155。2 位格式所允许的值:70 到 69,表示从 1970 到 2069。
* 即便 DATETIME 和 TIMESTAMP 返回相同的格式,它们的工作方式很不同。在 INSERT 或 UPDATE 查询中,TIMESTAMP 自动把自身设置为当前的日期和时间。TIMESTAMP 也接受不同的格式,比如 YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD 或 YYMMDD。
SQL Server 数据类型
Character 字符串:
数据类型 描述 存储
char(n) 固定长度的字符串。最多 8,000 个字符。 n
varchar(n) 可变长度的字符串。最多 8,000 个字符。
varchar(max) 可变长度的字符串。最多 1,073,741,824 个字符。
text 可变长度的字符串。最多 2GB 字符数据。
Unicode 字符串:
数据类型 描述 存储
nchar(n) 固定长度的 Unicode 数据。最多 4,000 个字符。
nvarchar(n) 可变长度的 Unicode 数据。最多 4,000 个字符。
nvarchar(max) 可变长度的 Unicode 数据。最多 536,870,912 个字符。
ntext 可变长度的 Unicode 数据。最多 2GB 字符数据。
Binary 类型:
数据类型 描述 存储
bit 允许 0、1 或 NULL
binary(n) 固定长度的二进制数据。最多 8,000 字节。
varbinary(n) 可变长度的二进制数据。最多 8,000 字节。
varbinary(max) 可变长度的二进制数据。最多 2GB 字节。
image 可变长度的二进制数据。最多 2GB。
Number 类型:
数据类型 描述 存储
tinyint 允许从 0 到 255 的所有数字。 1 字节
smallint 允许从 -32,768 到 32,767 的所有数字。 2 字节
int 允许从 -2,147,483,648 到 2,147,483,647 的所有数字。 4 字节
bigint 允许介于 -9,223,372,036,854,775,808 和 9,223,372,036,854,775,807 之间的所有数字。 8 字节
decimal(p,s) 固定精度和比例的数字。允许从 -10^38 +1 到 10^38 -1 之间的数字。
p 参数指示可以存储的最大位数(小数点左侧和右侧)。p 必须是 1 到 38 之间的值。默认是 18。
s 参数指示小数点右侧存储的最大位数。s 必须是 0 到 p 之间的值。默认是 0。
5-17 字节
numeric(p,s) 固定精度和比例的数字。允许从 -10^38 +1 到 10^38 -1 之间的数字。
p 参数指示可以存储的最大位数(小数点左侧和右侧)。p 必须是 1 到 38 之间的值。默认是 18。
s 参数指示小数点右侧存储的最大位数。s 必须是 0 到 p 之间的值。默认是 0。
5-17 字节
smallmoney 介于 -214,748.3648 和 214,748.3647 之间的货币数据。 4 字节
money 介于 -922,337,203,685,477.5808 和 922,337,203,685,477.5807 之间的货币数据。 8 字节
float(n) 从 -1.79E + 308 到 1.79E + 308 的浮动精度数字数据。 参数 n 指示该字段保存 4 字节还是 8 字节。float(24) 保存 4 字节,而 float(53) 保存 8 字节。n 的默认值是 53。 4 或 8 字节
real 从 -3.40E + 38 到 3.40E + 38 的浮动精度数字数据。 4 字节
Date 类型:
数据类型 描述 存储
datetime 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 3.33 毫秒。 8 bytes
datetime2 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 100 纳秒。 6-8 bytes
smalldatetime 从 1900 年 1 月 1 日 到 2079 年 6 月 6 日,精度为 1 分钟。 4 bytes
date 仅存储日期。从 0001 年 1 月 1 日 到 9999 年 12 月 31 日。 3 bytes
time 仅存储时间。精度为 100 纳秒。 3-5 bytes
datetimeoffset 与 datetime2 相同,外加时区偏移。 8-10 bytes
timestamp 存储唯一的数字,每当创建或修改某行时,该数字会更新。timestamp 基于内部时钟,不对应真实时间。每个表只能有一个 timestamp 变量。
其他数据类型:
数据类型 描述
sql_variant 存储最多 8,000 字节不同数据类型的数据,除了 text、ntext 以及 timestamp。
uniqueidentifier 存储全局标识符 (GUID)。
xml 存储 XML 格式化数据。最多 2GB。
cursor 存储对用于数据库操作的指针的引用。
table 存储结果集,供稍后处理。

Android Fragment使用碎片实现底部按钮Tab

时间:2016-9-13   作者:   分类: Android   热度:93°  评论:0  
时间:2016-9-13   分类: Android    热度:93   评论:0

出处:http://blog.csdn.net/guolin_blog/article/details/8881711

源码地址:http://pan.baidu.com/s/1pKA7gBx

现在Fragment的应用真的是越来越广泛了,之前Android在3.0版本加入Fragment的时候,主要是为了解决Android Pad屏幕比较大,空间不能充分利用的问题,但现在即使只是在手机上,也有很多的场景可以运用到Fragment了,今天我们就来学习其中一个特别棒的应用技巧。

很多手机应用都会有一个非常类似的功能,即屏幕的下方显示一行Tab标签选项,点击不同的标签就可以切换到不同的界面,如以下几个应用所示:

                     

上面三个应用从左到右分别是QQ、新浪微博和支付宝钱包,可见,这种底部标签式的布局策略真的非常常见。

那么话说回来,这种效果到底是如何的呢?熟悉Android的朋友一定都会知道,很简单嘛,使用TabHost就OK了!但是殊不知,TabHost并非是那么的简单,它的可扩展性非常的差,不能随意地定制Tab项显示的内容,而且运行还要依赖于ActivityGroup。ActivityGroup原本主要是用于为每一个TabHost的子项管理一个单独的Activity,但目前已经被废弃了。为什么呢?当然就是因为Fragment的出现了!查看Android官方文档中ActivityGroup的描述,如下所示:

        

可以看到,在API 13的时候Android就已经将ActivityGroup废弃掉了,并且官方推荐的替代方式就是使用Fragment,因为它使用起来更加的灵活。那么剩下的问题就是如何借助Fragment来完成类似于TabHost一般的效果了,因此我们自然要动起手来了。

另外,我们还应该准备好程序所需要的资源,比如说每一个Tab项中所用到的图片。我已经事先从QQ里截好了几张图作为这个项目的资源,稍后会连同源码一起给出。

新建一个项目,起名就叫FragmentDemo,这里我使用的是4.0的API。

下面开始编程工作,这里我们首先需要去编写一个类似于QQ的主界面,当然只会去编写界面最下方的TabHost部分,而不会编写上面的内容界面部分,因为内容界面是应该写在Fragment的布局里的。打开或新建activity_main.xml作为程序的主布局文件,在里面加入如下代码:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:orientation="vertical" >  
  5.   
  6.     <FrameLayout  
  7.         android:id="@+id/content"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="0dp"  
  10.         android:layout_weight="1" >  
  11.     </FrameLayout>  
  12.   
  13.     <LinearLayout  
  14.         android:layout_width="match_parent"  
  15.         android:layout_height="60dp"  
  16.         android:background="@drawable/tab_bg" >  
  17.   
  18.         <RelativeLayout  
  19.             android:id="@+id/message_layout"  
  20.             android:layout_width="0dp"  
  21.             android:layout_height="match_parent"  
  22.             android:layout_weight="1" >  
  23.   
  24.             <LinearLayout  
  25.                 android:layout_width="match_parent"  
  26.                 android:layout_height="wrap_content"  
  27.                 android:layout_centerVertical="true"  
  28.                 android:orientation="vertical" >  
  29.   
  30.                 <ImageView  
  31.                     android:id="@+id/message_image"  
  32.                     android:layout_width="wrap_content"  
  33.                     android:layout_height="wrap_content"  
  34.                     android:layout_gravity="center_horizontal"  
  35.                     android:src="@drawable/message_unselected" />  
  36.   
  37.                 <TextView  
  38.                     android:id="@+id/message_text"  
  39.                     android:layout_width="wrap_content"  
  40.                     android:layout_height="wrap_content"  
  41.                     android:layout_gravity="center_horizontal"  
  42.                     android:text="消息"  
  43.                     android:textColor="#82858b" />  
  44.             </LinearLayout>  
  45.         </RelativeLayout>  
  46.   
  47.         <RelativeLayout  
  48.             android:id="@+id/contacts_layout"  
  49.             android:layout_width="0dp"  
  50.             android:layout_height="match_parent"  
  51.             android:layout_weight="1" >  
  52.   
  53.             <LinearLayout  
  54.                 android:layout_width="match_parent"  
  55.                 android:layout_height="wrap_content"  
  56.                 android:layout_centerVertical="true"  
  57.                 android:orientation="vertical" >  
  58.   
  59.                 <ImageView  
  60.                     android:id="@+id/contacts_image"  
  61.                     android:layout_width="wrap_content"  
  62.                     android:layout_height="wrap_content"  
  63.                     android:layout_gravity="center_horizontal"  
  64.                     android:src="@drawable/contacts_unselected" />  
  65.   
  66.                 <TextView  
  67.                     android:id="@+id/contacts_text"  
  68.                     android:layout_width="wrap_content"  
  69.                     android:layout_height="wrap_content"  
  70.                     android:layout_gravity="center_horizontal"  
  71.                     android:text="联系人"  
  72.                     android:textColor="#82858b" />  
  73.             </LinearLayout>  
  74.         </RelativeLayout>  
  75.   
  76.         <RelativeLayout  
  77.             android:id="@+id/news_layout"  
  78.             android:layout_width="0dp"  
  79.             android:layout_height="match_parent"  
  80.             android:layout_weight="1" >  
  81.   
  82.             <LinearLayout  
  83.                 android:layout_width="match_parent"  
  84.                 android:layout_height="wrap_content"  
  85.                 android:layout_centerVertical="true"  
  86.                 android:orientation="vertical" >  
  87.   
  88.                 <ImageView  
  89.                     android:id="@+id/news_image"  
  90.                     android:layout_width="wrap_content"  
  91.                     android:layout_height="wrap_content"  
  92.                     android:layout_gravity="center_horizontal"  
  93.                     android:src="@drawable/news_unselected" />  
  94.   
  95.                 <TextView  
  96.                     android:id="@+id/news_text"  
  97.                     android:layout_width="wrap_content"  
  98.                     android:layout_height="wrap_content"  
  99.                     android:layout_gravity="center_horizontal"  
  100.                     android:text="动态"  
  101.                     android:textColor="#82858b" />  
  102.             </LinearLayout>  
  103.         </RelativeLayout>  
  104.   
  105.         <RelativeLayout  
  106.             android:id="@+id/setting_layout"  
  107.             android:layout_width="0dp"  
  108.             android:layout_height="match_parent"  
  109.             android:layout_weight="1" >  
  110.   
  111.             <LinearLayout  
  112.                 android:layout_width="match_parent"  
  113.                 android:layout_height="wrap_content"  
  114.                 android:layout_centerVertical="true"  
  115.                 android:orientation="vertical" >  
  116.   
  117.                 <ImageView  
  118.                     android:id="@+id/setting_image"  
  119.                     android:layout_width="wrap_content"  
  120.                     android:layout_height="wrap_content"  
  121.                     android:layout_gravity="center_horizontal"  
  122.                     android:src="@drawable/setting_unselected" />  
  123.   
  124.                 <TextView  
  125.                     android:id="@+id/setting_text"  
  126.                     android:layout_width="wrap_content"  
  127.                     android:layout_height="wrap_content"  
  128.                     android:layout_gravity="center_horizontal"  
  129.                     android:text="设置"  
  130.                     android:textColor="#82858b" />  
  131.             </LinearLayout>  
  132.         </RelativeLayout>  
  133.     </LinearLayout>  
  134.   
  135. </LinearLayout>  

这段布局代码虽然有点长,但其实主要就分为两部分。第一个部分就是FrameLayout,这里只是给FrameLayout的id设置成content,并没有在里面添加任何具体的内容,因为具体的内容是要在后面动态进行添加的。第二个部分就是FrameLayout下面的LinearLayout,这个LinearLayout中包含的就是整个类似于TabHost的布局。可以看到,我们将这个LinearLayout又等分成了四份,每一份中都会显示一个ImageView和一个TextView。ImageView用于显示当前Tab的图标,TextView用于显示当前Tab的标题,这个效果就会和QQ非常得类似。

既然是等分成了四分,那接下来我们自然要去分别实现四个Fragment和它们的布局了。新建一个message_layout.xml作为消息界面的布局,代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <LinearLayout  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"  
  9.         android:layout_centerInParent="true"  
  10.         android:orientation="vertical" >  
  11.   
  12.         <ImageView  
  13.             android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content"  
  15.             android:layout_gravity="center_horizontal"  
  16.             android:src="@drawable/message_selected" />  
  17.   
  18.         <TextView  
  19.             android:layout_width="wrap_content"  
  20.             android:layout_height="wrap_content"  
  21.             android:layout_gravity="center_horizontal"  
  22.             android:padding="10dp"  
  23.             android:text="这是消息界面"  
  24.             android:textSize="20sp" />  
  25.     </LinearLayout>  
  26.   
  27. </RelativeLayout>  

这个布局就相对简单多了,只是在屏幕的正中央显示一个消息图标,以及一段文字。

然后要去创建对应这个布局的Fragment。新建MessageFragment继承自Fragment,代码如下所示:

  1. public class MessageFragment extends Fragment {  
  2.   
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  4.             Bundle savedInstanceState) {  
  5.         View messageLayout = inflater.inflate(R.layout.message_layout, container, false);  
  6.         return messageLayout;  
  7.     }  
  8.   
  9. }  

后面就是依葫芦画瓢,把其它几个Fragment以及对应的布局创建出来。新建contacts_layout.xml作为联系人界面的布局,代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <LinearLayout  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"  
  9.         android:layout_centerInParent="true"  
  10.         android:orientation="vertical" >  
  11.   
  12.         <ImageView  
  13.             android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content"  
  15.             android:layout_gravity="center_horizontal"  
  16.             android:src="@drawable/contacts_selected" />  
  17.   
  18.         <TextView  
  19.             android:layout_width="wrap_content"  
  20.             android:layout_height="wrap_content"  
  21.             android:layout_gravity="center_horizontal"  
  22.             android:padding="10dp"  
  23.             android:text="这是联系人界面"  
  24.             android:textSize="20sp" />  
  25.     </LinearLayout>  
  26.   
  27. </RelativeLayout>  

再新建ContactsFragment继承自Fragment,代码如下所示:

  1. public class ContactsFragment extends Fragment {  
  2.   
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.             Bundle savedInstanceState) {  
  6.         View contactsLayout = inflater.inflate(R.layout.contacts_layout,  
  7.                 container, false);  
  8.         return contactsLayout;  
  9.     }  
  10.   
  11. }  

然后新建news_layout.xml作为动态界面的布局,代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <LinearLayout  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"  
  9.         android:layout_centerInParent="true"  
  10.         android:orientation="vertical" >  
  11.   
  12.         <ImageView  
  13.             android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content"  
  15.             android:layout_gravity="center_horizontal"  
  16.             android:src="@drawable/news_selected" />  
  17.   
  18.         <TextView  
  19.             android:layout_width="wrap_content"  
  20.             android:layout_height="wrap_content"  
  21.             android:layout_gravity="center_horizontal"  
  22.             android:padding="10dp"  
  23.             android:text="这是动态界面"  
  24.             android:textSize="20sp" />  
  25.     </LinearLayout>  
  26.   
  27. </RelativeLayout>  

再新建NewsFragment继承自Fragment,代码如下所示:

  1. public class NewsFragment extends Fragment {  
  2.   
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.             Bundle savedInstanceState) {  
  6.         View newsLayout = inflater.inflate(R.layout.news_layout, container,  
  7.                 false);  
  8.         return newsLayout;  
  9.     }  
  10.   
  11. }  

最后新建setting_layout.xml作为设置界面的布局,代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <LinearLayout  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"  
  9.         android:layout_centerInParent="true"  
  10.         android:orientation="vertical" >  
  11.   
  12.         <ImageView  
  13.             android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content"  
  15.             android:layout_gravity="center_horizontal"  
  16.             android:src="@drawable/setting_selected" />  
  17.   
  18.         <TextView  
  19.             android:layout_width="wrap_content"  
  20.             android:layout_height="wrap_content"  
  21.             android:layout_gravity="center_horizontal"  
  22.             android:padding="10dp"  
  23.             android:text="这是设置界面"  
  24.             android:textSize="20sp" />  
  25.     </LinearLayout>  
  26.   
  27. </RelativeLayout>  

再新建SettingFragment继承自Fragment,代码如下所示:

  1. public class SettingFragment extends Fragment {  
  2.   
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.             Bundle savedInstanceState) {  
  6.         View settingLayout = inflater.inflate(R.layout.setting_layout,  
  7.                 container, false);  
  8.         return settingLayout;  
  9.     }  
  10.   
  11. }  

这样我们就把每一个Fragment,以及它们所对应的布局文件都创建好了。接下来也就是最关键的步骤了,打开或新建MainActivity作为主Activity,代码如下所示:

  1. /** 
  2.  * 项目的主Activity,所有的Fragment都嵌入在这里。 
  3.  *  
  4.  * @author guolin 
  5.  */  
  6. public class MainActivity extends Activity implements OnClickListener {  
  7.   
  8.     /** 
  9.      * 用于展示消息的Fragment 
  10.      */  
  11.     private MessageFragment messageFragment;  
  12.   
  13.     /** 
  14.      * 用于展示联系人的Fragment 
  15.      */  
  16.     private ContactsFragment contactsFragment;  
  17.   
  18.     /** 
  19.      * 用于展示动态的Fragment 
  20.      */  
  21.     private NewsFragment newsFragment;  
  22.   
  23.     /** 
  24.      * 用于展示设置的Fragment 
  25.      */  
  26.     private SettingFragment settingFragment;  
  27.   
  28.     /** 
  29.      * 消息界面布局 
  30.      */  
  31.     private View messageLayout;  
  32.   
  33.     /** 
  34.      * 联系人界面布局 
  35.      */  
  36.     private View contactsLayout;  
  37.   
  38.     /** 
  39.      * 动态界面布局 
  40.      */  
  41.     private View newsLayout;  
  42.   
  43.     /** 
  44.      * 设置界面布局 
  45.      */  
  46.     private View settingLayout;  
  47.   
  48.     /** 
  49.      * 在Tab布局上显示消息图标的控件 
  50.      */  
  51.     private ImageView messageImage;  
  52.   
  53.     /** 
  54.      * 在Tab布局上显示联系人图标的控件 
  55.      */  
  56.     private ImageView contactsImage;  
  57.   
  58.     /** 
  59.      * 在Tab布局上显示动态图标的控件 
  60.      */  
  61.     private ImageView newsImage;  
  62.   
  63.     /** 
  64.      * 在Tab布局上显示设置图标的控件 
  65.      */  
  66.     private ImageView settingImage;  
  67.   
  68.     /** 
  69.      * 在Tab布局上显示消息标题的控件 
  70.      */  
  71.     private TextView messageText;  
  72.   
  73.     /** 
  74.      * 在Tab布局上显示联系人标题的控件 
  75.      */  
  76.     private TextView contactsText;  
  77.   
  78.     /** 
  79.      * 在Tab布局上显示动态标题的控件 
  80.      */  
  81.     private TextView newsText;  
  82.   
  83.     /** 
  84.      * 在Tab布局上显示设置标题的控件 
  85.      */  
  86.     private TextView settingText;  
  87.   
  88.     /** 
  89.      * 用于对Fragment进行管理 
  90.      */  
  91.     private FragmentManager fragmentManager;  
  92.   
  93.     @Override  
  94.     protected void onCreate(Bundle savedInstanceState) {  
  95.         super.onCreate(savedInstanceState);  
  96.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  97.         setContentView(R.layout.activity_main);  
  98.         // 初始化布局元素  
  99.         initViews();  
  100.         fragmentManager = getFragmentManager();  
  101.         // 第一次启动时选中第0个tab  
  102.         setTabSelection(0);  
  103.     }  
  104.   
  105.     /** 
  106.      * 在这里获取到每个需要用到的控件的实例,并给它们设置好必要的点击事件。 
  107.      */  
  108.     private void initViews() {  
  109.         messageLayout = findViewById(R.id.message_layout);  
  110.         contactsLayout = findViewById(R.id.contacts_layout);  
  111.         newsLayout = findViewById(R.id.news_layout);  
  112.         settingLayout = findViewById(R.id.setting_layout);  
  113.         messageImage = (ImageView) findViewById(R.id.message_image);  
  114.         contactsImage = (ImageView) findViewById(R.id.contacts_image);  
  115.         newsImage = (ImageView) findViewById(R.id.news_image);  
  116.         settingImage = (ImageView) findViewById(R.id.setting_image);  
  117.         messageText = (TextView) findViewById(R.id.message_text);  
  118.         contactsText = (TextView) findViewById(R.id.contacts_text);  
  119.         newsText = (TextView) findViewById(R.id.news_text);  
  120.         settingText = (TextView) findViewById(R.id.setting_text);  
  121.         messageLayout.setOnClickListener(this);  
  122.         contactsLayout.setOnClickListener(this);  
  123.         newsLayout.setOnClickListener(this);  
  124.         settingLayout.setOnClickListener(this);  
  125.     }  
  126.   
  127.     @Override  
  128.     public void onClick(View v) {  
  129.         switch (v.getId()) {  
  130.         case R.id.message_layout:  
  131.             // 当点击了消息tab时,选中第1个tab  
  132.             setTabSelection(0);  
  133.             break;  
  134.         case R.id.contacts_layout:  
  135.             // 当点击了联系人tab时,选中第2个tab  
  136.             setTabSelection(1);  
  137.             break;  
  138.         case R.id.news_layout:  
  139.             // 当点击了动态tab时,选中第3个tab  
  140.             setTabSelection(2);  
  141.             break;  
  142.         case R.id.setting_layout:  
  143.             // 当点击了设置tab时,选中第4个tab  
  144.             setTabSelection(3);  
  145.             break;  
  146.         default:  
  147.             break;  
  148.         }  
  149.     }  
  150.   
  151.     /** 
  152.      * 根据传入的index参数来设置选中的tab页。 
  153.      *  
  154.      * @param index 
  155.      *            每个tab页对应的下标。0表示消息,1表示联系人,2表示动态,3表示设置。 
  156.      */  
  157.     private void setTabSelection(int index) {  
  158.         // 每次选中之前先清楚掉上次的选中状态  
  159.         clearSelection();  
  160.         // 开启一个Fragment事务  
  161.         FragmentTransaction transaction = fragmentManager.beginTransaction();  
  162.         // 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况  
  163.         hideFragments(transaction);  
  164.         switch (index) {  
  165.         case 0:  
  166.             // 当点击了消息tab时,改变控件的图片和文字颜色  
  167.             messageImage.setImageResource(R.drawable.message_selected);  
  168.             messageText.setTextColor(Color.WHITE);  
  169.             if (messageFragment == null) {  
  170.                 // 如果MessageFragment为空,则创建一个并添加到界面上  
  171.                 messageFragment = new MessageFragment();  
  172.                 transaction.add(R.id.content, messageFragment);  
  173.             } else {  
  174.                 // 如果MessageFragment不为空,则直接将它显示出来  
  175.                 transaction.show(messageFragment);  
  176.             }  
  177.             break;  
  178.         case 1:  
  179.             // 当点击了联系人tab时,改变控件的图片和文字颜色  
  180.             contactsImage.setImageResource(R.drawable.contacts_selected);  
  181.             contactsText.setTextColor(Color.WHITE);  
  182.             if (contactsFragment == null) {  
  183.                 // 如果ContactsFragment为空,则创建一个并添加到界面上  
  184.                 contactsFragment = new ContactsFragment();  
  185.                 transaction.add(R.id.content, contactsFragment);  
  186.             } else {  
  187.                 // 如果ContactsFragment不为空,则直接将它显示出来  
  188.                 transaction.show(contactsFragment);  
  189.             }  
  190.             break;  
  191.         case 2:  
  192.             // 当点击了动态tab时,改变控件的图片和文字颜色  
  193.             newsImage.setImageResource(R.drawable.news_selected);  
  194.             newsText.setTextColor(Color.WHITE);  
  195.             if (newsFragment == null) {  
  196.                 // 如果NewsFragment为空,则创建一个并添加到界面上  
  197.                 newsFragment = new NewsFragment();  
  198.                 transaction.add(R.id.content, newsFragment);  
  199.             } else {  
  200.                 // 如果NewsFragment不为空,则直接将它显示出来  
  201.                 transaction.show(newsFragment);  
  202.             }  
  203.             break;  
  204.         case 3:  
  205.         default:  
  206.             // 当点击了设置tab时,改变控件的图片和文字颜色  
  207.             settingImage.setImageResource(R.drawable.setting_selected);  
  208.             settingText.setTextColor(Color.WHITE);  
  209.             if (settingFragment == null) {  
  210.                 // 如果SettingFragment为空,则创建一个并添加到界面上  
  211.                 settingFragment = new SettingFragment();  
  212.                 transaction.add(R.id.content, settingFragment);  
  213.             } else {  
  214.                 // 如果SettingFragment不为空,则直接将它显示出来  
  215.                 transaction.show(settingFragment);  
  216.             }  
  217.             break;  
  218.         }  
  219.         transaction.commit();  
  220.     }  
  221.   
  222.     /** 
  223.      * 清除掉所有的选中状态。 
  224.      */  
  225.     private void clearSelection() {  
  226.         messageImage.setImageResource(R.drawable.message_unselected);  
  227.         messageText.setTextColor(Color.parseColor("#82858b"));  
  228.         contactsImage.setImageResource(R.drawable.contacts_unselected);  
  229.         contactsText.setTextColor(Color.parseColor("#82858b"));  
  230.         newsImage.setImageResource(R.drawable.news_unselected);  
  231.         newsText.setTextColor(Color.parseColor("#82858b"));  
  232.         settingImage.setImageResource(R.drawable.setting_unselected);  
  233.         settingText.setTextColor(Color.parseColor("#82858b"));  
  234.     }  
  235.   
  236.     /** 
  237.      * 将所有的Fragment都置为隐藏状态。 
  238.      *  
  239.      * @param transaction 
  240.      *            用于对Fragment执行操作的事务 
  241.      */  
  242.     private void hideFragments(FragmentTransaction transaction) {  
  243.         if (messageFragment != null) {  
  244.             transaction.hide(messageFragment);  
  245.         }  
  246.         if (contactsFragment != null) {  
  247.             transaction.hide(contactsFragment);  
  248.         }  
  249.         if (newsFragment != null) {  
  250.             transaction.hide(newsFragment);  
  251.         }  
  252.         if (settingFragment != null) {  
  253.             transaction.hide(settingFragment);  
  254.         }  
  255.     }  
  256. }  

这个类中的注释已经写得非常详细了,下面我再带大家简单梳理一遍。在onCreate()方法中先是调用了initViews()来获取每个控件的实例,并给相应的控件设置好点击事件,然后调用setTabSelection()方法设置默认的选中项,这里传入的0说明默认选中第1个Tab项。

那么setTabSelection()方法中又是如何处理的呢?可以看到,首先第一步是调用clearSelection()方法来清理掉之前的选中状态,然后开启一个Fragment事务,并隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上。接下来根据传入的index参数判断出选中的是哪一个Tab项,并改变该Tab项的图标和文字颜色,然后将相应的Fragment添加到界面上。这里注意一个细节,我们添加Fragment的时候并没有使用replace()方法,而是会先判断一下该Fragment是否为空,如果是空的则调用add()方法添加一个进来,如果不是空的则直接调用show()方法显示出来即可。那么为什么没有使用replace()方法呢?这是因为replace()方法会将被替换掉的那个Fragment彻底地移除掉,该Fragment的生命周期就结束了。当再次点击刚才那个Tab项的时候,就会让该Fragment的生命周期重新开始,onCreate()、onCreateView()等方法都会重新执行一遍。这显然不是我们想要的,也和ActivityGroup的工作原理不符,因此最好的解决方案就是使用hide()和show()方法来隐藏和显示Fragment,这就不会让Fragment的生命周期重走一遍了。

设置完默认选中项后,我们当然还可以通过点击Tab项来自由地切换界面,这就会进入到onClick()方法中。onClick()方法中的逻辑判断非常简单,当点击了消息标签时就会选中第1个tab项,点击联系人标签时就会选中第2个tab项,点击动态标签时就会选中第3个tab项,点击设置标签时就会选中第4个tab项。都是通过调用setTabSelection()方法来完成的,只是传入了不同的参数。

好了,这样我们就将全部的代码都编写完成了,下面就来运行一下吧。整个Tab的界面有点类似于QQ的感觉,并且可以通过点击不同的Tab来切换界面,如下图所示:

                                                   

另外,这个Tab界面即使在横屏的情况下也有不错的适用性哦,如下图所示:

                            

这样,我们就成功使用Fragment编写出了和TabHost一样的效果。每个界面的具体逻辑就可以写在相应的Fragment里,效果和之前写在Activity里是差不多的。如此一来,我们终于可以和那个被废弃的ActivityGroup说再见了!

 

Android实现下拉刷新、上拉加载功能

时间:2016-9-12   作者:   分类: Android   热度:96°  评论:0  
时间:2016-9-12   分类: Android    热度:96   评论:0

实现下拉刷新和上拉加载的功能,先看看实现后的效果图 


1.png2.png3.png4.png5.png

 源码地址:http://pan.baidu.com/s/1eR3xQD0

 

ListView的头布局和脚布局:

头布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:paddingBottom="15dp"
                android:paddingTop="10dp">
    <!--圆形进度条-->
    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/pull_to_refresh_progress"
        style="@android:style/Widget.ProgressBar.Small"
        android:layout_centerVertical="true"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:indeterminate="false"
        android:visibility="gone"/>
    <!-- 箭头图标-->
    <ImageView
        android:id="@+id/pull_to_refresh_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="20dp"
        android:src="@drawable/ic_pulltorefresh_arrow"
        android:visibility="visible"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/pull_to_refresh_text"
        android:gravity="center"
        android:layout_gravity="center"
        android:paddingTop="5dp"
        android:text="下拉可刷新!"
        android:layout_marginTop="18dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/pull_to_refresh_updated_at"
        android:layout_below="@id/pull_to_refresh_text"
        android:gravity="center"
        android:layout_gravity="center"
        android:paddingTop="5dp"
        android:textAppearance="?android:attr/textAppearanceSmall"
       android:visibility="gone"/>
</RelativeLayout>



<p style="text-indent:2em;">
 <br />
<p>
 &nbsp;
</p>
</p>
<p style="text-indent:2em;">
 <strong><span style="font-size:14px;">脚布局:</span></strong> 
</p>
<p style="text-indent:2em;">
 <strong></strong>&nbsp;
</p>
<p style="text-indent:2em;">
 <strong></strong>&nbsp;
</p>
<p>
 <strong>
</p>
<p style="text-indent:2em;">
 <p style="text-indent:2em;">
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:paddingBottom="15dp"
                android:paddingTop="10dp">
    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/loadmode_progress"
        style="@android:style/Widget.ProgressBar.Small"
        android:layout_centerVertical="true"
        android:layout_marginLeft="60dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:indeterminate="true"
        android:visibility="visible"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/loadmode_text"
        android:gravity="center"
        android:layout_gravity="center"
        android:paddingTop="5dp"
        android:text="@string/loadmore_label"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textStyle="bold"/>
</RelativeLayout>
自定义Item视图:
 
<p>
 <span style="font-size:14px;"></span>
</p>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal"
        android:text="我是List"
        android:id="@+id/name"
        android:textSize="20dp"/>
</LinearLayout>
主视图:
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.learn.listviewrefresh.MainActivity">
    <com.learn.listviewrefresh.PullToRefreshListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/wibolist"
        android:fastScrollEnabled="true"
        android:cacheColorHint="#000000"/>
</LinearLayout>
    

 

自定义ListView:

 

/**
 * 自定义ListView
 */
public class PullToRefreshListView extends ListView implements AbsListView.OnScrollListener {
    /**
     * 当前的操作状态为——正常状态
     */
    private static final int NORMAL = 0;
    /**
     * 当前的操作状态为——提示下拉可以刷新的状态
     */
    private static final int PULL = 1;
    /**
     * 当前的操作状态为——松开可以刷新的状态
     */
    private static final int RELEASE = 2;
    /**
     * 当前的操作状态为——正在刷新状态
     */
    private static final int REFRESHING = 3;
    private OnScrollListener mOnScrollListener;         //列表滚动监听器
    private LayoutInflater mLayoutInflater;                 //用于加载布局文件
    private RelativeLayout mRefreshHeaderView; //刷新视图(顶部刷新动画)
    private TextView mRefreshHeaderText; //刷新顶部文字
    private ImageView mRefreshHeaderImage; //刷新顶部箭头
    private ProgressBar mRefreshHeaderProgerss;//刷新顶部进度条
    private RelativeLayout mLoadMoreFooterView; //加载更多
    private TextView mTextLoadMore;//提示文本
    private ProgressBar mLoadMoreProgress;//加载更多进度条
    private int mRefreshViewHeight;                            // 刷新视图高度
    int totalItemCount;// 总数量;
    int lastVisibleItem;// 最后一个可见的item;
    boolean isLoading;// 正在加载;
    /**
     * ListView当前滚动状态
     */
    private int scrollState = 0;
    /**
     * ListView当前屏幕可见的第一个item的位置
     */
    private int firstVisibleItem = 0;
    /**
     * 标识是否是在ListView的首个item出现在屏幕最顶端时手指按下
     */
    private boolean isRemark = false;
    /**
     * 当前屏幕中,ListViwe显示的第一个item是首个item时,手指按下时的Y轴坐标
     */
    private int startY = 0;
    /**
     * 当前的操作状态
     */
    private int currentState = 0;
    /**
     * 数据刷新接口
     */
    IReflashListener iReflashListener;//刷新数据的接口
    public PullToRefreshListView(Context context) {
        super(context);
        init(context);
    }
    public PullToRefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    public PullToRefreshListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }
    //初始化布局
    private void init(Context context) {
        // 获取LayoutInflater实例对象
        mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mRefreshHeaderView = (RelativeLayout) mLayoutInflater.inflate(R.layout.pull_to_refresh_header, this, false);
        //绑定控件
        mLoadMoreFooterView = (RelativeLayout) mLayoutInflater.inflate(R.layout.loadmore_footer, this, false);
        mTextLoadMore = (TextView) mLoadMoreFooterView.findViewById(R.id.loadmode_text);
        mLoadMoreProgress = (ProgressBar) mLoadMoreFooterView.findViewById(R.id.loadmode_progress);
            //设置底部视图不可见
        mLoadMoreFooterView.setVisibility(GONE);
        measureView(mRefreshHeaderView);
        mRefreshViewHeight = mRefreshHeaderView.getMeasuredHeight(); //得到视图的高度
        paddingTop(-mRefreshViewHeight);
        addHeaderView(mRefreshHeaderView);  //增加头部视图
        addFooterView(mLoadMoreFooterView); //增加顶部视图
        super.setOnScrollListener(this); //滑屏分页显示数据
    }
    public void setOnScrollListener(AbsListView.OnScrollListener l) {
        mOnScrollListener = l;
    }
    //触摸事件
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:  //手指按下
                if (0 == firstVisibleItem) {
                    isRemark = true;
                    startY = (int) event.getY();
                    Log.v("手指按下", "手指按下" + startY);
                }
                break;
            case MotionEvent.ACTION_MOVE:  ////手指移动
                onMove(event);
                break;
            case MotionEvent.ACTION_UP:   //手指抬起
                if (currentState == RELEASE) { // 提示“松开可以刷新”,那么就刷新数据
                    currentState = REFRESHING;
                    refreshListViewByCurrentState();
                    if (iReflashListener != null) {
                        iReflashListener.onRefresh();
                    }
                } else if (currentState == PULL) { // 提示“下拉可以刷新”,那么就复位
                    currentState = NORMAL;
                    isRemark = false;
                    refreshListViewByCurrentState();
                }
                break;
        }
        return super.onTouchEvent(event);
    }
    /**
     * 根据当前状态,来改变界面显示
     */
    private void refreshListViewByCurrentState() {
        // 加载下拉刷新的头部视图  绑定控件
        mRefreshHeaderImage = (ImageView) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_image);
        mRefreshHeaderProgerss = (ProgressBar) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_progress);
        mRefreshHeaderText = (TextView) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_text);
        // 箭头从上到下旋转180度的动画
        RotateAnimation upTodown = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        upTodown.setDuration(500);
        upTodown.setFillAfter(true);
        // 箭头从下到上旋转180度的动画
        RotateAnimation downToup = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        downToup.setDuration(500);
        downToup.setFillAfter(true);
        switch (currentState) {
            case NORMAL:
                mRefreshHeaderImage.clearAnimation();
                paddingTop(-mRefreshViewHeight);
                break;
            case PULL:
                mRefreshHeaderImage.setVisibility(View.VISIBLE);
                mRefreshHeaderText.setText("下拉可以刷新");
                mRefreshHeaderImage.clearAnimation();
                mRefreshHeaderImage.startAnimation(downToup);
                break;
            case RELEASE:
                mRefreshHeaderImage.setVisibility(View.VISIBLE);
                mRefreshHeaderProgerss.setVisibility(View.GONE);
                mRefreshHeaderText.setText("松开可以刷新");
                mRefreshHeaderImage.clearAnimation();
                mRefreshHeaderImage.startAnimation(upTodown);
                break;
            case REFRESHING:
                paddingTop(50);
                mRefreshHeaderImage.setVisibility(View.GONE);
                mRefreshHeaderProgerss.setVisibility(View.VISIBLE);
                mRefreshHeaderText.setText("刷新中...");
                mRefreshHeaderImage.clearAnimation();
                break;
        }
    }
    //判断移动过程
    private void onMove(MotionEvent event) {
        if (!isRemark) {
            return;
             /*
             * 如果不是手指在ListView的首个item出现在顶部时按下,并滑动的操作,
             * 说明用户不是在做下拉刷新的操作,那么就不需要做任何操作,方法直接放回
             */
        }
        int currentY = (int) event.getY(); // 当前手指移动到哪个位置
        int space = currentY - startY;    // 移动的距离是多少
        int paddingTop = space - mRefreshViewHeight;
        switch (currentState) {
            case NORMAL:
                if (space > 0) {
                    currentState = PULL;
                    refreshListViewByCurrentState();
                }
                break;
            case PULL:
                paddingTop(paddingTop);
                if (space - mRefreshViewHeight > 30
                        && scrollState == SCROLL_STATE_TOUCH_SCROLL) { // 移动距离大于一定高度,并且正在滚动
                    currentState = RELEASE;
                    refreshListViewByCurrentState();
                }
                break;
            case RELEASE:
                paddingTop(paddingTop);
                if (space - mRefreshViewHeight < 30) { // 如果小于一定的高度
                    currentState = PULL;
                    refreshListViewByCurrentState();
                }
                break;
        }
    }
    //获取视图大小
    private void measureView(View child) {
        ViewGroup.LayoutParams params = child.getLayoutParams();
        if (params == null) {
            params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int width = ViewGroup.getChildMeasureSpec(0, 0, params.width);
        int hight = 0;
        int tempHight = params.height;
        if (tempHight > 0) {
            hight = MeasureSpec.makeMeasureSpec(tempHight, MeasureSpec.EXACTLY);
        } else {
            hight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(width, hight);
    }
    /**
     * 设置顶部布局的上内边距
     */
    private void paddingTop(int paddingTop) {
        mRefreshHeaderView.setPadding(mRefreshHeaderView.getPaddingLeft(), paddingTop, getListPaddingRight(), getListPaddingBottom());
        mRefreshHeaderView.invalidate();
    }
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.scrollState = scrollState;
        if (totalItemCount == lastVisibleItem && scrollState == SCROLL_STATE_IDLE && currentState == NORMAL) {
            if (!isLoading) {
                isLoading = true;
                mLoadMoreFooterView.setVisibility(VISIBLE);
                //加载更多
                iReflashListener.onRefresh2();
            }
        }
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem; //第一个item
        this.lastVisibleItem = firstVisibleItem + visibleItemCount; //最后一个item = 第一个item + 可见的item
        this.totalItemCount = totalItemCount;
    }
    //加载完成
    public void reflashComplete() {
        currentState = NORMAL;
        isRemark = false;
        refreshListViewByCurrentState();
        isLoading = false;
        mLoadMoreFooterView.setVisibility(GONE);
    }
    public void setInterface(IReflashListener iReflashListener) {
        this.iReflashListener = iReflashListener;
    }
    /**
     * 数据刷新接口
     */
    public interface IReflashListener {
        public void onRefresh();
        public void onRefresh2();
    }
}
 <p>
   &nbsp;
  </p>
  <p>
   自定义Adapt:
  </p>
public class MyAdapter extends BaseAdapter {
    ArrayList<MyEntity> arrayList;
    LayoutInflater inflater;
    public MyAdapter(Context context,ArrayList<MyEntity> arrayList){
        this.arrayList = arrayList;
        this.inflater = LayoutInflater.from(context);
    }
    public void onDataChange(ArrayList<MyEntity> arrayList){
        this.arrayList = arrayList;
        this.notifyDataSetChanged();
    }
    @Override
    public int getCount() {
        return arrayList.size();
    }
    @Override
    public Object getItem(int position) {
        return arrayList.get(position);
    }
    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        MyEntity entity = arrayList.get(position);
        ViewHolder holder;
        if (convertView==null){
            holder=new ViewHolder();
            convertView = inflater.inflate(R.layout.item_layout,null);
            holder.name = (TextView) convertView.findViewById(R.id.name);
            convertView.setTag(holder);
        }else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.name.setText(entity.getName());
        return convertView;
    }
    class ViewHolder{
        TextView name;
    }
}
 <p>
   &nbsp;
  </p>
  <p>
   &nbsp;
  </p>
MyEntity.java
public class MyEntity {
    private String name;
    private String des;
    private String info;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDes() {
        return des;
    }
    public void setDes(String des) {
        this.des = des;
    }
    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
}
 
 MainActivity.java
public class MainActivity extends Activity implements PullToRefreshListView.IReflashListener {
    ArrayList<MyEntity> arrayList = new ArrayList<MyEntity>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getData();
        showList(arrayList);
    }
    MyAdapter adapter;
    PullToRefreshListView listView;
    private void showList(ArrayList<MyEntity> arrayList) {
        if (adapter == null) {
            listView = (PullToRefreshListView) findViewById(R.id.wibolist);
            listView.setInterface(this);
            adapter = new MyAdapter(this, arrayList);
            listView.setAdapter(adapter);
        } else {
            adapter.onDataChange(arrayList);
        }
    }
    private void getData() {
        for (int i = 0; i < 10; i++) {
            MyEntity entity = new MyEntity();
            entity.setName("数据");
            arrayList.add(entity);
        }
    }
    private void RefreshMoreData() {
        for (int i = 0; i < 2; i++) {
            MyEntity entity = new MyEntity();
            entity.setName("刷新的数据");
            arrayList.add(0,entity);
        }
    }
    private void LoadMoreData() {
        for (int i = 0; i < 2; i++) {
            MyEntity entity = new MyEntity();
            entity.setName("加载更多的数据");
            arrayList.add(entity);
        }
    }
    public void onLoad() {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //加载更多数据
                RefreshMoreData();
                //更新ListView
                showList(arrayList);
                //通知ListView加载完成
                listView.reflashComplete();
            }
        }, 2000);
    }
    public void onLoadNext() {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //加载更多数据
                LoadMoreData();
                //更新ListView
                showList(arrayList);
                //通知ListView加载完成
                listView.reflashComplete();
            }
        }, 2000);
    }
    @Override
    public void onRefresh() {
        onLoad();
        showList(arrayList);
    }
    @Override
    public void onRefresh2() {
        onLoadNext();
        showList(arrayList);
    }
}
 
 
<p>
 <br />
</p>

<p>
 <br />
</p>
 
 <p>
   <br />
  </p>
  <p style="text-indent:2em;">
   <br />
  </p>
  <p style="text-indent:2em;">
   </strong>
  </p>
  <p>
   </strong>
  </p>
  <p style="text-indent:2em;">
   <br />
<p>
 &nbsp;
</p>
 </p>

Android EditText 属性汇总

时间:2016-9-6   作者:   分类: Android   热度:209°  评论:0  
时间:2016-9-6   分类: Android    热度:209   评论:0

标签:
1.EditText输入限制规则
在xml:EditText 设置属性
android:digits="ABCDE123&*"
ABCDE123&*是你的限制规则
例如:android:digits="0123456789abc"
规则是只能输入英文字母(小写)abc和数字
2.EditTex输入的文字为密码形式
(1)在xml中设置
android:password="true" //以"."形式显示文本
(2)在代码里设置
通过设置EditTex的setTransformationMethod()方法来实现隐藏密码和显示密码
editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
//设置密码不可见
3.EditTex输入的文字为电话号码
android:phoneNumber="true"//输入电话号码
4.EditTex字数限制
(1)在xml中设置
android:maxLength="50"
(2)在代码中设置
editText.setFilters(new InputFilter[]{newInputFilter.LengthFilter(100)});
5.EditTex是否可编辑
android:editable="true"//可编辑,false不可编辑
6.在EditText中软键盘的调起、关闭
(1)EditTex有焦点(focusable为true)阻止输入法弹出
editText.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View view,MotionEvent event){
editText.setInputType(Input.TYPE_NULL);//关闭软键盘
return false;
}});
(2)EditText无焦点(focusable=false)时阻挡输入法弹出
InputMethodManager imm=(InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(),0);
(3)调用数字键盘并设置输入类型和键盘为英文
editText.setInputType(InputType.TYPE_CLASS_NUMBER);//调用数字键盘
editText.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);//英文
(4)键盘永远不会弹出
android:focusable="false"// 键盘永不弹出
7.软键盘的调起导致原来的界面被挤上去,或者导致界面下面的tab导航被挤上去,解决方法如下
使用Mainfest中的Activity的android:windowSfotInputMdoe的“adjustPan"属性
另外注意:有关软键盘的问题可参考android:windowSoftInputMode中的属性
8.光标详解
editText.requestFocusFromTouch();//让光标放入到点击位置
editText.requestFocus();//默认方式获得焦点
editText editor=(EditText)getCurrentView();//光标插入
int cursor=editor.getSelectionStart();//光标插入
editor.getText().inset(cursor,delta);
 
Android EditText 属性汇总
android:layout_gravity="center_vertical" 设置控件显示的位置:默认top,这里居中显示,还有bottom android:hint="请输入数字!"
设置显示在空间上的提示信息 android:numeric="integer" 设置只能输入整数,如果是小数则是:
decimal android:singleLine="true" 设置单行输入,一旦设置为true,则文字不会自动换行。
android:password="true" 设置只能输入密码
android:textColor = "#ff8c00" 字体颜色
android:textStyle="bold" 字体,bold, italic, bolditalic android:textSize="20dip" 大小
android:capitalize = "characters" 以大写字母写
android:textAlign="center" EditText没有这个属性,但TextView有 android:textColorHighlight="#cccccc" 被选中文字的底色,默认为蓝色
android:textColorHint="#ffff00" 设置提示信息文字的颜色,默认为灰色 android:textScaleX="1.5" 控制字与字之间的间距
android:typeface="monospace" 字型,normal, sans, serif, monospace android:background="@null" 空间背景,这里没有,指透明
android:layout_weight="1" 权重,控制控件之间的地位,在控制控件显示的大小时蛮有用的。
android:textAppearance="?android:attr/textAppearanceLargeInverse" 文字外观,这里引用的是系统自带的一个外观,?表示系统是否有这种外观,否则使用默认的外观。不知道这样理解对不对? 通过EditText的layout xml文件中的相关属性来实现:
1. 密码框属性 android:password="true" 这条可以让EditText显示的内容自动为星号,输入时内容会在1秒内变成*字样。
2. 纯数字 android:numeric="true" 这条可以让输入法自动变为数字输入键盘,同时仅允许0-9的数字输入
3. 仅允许 android:capitalize="cwj1987" 这样仅允许接受输入cwj1987,一般用于密码验证 下面是一些扩展的风格属性
android:editable="false" 设置EditText不可编辑
android:singleLine="true" 强制输入的内容在单行
android:ellipsize="end" 自动隐藏尾部溢出数据,一般用于文字内容过长一行无法全部显示时

Android键盘显示与隐藏

时间:2016-9-6   作者:   分类: Android   热度:120°  评论:0  
时间:2016-9-6   分类: Android    热度:120   评论:0
activity 按钮隐藏输入法键盘
InputMethodManager inputMethodManager = 
(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(numberPicker.getWindowToken(), 0);
在Fragment中,隐藏或关闭软键盘(虚拟键盘)的方法
/隐藏虚拟键盘
      public static void HideKeyboard(View v)
      {
          InputMethodManager imm = ( InputMethodManager ) v.getContext( ).getSystemService( Context.INPUT_METHOD_SERVICE );     
        if ( imm.isActive( ) ) {     
            imm.hideSoftInputFromWindow( v.getApplicationWindowToken( ) , 0 );   
            
        }    
      }

imageViewer-JAVA一个简单的图片查看

时间:2016-9-2   作者:   分类: Java   热度:122°  评论:0  
时间:2016-9-2   分类: Java    热度:122   评论:0

一个简单的图片查看

 

ImageViewer_01.pngImageViewer_02.pngImageViewer_03.png

package imageViewer;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.naming.event.EventDirContext;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class ImageViewer {
 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   
   @Override
   public void run() {
    JFrame frame = (JFrame) new ImageViewerFrame();
    frame.setTitle("图片查看");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    
   }
  });

 }

}
class ImageViewerFrame extends JFrame {
 private JLabel lable;
 private JFileChooser chooser;
 private static final int DELAULT_WIDTH = 300;
 private static final int DELAULT_HIGHT = 400;
 public ImageViewerFrame(){
  setSize(DELAULT_WIDTH,DELAULT_HIGHT);
  lable = new JLabel();
  add(lable);
  chooser = new JFileChooser();
  chooser.setCurrentDirectory(new File("."));
  
  
  
  JMenuBar menuBar= new JMenuBar();
  setJMenuBar(menuBar);
  
  JMenu menu = new JMenu("文件");
  menuBar.add(menu);
  
  JMenuItem openItem = new JMenuItem("打开");
  menu.add(openItem);
  openItem.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent event) {
    int result = chooser.showOpenDialog(null);
    
    if(result == JFileChooser.APPROVE_OPTION){
     String name = chooser.getSelectedFile().getPath();
     lable.setIcon(new ImageIcon(name));
    }
    
   }
  });
  
  JMenuItem exitItem = new JMenuItem("关闭");
  menu.add(exitItem);
  exitItem.addActionListener(new ActionListener() {
   
   @Override
   public void actionPerformed(ActionEvent event) {
    System.exit(0);
    
   }
  });
 }
}

 

部分Android手机拍照后照片被旋转的解决方案

时间:2016-8-9   作者:   分类: Android   热度:87°  评论:0  
时间:2016-8-9   分类: Android    热度:87   评论:0

在部分Android手机(如MT788、Note2)上,使用Camera拍照以后,得到的照片会被自动旋转(90°、180°、270°),这个情况很不符合预期。仔细分析了一下,因为照片属性中是存储了旋转信息的,所以要解决这个问题,可以在onActivityResult方法中,获取到照片数据后,读取它的旋转信息,如果不是0,说明这个照片已经被旋转过了,那么再使用android.graphics.Matrix将照片旋转回去即可。

1、读取图片的旋转属性

/**
 * 读取图片的旋转的角度
 *
 * @param path
 *            图片绝对路径
 * @return 图片的旋转角度
 */
private int getBitmapDegree(String path) {
    int degree = 0;
    try {
        // 从指定路径下读取图片,并获取其EXIF信息
        ExifInterface exifInterface = new ExifInterface(path);
        // 获取图片的旋转信息
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            degree = 90;
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            degree = 180;
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            degree = 270;
            break;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return degree;
}
2、将图片按照某个角度进行旋转

/**
 * 将图片按照某个角度进行旋转
 *
 * @param bm
 *            需要旋转的图片
 * @param degree
 *            旋转角度
 * @return 旋转后的图片
 */
public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
    Bitmap returnBm = null;
  
    // 根据旋转角度,生成旋转矩阵
    Matrix matrix = new Matrix();
    matrix.postRotate(degree);
    try {
        // 将原始图片按照旋转矩阵进行旋转,并得到新的图片
        returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
    } catch (OutOfMemoryError e) {
    }
    if (returnBm == null) {
        returnBm = bm;
    }
    if (bm != returnBm) {
        bm.recycle();
    }
    return returnBm;
}

返回顶部    首页    手气不错    QQ邮箱:1085911874@qq.com后花园   
版权所有:Remember    站长:                 sitemap