妹子圖APP(三)—— RecyclerView的Item點擊事件和圖片保存至本地

前面實現了網絡圖片加載、下拉刷新和上拉加載,現在需要點擊圖片跳轉頁面用於查看詳細的圖片,並可以保存
所以需要爲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();
            }
        }
    }
運行在Android 6.0及其以上版本的情況如下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章