您的位置:首页 > 移动开发

妹子图APP(三)—— RecyclerView的Item点击事件和图片保存至本地

2017-03-03 09:34 453 查看
接上文:妹子图APP(二)—— SwipeRefreshLayout实现下拉刷新上拉加载
前面实现了网络图片加载、下拉刷新和上拉加载,现在需要点击图片跳转页面用于查看详细的图片,并可以保存
所以需要为RecyclerView的item设置点击事件,点击后,带数据跳转另一个Activity
1.显示详细图片的Activity
图片显示采用开源控件PhotoView
PhotoView :一款扩展自Android ImageView 支持通过单点/多点触摸来进行图片缩放的智能控件。
Android Studio中添加依赖
compile 'com.github.chrisbanes.photoview:library:1.2.4'

布局中直接使用
<?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">

<uk.co.senab.photoview.PhotoView
android:id="@+id/iv_imageshow"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

Android Studio中添加依赖
compile 'de.hdodenhof:circleimageview:2.1.0'

创建对应的ImageShowActivity类,并在AndroidManifest文件中注册
<activity android:name=".activity.ImageShowActivity"/>

2.RecyclerView的Item点击事件设置
目的:模拟ListView的setOnItemClickListener()方法,设置点击事件后点击能获得被点击item的相关数据,即图片的网址。
步骤:
2.1 在MyAdapter类中定义一个接口
//自定义的接口 用于传递图片地址给跳转的Activity
public interface OnItemClickListener {
//data 用于获得图片的网址
void onItemClick(String data);
}


2.2 声明一个接口变量
//声明接口变量
private OnItemClickListener mOnItemClickListener = null;


2.3 定义一个方法暴露接口给外部
//暴露接口给外部
public void setOnItemClickListener(OnItemClickListener OnItemClickListener) {
this.mOnItemClickListener = OnItemClickListener;
}

2.4 RecyclerView子Item设置点击事件
此处是在onBindViewHolder()方法中设置 需求不同设置方法不同,根据个人的理解去设置。
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
//Glide设置图片(未加载则用粉色替代)
final String imageUrl = mList.get(position).getPicUrl();
Glide.with(mContext)
.load(imageUrl)
.asBitmap()
.centerCrop()
.placeholder(R.color.colorAccent)
.into(holder.mImageView);
//将数据保存在mImageView的TAG中,以便需要时取出
holder.mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//如果接口对象不为空
if (mOnItemClickListener != null) {
//将点击事件转移给自定义的接口
mOnItemClickListener.onItemClick(imageUrl);
Log.e("TAG","-----------------adapter---" +  imageUrl);
}
}
});

}

2.5 在Activity中调用自己写的 setOnItemClickListenter()方法

前面我是在回掉接口onFinish()方法中得到的 adapter对象,所以在此方法中设置事件监听,不然报空指针异常
@Override
public void onFinish(GirlsBean data) {
//得到适配器
mAdapter = new MyAdapter(this,data.getShowapi_res_body().getNewslist());
//设置适配器
mRecyclerView.setAdapter(mAdapter);
//RecyclerView设置Item的点击事件
mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
@Override
public void onItemClick(String data) {
//跳转显示详细图片的Activity
Intent intent = new Intent(MainActivity.this, ImageShowActivity.class);
intent.putExtra("data",data);
startActivity(intent);
}
});
}


3 获取传递的图片地址加载图片并实现保存功能
3.1Glide加载图片
PhotoView mPhotoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_imageshow);

mPhotoView = (PhotoView) findViewById(R.id.iv_imageshow);
//得到intent传来的值
String imageUrl = getIntent().getStringExtra("data");
//Glide设置图片(未加载则用粉色替代)
Glide.with(this)
.load(imageUrl)
.asBitmap()
.centerCrop()
.placeholder(R.color.colorAccent)
.into(mPhotoView);
}

此时效果如下



3.2 实现保存图片功能
首先写一个保存图片的类,能够实现保存图片,并更新本地图库,显示在图库中
public class PicDownload {
public static void saveImage(View view, Context context) {
//得到sd卡根目录
File root = Environment.getExternalStorageDirectory();
//将存储路径设置为工程的名字
File dicectory = new File(root, "GirlImage");
//创建文件夹
if (!dicectory.exists()) {
dicectory.mkdirs();
}
// 获取View的cache先要通过setDrawingCacheEnable方法把cache开启,
// 然后再调用getDrawingCache方法就可 以获得view的cache图片
Bitmap bitmap = view.getDrawingCache();
//文件名以保存时的时间命名
File file = new File(dicectory, new Date().getTime() + ".jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
//将bitmap以JPG的格式保存在设置的文件夹中
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();

Uri uri = Uri.fromFile(file);
//保存图片后发送广播通知图库更新图片
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
Toast.makeText(context, "保存成功", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(context, "保存失败", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

然后设置ImageShowActivity中图片View的长按事件监听,通过对话框的形式提示用户
//设置为true后,可以通过view.getDrawingCache()获得view的cache(缓存)
mPhotoView.setDrawingCacheEnabled(true);
//View的长按事件
mPhotoView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//new一个对话框
new AlertDialog.Builder(ImageShowActivity.this)
.setMessage("保存图片")
//消极的 否定的 即对话框的取消选项
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface anInterface, int i) {
//让Dialog对话框 从屏幕上消失
anInterface.dismiss();
}
})
//积极的 确定的 即对话框的确定选项
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface anInterface, int i) {
anInterface.dismiss();
//保存图片
PicDownload.saveImage(mPhotoView, ImageShowActivity.this);
}
}).show();
return true;
}
});

进行文件操作别忘记文件加上读写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

最后效果如下,并进行了手机本地图库查看图片是否真保存成功。



4.动态权限

以上都是在模拟器运行的,当把apk运行在真机后,无法保存图片,报错提示无法创建文件夹
因为我的真机为Android7.0,模拟器为android4.4,当版本高于6.0即sdk大于23后需要动态权限申请
在ImageShowActivity中首先写一个方法用于检测当前SDK版本是否大于23
//自定义的权限请求码
private final static int REQUESTCODE = 101;
public void saveImage(){
//如果版本高于23 即Android6.0
if (Build.VERSION.SDK_INT >= 23) {
//检查权限
int checkWriteContactsPermission = checkSelfPermission(
Manifest.permission.WRITE_EXTERNAL_STORAGE);
//如果没有权限
if (checkWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
//请求权限 REQUESTCODE 自定义的权限请求码
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}
,REQUESTCODE);
return;
} else {
//如果有权限了
//执行保存图片的方法
PicDownload.saveImage(mPhotoView, ImageShowActivity.this);
}
} else {
//如果版本低于Android6.0则直接使用
//执行保存图片的方法
PicDownload.saveImage(mPhotoView, ImageShowActivity.this);
}
}
然后重写方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//回调
if (requestCode == REQUESTCODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//执行保存图片的方法
PicDownload.saveImage(mPhotoView, ImageShowActivity.this);
} else {
Toast.makeText(this,"您已禁止该权限,需要重新开启",Toast.LENGTH_SHORT).show();
}
}
}

详细代码:https://github.com/897532167/LoadNetworkPicture
如有兴趣可看:http://blog.csdn.net/ww897532167/article/details/61196843
运行在Android 6.0及其以上版本的情况如下

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: