android项目 之 记事本(13) ----- 查看图片及播放录音
本文是自己学习所做笔记,欢迎转载。但请注明出处:http://blog.csdn.net/jesson20121020
今天就来实现下查看图片及录音的功能,在编辑或者浏览记事时,点击图片。打开一个自己定义Activity(当然了,也能够调用系统的图库来查看)来查看所加入的图片的原始图片。而不是缩放后的图片,同理,用自己定义Activity来查看录音文件。实现播放录音的功能。
上图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamVzc29uMjAxMjEwMjA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamVzc29uMjAxMjEwMjA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
从图中也能够看出,我们首先要创建两个Activity。当然了,布局文件也是少不了的。例如以下:
activity_show_picture.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
> <ImageView
android:id="@+id/iv_showPic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
/> </LinearLayout>
ShowPicture.java
public class ShowPicture extends Activity {
private ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_show_picture);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_add);
//设置标题
TextView tv_title = (TextView)findViewById(R.id.tv_title);
tv_title.setText("查看图片");
Button bt_back = (Button)findViewById(R.id.bt_back);
bt_back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
ShowPicture.this.finish();
}
});
Button bt_del = (Button)findViewById(R.id.bt_save);
bt_del.setBackgroundResource(R.drawable.paint_icon_delete);
img = (ImageView)findViewById(R.id.iv_showPic);
Intent intent = this.getIntent();
String imgPath = intent.getStringExtra("imgPath");
Bitmap bm = BitmapFactory.decodeFile(imgPath);
img.setImageBitmap(bm);
}
}
主要思想就是用ImageView来显示指定路径的图片。该路径是从前一个Activity中传入进来的。
这里的监听事件。仅仅实现了返回的功能,至于,放大缩小图片。旋转图片。下节再实现吧。activity_show_record.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_centerInParent="true"
> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:layout_margin="5dp"
>
<ImageView
android:id="@+id/iv_record_wave_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_margin="5dp"
android:background="@anim/record_wave_left"
/>
<ImageView
android:id="@+id/iv_microphone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/record_microphone_icon"
android:layout_margin="5dp"
/>
<ImageView
android:id="@+id/iv_record_wave_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_margin="5dp"
android:background="@anim/record_wave_right"
/> </LinearLayout>
<TextView
android:id="@+id/tv_recordTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#499df7"
android:textSize="20sp"
android:text="00:00:00"
android:gravity="center"
android:layout_margin="5dp"
/>
</LinearLayout> </RelativeLayout>
ShowRecord.java
public class ShowRecord extends Activity {
private String audioPath;
private int isPlaying = 0;
private AnimationDrawable ad_left,ad_right;
private Timer mTimer;
//语音操作对象
private MediaPlayer mPlayer = null;
private ImageView iv_record_wave_left,iv_record_wave_right,iv_microphone;
private TextView tv_recordTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_show_record);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_add);
//设置标题
TextView tv_title = (TextView)findViewById(R.id.tv_title);
tv_title.setText("查看录音");
Button bt_back = (Button)findViewById(R.id.bt_back);
bt_back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if(isPlaying == 1){
mPlayer.stop();
mPlayer.release();
}
ShowRecord.this.finish();
}
});
Button bt_del = (Button)findViewById(R.id.bt_save);
bt_del.setBackgroundResource(R.drawable.paint_icon_delete);
Intent intent = this.getIntent();
audioPath = intent.getStringExtra("audioPath");
iv_microphone = (ImageView)findViewById(R.id.iv_microphone);
iv_microphone.setOnClickListener(new ClickEvent());
iv_record_wave_left = (ImageView)findViewById(R.id.iv_record_wave_left);
iv_record_wave_right = (ImageView)findViewById(R.id.iv_record_wave_right);
ad_left = (AnimationDrawable)iv_record_wave_left.getBackground();
//ad_left = (AnimationDrawable)iv_record_wave_left.getDrawable();
ad_right = (AnimationDrawable)iv_record_wave_right.getBackground();
//ad_right = (AnimationDrawable)iv_record_wave_right.getDrawable();
tv_recordTime = (TextView)findViewById(R.id.tv_recordTime);
}
final Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch(msg.what){
case 1 :
String time[] = tv_recordTime.getText().toString().split(":");
int hour = Integer.parseInt(time[0]);
int minute = Integer.parseInt(time[1]);
int second = Integer.parseInt(time[2]);
if(second < 59){
second++;
}
else if(second == 59 && minute < 59){
minute++;
second = 0;
}
if(second == 59 && minute == 59 && hour < 98){
hour++;
minute = 0;
second = 0;
}
time[0] = hour + "";
time[1] = minute + "";
time[2] = second + "";
//调整格式显示到屏幕上
if(second < 10)
time[2] = "0" + second;
if(minute < 10)
time[1] = "0" + minute;
if(hour < 10)
time[0] = "0" + hour;
//显示在TextView中
tv_recordTime.setText(time[0]+":"+time[1]+":"+time[2]);
break;
}
}
};
class ClickEvent implements OnClickListener{
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//试听
if(isPlaying == 0){
isPlaying = 1;
mPlayer = new MediaPlayer();
tv_recordTime.setText("00:00:00");
mTimer = new Timer();
mPlayer.setOnCompletionListener(new MediaCompletion());
try {
mPlayer.setDataSource(audioPath);
mPlayer.prepare();
mPlayer.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mTimer.schedule(new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
}, 1000,1000);
//播放动画
ad_left.start();
ad_right.start();
}
//结束试听
else{
isPlaying = 0;
mPlayer.stop();
mPlayer.release();
mPlayer = null;
mTimer.cancel();
mTimer = null;
//停止动画
ad_left.stop();
ad_right.stop();
}
}
}
class MediaCompletion implements OnCompletionListener{
@Override
public void onCompletion(MediaPlayer mp) {
mTimer.cancel();
mTimer = null;
isPlaying = 0;
//停止动画
ad_left.stop();
ad_right.stop();
Toast.makeText(ShowRecord.this, "播放完成", Toast.LENGTH_SHORT).show();
tv_recordTime.setText("00:00:00");
}
}
}
在查看录音时,用到了对播放时间的显示处理。以及动画的播放与停止,稍有点复杂,这些在之前“加入录音”一节就就讲述了。
有了这两个Activity后,那么剩下的工作就是在单击图片或者录音的事件中启动这两个Activity就可以。但这就有一个问题,怎样在图文混排的EditText中的推断单击的是图片。录音,还是文字呢??这就须要从EditText中的识别那些是图片。那些是文字,再进一步对图片分析究竟单击的是那一个图片,从而实现查看详细图片及录音的功能,详细例如以下:
1. 记录EditText中每一个图片的位置及所在源路径
为了实如今编辑和浏览时能够随时查看原图片及录音文件,所以在每次加入图片或录音后,用一个List记住新添加的每一个图片或录音的位置及所在路径,当然了,假设是浏览已经存在于数据库中的记事时。在载入数据的同一时候,相同用ListView来记住全部的图片及录音的位置和路径。
主要代码例如以下:
//记录editText中的图片。用于单击时推断单击的是那一个图片
private List<Map<String,String>> imgList = new ArrayList<Map<String,String>>();
每次单击记事列表项。进入查看记事。在载入数据的同一时候将全部图片及录音的位置及路径记录下来。详细为在loadDate()方法中加入下面代码:
//用List记录该录音的位置及所在路径。用于单击事件
Map<String,String> map = new HashMap<String,String>();
map.put("location", m.start()+"-"+m.end());
map.put("path", path);
imgList.add(map);
同理。也要在每次加入图片录音后也要加入对应的代码,在InsertBitmap()函数中加入例如以下代码:
//用List记录该录音的位置及所在路径。用于单击事件
Map<String,String> map = new HashMap<String,String>();
map.put("location", selectionIndex+"-"+(selectionIndex+spannableString.length()));
map.put("path", imgPath);
imgList.add(map);
2. 给EditText加入单击事件
private LineEditText et_Notes; ... ... et_Notes.setOnClickListener(new TextClickEvent());
3. 推断单击的是图片还是普通文字
为了推断单击的是图片还是普通文字,用到了Spanned,ImageSpan。主要思想,就是推断当前单击的位置是否在图片的位置范围内,主要代码例如以下:
Spanned s = et_Notes.getText();
ImageSpan[] imageSpans;
imageSpans = s.getSpans(0, s.length(), ImageSpan.class); int selectionStart = et_Notes.getSelectionStart();
for(ImageSpan span : imageSpans){ int start = s.getSpanStart(span);
int end = s.getSpanEnd(span);
//找到图片
if(selectionStart >= start && selectionStart < end){
... ...
} }
打到了图片,接下来就要推断单击的究竟是那一图片呢?
4. 决断单击的详细是那一张图片
这就用到了第一步记录的图片的位置和路径了,显然,就是用位置来推断究竟是单击的那一个图片。主要代码例如以下:
//查找当前单击的图片是哪一个图片
//System.out.println(start+"-----------"+end);
String path = null;
for(int i = 0;i < imgList.size();i++){
Map map = imgList.get(i);
//找到了
if(map.get("location").equals(start+"-"+end)){
path = imgList.get(i).get("path");
break;
}
}
5. 推断是录音还是图片,启动相应的Activity,并传递路径
查看图片,有两种方法,一种是调用系统的图库打开图片,还有一种就是自己定义,这里。我都实现了。打开录音用的是自己定义的Activity,例如以下:
//接着推断当前图片是否是录音。假设为录音,则跳转到试听录音的Activity,假设不是,则跳转到查看图片的界面
//录音,则跳转到试听录音的Activity
if(path.substring(path.length()-3, path.length()).equals("amr")){
Intent intent = new Intent(AddActivity.this,ShowRecord.class);
intent.putExtra("audioPath", path);
startActivity(intent);
}
//图片。则跳转到查看图片的界面
else{
//有两种方法,查看图片。第一种就是直接调用系统的图库查看图片。另外一种是自己定义Activity
//调用系统图库查看图片
/*Intent intent = new Intent(Intent.ACTION_VIEW);
File file = new File(path);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "image/*");*/
//使用自己定义Activity
Intent intent = new Intent(AddActivity.this,ShowPicture.class);
intent.putExtra("imgPath", path);
startActivity(intent);
}
以上。3,4,5步事实上都是在单击的监听器中实现的。完整代码例如以下:
//为EidtText设置监听器
class TextClickEvent implements OnClickListener{ @Override
public void onClick(View v) {
Spanned s = et_Notes.getText();
ImageSpan[] imageSpans;
imageSpans = s.getSpans(0, s.length(), ImageSpan.class); int selectionStart = et_Notes.getSelectionStart();
for(ImageSpan span : imageSpans){ int start = s.getSpanStart(span);
int end = s.getSpanEnd(span);
//找到图片
if(selectionStart >= start && selectionStart < end){
//Bitmap bitmap = ((BitmapDrawable)span.getDrawable()).getBitmap();
//查找当前单击的图片是哪一个图片
//System.out.println(start+"-----------"+end);
String path = null;
for(int i = 0;i < imgList.size();i++){
Map map = imgList.get(i);
//找到了
if(map.get("location").equals(start+"-"+end)){
path = imgList.get(i).get("path");
break;
}
}
//接着推断当前图片是否是录音。假设为录音。则跳转到试听录音的Activity,假设不是,则跳转到查看图片的界面
//录音,则跳转到试听录音的Activity
if(path.substring(path.length()-3, path.length()).equals("amr")){
Intent intent = new Intent(AddActivity.this,ShowRecord.class);
intent.putExtra("audioPath", path);
startActivity(intent);
}
//图片,则跳转到查看图片的界面
else{
//有两种方法,查看图片,第一种就是直接调用系统的图库查看图片,另外一种是自己定义Activity
//调用系统图库查看图片
/*Intent intent = new Intent(Intent.ACTION_VIEW);
File file = new File(path);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "image/*");*/
//使用自己定义Activity
Intent intent = new Intent(AddActivity.this,ShowPicture.class);
intent.putExtra("imgPath", path);
startActivity(intent);
}
}
else
//假设单击的是空白出或文字。则获得焦点,即打开软键盘
imm.showSoftInput(et_Notes, 0);
}
}
}
至此。就实现了查看图片以及播放录音的功能。
android项目 之 记事本(13) ----- 查看图片及播放录音的更多相关文章
- android项目 之 记事本(11) ----- 加入数据库
本文是自己学习所做笔记.欢迎转载.但请注明出处:http://blog.csdn.net/jesson20121020 通过之前的10节,已实现了记事本的大部分功能,有加入拍照.加入照片,加入录音,加 ...
- android项目 之 记事本(12) ----- 图片的等比例缩放及给图片加入边框
本文是自己学习所做笔记.欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 在Android的UI开发中常常会遇到图片的缩放,就比方记事本,如今的图片都比較 ...
- android项目 之 记事本(6)----- 加入手写
想必大家都用过QQ的白板功能,里面主要有两项,一个是涂鸦功能,事实上类似于上节的画板功能,而还有一个就是手写,那记事本怎么能没有这个功能呢,今天就来为我们的记事本加入手写功能. 先上图,看看效果: 看 ...
- 关于Eclipse创建Android项目时,会多出一个appcompat_v7的问题
问题描述: 使用eclipse创建一个Android项目时,发现project列表中会多创建出一个appcompat_v7项目,再创建一个Android项目时,又会再多出一个appcompat_ ...
- 使用eclipse创建android项目的时候为什么会生成两个项目
使用eclipse创建android项目的时候为什么会生成两个项目 问题描述: 使用eclipse创建一个Android项目时,发现project列表中会多创建出一个appcompat_v7项目,再创 ...
- 【转】关于Eclipse创建Android项目时,会多出一个appcompat_v7的问题
问题描述: 使用eclipse创建一个Android项目时,发现project列表中会多创建出一个appcompat_v7项目,再创建一个Android项目时,又会再多出一个appcompat_v7_ ...
- Android 高仿微信朋友圈动态, 支持双击手势放大并滑动查看图片。
转载请注明出处:http://blog.csdn.net/sk719887916/article/details/40348873 作者skay: 最近参与了开发一款旅行APP,其中包含实时聊天和动态 ...
- 如何在使用eclipse的情况下,清理android项目中的冗余class文件和资源文件以及冗余图片
在我们迭代项目的过程中,经常会启用某些功能,或者修改某些界面的问题,那么问题来了,这样很容易出现大量的冗余.java文件,冗余资源文件,一些冗余的界面文件等.那么问题既然出现了,那么如何去解决呢,这就 ...
- Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能
Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...
随机推荐
- DP———7.导弹拦截(emmm冷静分析一波也不叫DP吧,不过有一种DP的方法写)
最少拦截系统 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- code forces 990C
http://codeforces.com/contest/990/problem/C C. Bracket Sequences Concatenation Problem time limit pe ...
- Java代码实现真分页
在JavaWeb项目中,分页是一个非常常见且重要的一个小方面.本次作为记载和学习,记录项目中出现的分页并做好学习记录.在这里,用的是SSH框架.框架可以理解如下图: 在JSP页面,描写的代码如下: & ...
- 理解javascript的闭包,原型,和匿名函数及IIFE
理解javascript的闭包,原型,和匿名函数(自己总结) 一 .>关于闭包 理解闭包 需要的知识1.变量的作用域 例1: var n =99; //建立函数外的全局变量 function r ...
- bzoj4897 [Thu Summer Camp2016]成绩单
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4897 [题解] 第一次看这题想的是f[l,r]的区间dp发现仅记录这两个好像不能转移啊 会出 ...
- JS日历控件集合----附效果图、源代码
http://www.cnblogs.com/yank/archive/2008/08/14/1267746.html 在进行开发的过程中,经常需要输入时间,特别是在进行查询.统计的时候,时间限定更为 ...
- python 删除字符串中的连续空格只保留一个
目标是要去掉多余的空格字符,在相邻字符串中,只保留一个空格 紫梧桐 - 蛋壳公寓朝阳门店 郑田力 可以利 ...
- mysql 共享空间转为独立表空间
由于以前的mysql配置为共享表空间,服务器空间不足,清理日志表里的数据后,数据库并没缩小,照成空间浪费,现在修改为独立表空间 #独立表空间innodb_file_per_table=1 #停止事物日 ...
- 设计模式-python实现
设计模式是什么? 设计模式是经过总结.优化的,对我们经常会碰到的一些编程问题的可重用解决方案.一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码.反之,设计模式更为高级,它是一种必须在特定情 ...
- 来杯咖啡-装饰者模式(Decorator)
前言 上篇[观察者模式]发布已经近一个月了,个人感觉反应并不太理想,因为大家响应都不是很积极,不知是文章那里写得有问题,而且也没有人提出过有价值的改进建议,多少感觉有些失望L!因为工作繁忙,所以不可能 ...