選擇相冊上傳圖片 展示圖片(仿微信選擇圖片)

前言

之前也一直想整理一個關於相冊的選擇啊,圖片的上傳啊,展示啊,真好前段時間項目需要,於是整理了下(因爲上一個項目寫的比較匆忙,所以比較亂)項目剛上線就想着寫個博客記錄一下


先來幾張效果圖qaq

這裏寫圖片描述

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

就是這幾個界面了, 大致的思路就是獲取手機的圖片,選擇 返回選擇的路徑(拍照

也差不多拿到路徑就好)然後展示上傳就好,下面貼一下主要代碼。

開始選擇的類,也就是上傳的類

public class AttachFileNewActivity extends BaseHeaderActivity {

    @BindView(R.id.noScrollgridview)
    GridView noScrollgridview;
    ArrayList<String> arrayList;
    AttachFileNewAdapter fileNewAdapter;

    final String mKey = "mSelectedImage";
    final String mKeyReturn = "ViewBigImageActivity";
    final String mKeyFileis = "AttachFileActivityIs";
    final String mKeyFileNew = "AttachFileNewActivity";
    String RelationRecordCode;
    int isFile;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_attachfilenew;
    }

    @Override
    protected void initView() {
        mTitle.setText(R.string.NewAccessoryManagement);
        mAction.setText(R.string.btn_Determine);
        arrayList = new ArrayList<>();
        if (getIntent().getStringExtra(mKeyFileNew) != null) {
            RelationRecordCode = getIntent().getStringExtra(mKeyFileNew);
            isFile = getIntent().getIntExtra(mKeyFileis, 0);
        }
        fileNewAdapter = new AttachFileNewAdapter(this, arrayList);
        noScrollgridview.setAdapter(fileNewAdapter);
    }

    @Override
    public void initListener() {
        noScrollgridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int i, long id) {
                if (i == arrayList.size()) {
                    ActionSheetDialog();
                } else {
                    Bundle bundle = new Bundle();
                    bundle.putInt("selet", 2);// 2,大圖顯示當前頁數,1,頭像,不顯示頁數
                    bundle.putInt("code", i);//第幾張
                    bundle.putSerializable("imageuri", arrayList);
                    bundle.putBoolean("isLocal", true);
                    Intent intent = new Intent(AttachFileNewActivity.this, ViewBigImageActivity.class);
                    intent.putExtras(bundle);
                    jumpToActivityForResult(intent, 13);
                }
            }
        });
        mAction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (arrayList.size() != 0) initHttpPostFile();
                else APP.mToast(R.string.mustOne);
            }
        });
    }

    private void initHttpPostFile() {
        shouCustomProgressDialog("");
        File[] mFile = new File[arrayList.size()];
        String[] mS = new String[arrayList.size()];
        for (int i = 0; i < arrayList.size(); i++) {
            File f = new File(arrayList.get(i));
            mFile[i] = f;
            mS[i] = "file" + i;
        }
        String[] parameter = new String[1];
        switch (isFile) {
            case 1:
                parameter = new String[]{"AccountCode", "CustomerCode"};
                break;
            case 2:
                parameter = new String[]{"AccountCode", "RelationRecordCode"};
                break;
            case 3:
                parameter = new String[]{"AccountCode", "ContactCode"};
                break;
        }

        String[] content = new String[]{StringCrypto.EncodeString(APP.UserInfo.getAccountCode(), U.mKey), StringCrypto.EncodeString(RelationRecordCode, U.mKey)};
        HttpPost.LoginAddFile(U.uploadPhoto(isFile), mFile, mS, parameter, content, new OnLoginListener() {
            @Override
            public void loginSuccess(String response, int id) {
                boolean status = false;
                try {
                    JSONObject jsonob = new JSONObject(response);
                    status = jsonob.optBoolean("status");
                } catch (JSONException e) {
                    e.printStackTrace();
                    dissmisToast(UiUtils.getString(R.string.OkhttpDataError));
                    return;
                }
                if (status) {
                    dissmisToast(UiUtils.getString(R.string.uploadPhotoSuccess));
                    finish();
                } else {
                    dissmisToast(UiUtils.getString(R.string.uploadPhotoError));
                }
            }

            @Override
            public void loginError(Call call, Exception e, int id) {
                dissmisToast(UiUtils.getString(R.string.OkhttpError));
            }
        });
    }

    private void ActionSheetDialog() {
        new ActionSheetDialog(this)
                .builder()
                .setCancelable(false)
                .setCanceledOnTouchOutside(false)
                .addSheetItem("選擇相冊", SheetItemColor.Blue,
                        new OnSheetItemClickListener() {
                            @Override
                            public void onClick(int which) {
                                jumpToActivityForResult(AlbumActivity.class, 13);
                            }
                        })
                .addSheetItem("拍照", SheetItemColor.Blue,
                        new OnSheetItemClickListener() {
                            @Override
                            public void onClick(int which) {
                                takePhoto();
                            }
                        }).show();
    }

    private String path = "";

    /**
     * 拍照
     */
    public void takePhoto() {
        Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File vFile = new File(Environment.getExternalStorageDirectory()
                + "/頂易手機端/附件/", String.valueOf(System
                .currentTimeMillis()) + ".jpg");
        if (!vFile.exists()) {
            File vDirPath = vFile.getParentFile();
            vDirPath.mkdirs();
        } else {
            if (vFile.exists()) {
                vFile.delete();
            }
        }
        path = vFile.getPath();
        Uri cameraUri = Uri.fromFile(vFile);
        openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
        startActivityForResult(openCameraIntent, 13);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 13 && resultCode == 33) {
            List<String> array = data.getStringArrayListExtra(mKey);
            if (array != null) {
                arrayList.addAll(array);
                fileNewAdapter.setUpdate(arrayList);
            }
        } else if (requestCode == 13 && resultCode == 150) {
            ArrayList<String> array = data.getStringArrayListExtra(mKeyReturn);
            arrayList.clear();
            arrayList.addAll(array);
            fileNewAdapter.setUpdate(arrayList);
        } else if (requestCode == 13 && resultCode == -1 && !TextUtils.isEmpty(path)) {
            arrayList.add(path);// 在添加拍照的。一共顯示的是選中加拍照的
            fileNewAdapter.setUpdate(arrayList);
        }
    }
}

由於我項目裏有三個的附件管理,所以我上傳的地方做了判斷

下面是獲取相冊類,參照的是洪洋博客的

public class AlbumActivity extends BaseHeaderActivity implements ListImageDirPopupWindow.OnImageDirSelected{


    private ProgressDialog mProgressDialog;

    /**
     * 存儲文件夾中的圖片數量
     */
    private int mPicsSize;
    /**
     * 圖片數量最多的文件夾
     */
    private File mImgDir;
    /**
     * 所有的圖片
     */
    private List<String> mImgs;

    private GridView mGirdView;
    private AlbumAdapter mAdapter;
    /**
     * 臨時的輔助類,用於防止同一個文件夾的多次掃描
     */
    private HashSet<String> mDirPaths = new HashSet<String>();

    /**
     * 掃描拿到所有的圖片文件夾
     */
    private List<ImageFloder> mImageFloders = new ArrayList<ImageFloder>();

    private RelativeLayout mBottomLy;

    private TextView mChooseDir;
    private TextView mImageCount;
    int totalCount = 0;

    private int mScreenHeight;

    private ListImageDirPopupWindow mListImageDirPopupWindow;

    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            mProgressDialog.dismiss();
            // 爲View綁定數據
            data2View();
            // 初始化展示文件夾的popupWindw
            initListDirPopupWindw();
        }
    };


    @Override
    protected int getLayoutId() {
        return R.layout.activity_album;
    }


    /**
     * 爲View綁定數據
     */
    private void data2View() {
        if (mImgDir == null) {
            Toast.makeText(getApplicationContext(), "擦,一張圖片沒掃描到",
                    Toast.LENGTH_SHORT).show();
            return;
        }
        mImgs = Arrays.asList(mImgDir.list());
        /**
         * 可以看到文件夾的路徑和圖片的路徑分開保存,極大的減少了內存的消耗;
         */
        mAdapter = new AlbumAdapter(this, mImgs,
                R.layout.grid_item, mImgDir.getAbsolutePath());
        mAdapter.setAlbumAdapterRe(new AlbumAdapter.AlbumAdapterRe() {
            @Override
            public void ResultsetImageCount(List<String> arrayList) {
                setImageCount(arrayList);
            }
        });
        mGirdView.setAdapter(mAdapter);
        mImageCount.setText(totalCount + "張");
    }

    /**
     * 初始化展示文件夾的popupWindw
     */
    private void initListDirPopupWindw() {
        mListImageDirPopupWindow = new ListImageDirPopupWindow(
                ViewGroup.LayoutParams.MATCH_PARENT, (int) (mScreenHeight * 0.7),
                mImageFloders, LayoutInflater.from(getApplicationContext())
                .inflate(R.layout.list_dir, null));

        mListImageDirPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {

            @Override
            public void onDismiss() {
                // 設置背景顏色變暗
                WindowManager.LayoutParams lp = getWindow().getAttributes();
                lp.alpha = 1.0f;
                getWindow().setAttributes(lp);
            }
        });
        // 設置選擇文件夾的回調
        mListImageDirPopupWindow.setOnImageDirSelected(this);
    }

    /**
     * 利用ContentProvider掃描手機中的圖片,此方法在運行在子線程中 完成圖片的掃描,最終獲得jpg最多的那個文件夾
     */
    private void getImages() {
        if (!Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            Toast.makeText(this, "暫無外部存儲", Toast.LENGTH_SHORT).show();
            return;
        }
        // 顯示進度條
        mProgressDialog = ProgressDialog.show(this, null, "正在加載...");

        new Thread(new Runnable() {
            @Override
            public void run() {

                String firstImage = null;

                Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                ContentResolver mContentResolver = AlbumActivity.this
                        .getContentResolver();

                // 只查詢jpeg和png的圖片
                Cursor mCursor = mContentResolver.query(mImageUri, null,
                        MediaStore.Images.Media.MIME_TYPE + "=? or "
                                + MediaStore.Images.Media.MIME_TYPE + "=?",
                        new String[]{"image/jpeg", "image/png"},
                        MediaStore.Images.Media.DATE_MODIFIED);

             //   LogUtils.e("TAG", mCursor.getCount() + "");
                while (mCursor.moveToNext()) {
                    // 獲取圖片的路徑
                    String path = mCursor.getString(mCursor
                            .getColumnIndex(MediaStore.Images.Media.DATA));

                //    LogUtils.e("TAG", path);
                    // 拿到第一張圖片的路徑
                    if (firstImage == null)
                        firstImage = path;
                    // 獲取該圖片的父路徑名
                    File parentFile = new File(path).getParentFile();
                    if (parentFile == null)
                        continue;
                    String dirPath = parentFile.getAbsolutePath();
                    ImageFloder imageFloder = null;
                    // 利用一個HashSet防止多次掃描同一個文件夾(不加這個判斷,圖片多起來還是相當恐怖的~~)
                    if (mDirPaths.contains(dirPath)) {
                        continue;
                    } else {
                        mDirPaths.add(dirPath);
                        // 初始化imageFloder
                        imageFloder = new ImageFloder();
                        imageFloder.setDir(dirPath);
                        imageFloder.setFirstImagePath(path);
                    }

                    int picSize = parentFile.list(new FilenameFilter() {
                        @Override
                        public boolean accept(File dir, String filename) {
                            if (filename.endsWith(".jpg")
                                    || filename.endsWith(".png")
                                    || filename.endsWith(".jpeg"))
                                return true;
                            return false;
                        }
                    }).length;
                    totalCount += picSize;

                    imageFloder.setCount(picSize);
                    mImageFloders.add(imageFloder);

                    if (picSize > mPicsSize) {
                        mPicsSize = picSize;
                        mImgDir = parentFile;
                    }
                }
                mCursor.close();

                // 掃描完成,輔助的HashSet也就可以釋放內存了
                mDirPaths = null;

                // 通知Handler掃描圖片完成
                mHandler.sendEmptyMessage(0x110);

            }
        }).start();
    }


    /**
     * 初始化View
     */
    @Override
    protected void initView() {
        DisplayMetrics outMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
        mScreenHeight = outMetrics.heightPixels;
        mGirdView = (GridView) findViewById(R.id.id_gridView);
        mChooseDir = (TextView) findViewById(R.id.id_choose_dir);
        mImageCount = (TextView) findViewById(R.id.id_total_count);

        mBottomLy = (RelativeLayout) findViewById(R.id.id_bottom_ly);
        mTitle.setText("選擇圖片");
        mAction.setText("確定");
        getImages();
        initEvent();

    }

    private void initEvent() {
        /**
         * 爲底部的佈局設置點擊事件,彈出popupWindow
         */
        mBottomLy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListImageDirPopupWindow
                        .setAnimationStyle(R.style.anim_popup_dir);
                mListImageDirPopupWindow.showAsDropDown(mBottomLy, 0, 0);

                // 設置背景顏色變暗
                WindowManager.LayoutParams lp = getWindow().getAttributes();
                lp.alpha = .3f;
                getWindow().setAttributes(lp);
            }
        });
        mAction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAdapter.setToIntent();
            }
        });
    }

    @Override
    public void selected(ImageFloder floder) {

        mImgDir = new File(floder.getDir());
        mImgs = Arrays.asList(mImgDir.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String filename) {
                if (filename.endsWith(".jpg") || filename.endsWith(".png")
                        || filename.endsWith(".jpeg"))
                    return true;
                return false;
            }
        }));
        /**
         * 可以看到文件夾的路徑和圖片的路徑分開保存,極大的減少了內存的消耗;
         */
        //mAdapter = new AlbumAdapter(this, mImgs,
        //       R.layout.grid_item, mImgDir.getAbsolutePath());
        // mGirdView.setAdapter(mAdapter);
        mAdapter.setAlbumAdapter(mImgs, mImgDir.getAbsolutePath());
        // mAdapter.notifyDataSetChanged();
        //  mImageCount.setText(floder.getCount() + "張");原顯示圖片張數

        mChooseDir.setText(floder.getName() + "/" + floder.getCount() + "張");
        mListImageDirPopupWindow.dismiss();

    }


    public void setImageCount(List<String> mSelectedImage) {
        mImageCount.setText("已選擇(" + mSelectedImage.size() + ")張");
    }

}

查看完整大圖的類


/**
 * 用於查看大圖
 *
 * @author jingbin
 */
public class ViewBigImageActivity extends FragmentActivity implements OnPageChangeListener, PhotoViewAttacher.OnPhotoTapListener {
    final String mKey = "ViewBigImageActivity";
    // 保存圖片
    private TextView tv_save_big_image;
    //刪除圖片 附件
    private TextView tv_delete_big_image;

    // 接收傳過來的uri地址
    List<String> imageuri;
    ArrayList<AttachFileBean> imageuribean;
    // 接收穿過來當前選擇的圖片的數量
    int code;
    // 用於判斷是頭像還是文章圖片 1:頭像 2:文章大圖
    int selet;
    int  isFile;//用於判斷那個類型進來的
    // 用於管理圖片的滑動
    ViewPager very_image_viewpager;
    // 當前頁數
    private int page;

    /**
     * 顯示當前圖片的頁數
     */
    TextView very_image_viewpager_text;
    /**
     * 用於判斷是否是加載本地圖片
     */
    private boolean isLocal;

    ViewPagerAdapter adapter;

    /**
     * 本應用圖片的id
     */
    private int imageId;
    /**
     * 是否是本應用中的圖片
     */
    private boolean isApp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_big_image);
        getView();
    }

    /**
     * 保存圖片至相冊
     */
    public static void saveImageToGallery(Context context, Bitmap bmp) {
        // 首先保存圖片
        File appDir = new File(Environment.getExternalStorageDirectory(), "頂易手機端");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 其次把文件插入到系統圖庫
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(),
                    file.getAbsolutePath(), fileName, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        // 最後通知圖庫更新
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getAbsoluteFile())));
    }


    /**
     * Glide 獲得圖片緩存路徑
     */
    private String getImagePath(String imgUrl) {
        String path = null;
        FutureTarget<File> future = Glide.with(ViewBigImageActivity.this)
                .load(imgUrl)
                .downloadOnly(500, 500);
        try {
            File cacheFile = future.get();
            path = cacheFile.getAbsolutePath();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        return path;
    }

    /*
     * 接收控件
     */
    private void getView() {
        /************************* 接收控件 ***********************/
        very_image_viewpager_text = (TextView) findViewById(R.id.very_image_viewpager_text);
        tv_save_big_image = (TextView) findViewById(R.id.tv_save_big_image);
        very_image_viewpager = (ViewPager) findViewById(R.id.very_image_viewpager);
        tv_delete_big_image = (TextView) findViewById(R.id.tv_delete_big_image);
        tv_save_big_image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                ToastUtil.showToast("開始下載圖片");
                if (isApp) {// 本地圖片
                    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imageId);
                    if (bitmap != null) {
                        saveImageToGallery(ViewBigImageActivity.this, bitmap);
                        ToastUtil.showToast("保存成功");
//                        Toast.makeText(ViewBigImageActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
                    }

                } else {// 網絡圖片
                    final BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            // 子線程獲得圖片路徑
                            final String imagePath = getImagePath(imageuri.get(page));
                            // 主線程更新
                            ViewBigImageActivity.this.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if (imagePath != null) {
                                        Bitmap bitmap = BitmapFactory.decodeFile(imagePath, bmOptions);
                                        if (bitmap != null) {
                                            saveImageToGallery(ViewBigImageActivity.this, bitmap);
                                            ToastUtil.showToast("已保存至" + Environment.getExternalStorageDirectory().getAbsolutePath() + "/雲閱相冊");
//                                            Toast.makeText(ViewBigImageActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                }
                            });
                        }
                    }).start();
                }
            }
        });
        tv_delete_big_image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isLocal) {//選擇相冊返回的圖片顯示
                    imageuri.remove(page);
                    adapter.notifyDataSetChanged();
                } else {//刪除附件
                    OnHttpUtilsDelete(imageuribean.get(page).getAttachFileCode(), page);
                }

            }
        });
        /************************* 接收傳值 ***********************/
        Bundle bundle = getIntent().getExtras();
        code = bundle.getInt("code");
        selet = bundle.getInt("selet");
        isLocal = bundle.getBoolean("isLocal", false);
        imageuribean = (ArrayList<AttachFileBean>) bundle.getSerializable("imageuribean");
        imageuri = bundle.getStringArrayList("imageuri");
        isFile= bundle.getInt("isFile",0);
        /**是否是本應用中的圖片*/
        isApp = bundle.getBoolean("isApp", false);
        /**本應用圖片的id*/
        imageId = bundle.getInt("id", 0);
        if (imageuribean != null) {
            if (imageuri == null) imageuri = new ArrayList<>();
            for (int i = 0; i < imageuribean.size(); i++) {
                imageuri.add(imageuribean.get(i).getUrl());
            }
        }
        /**
         * 給viewpager設置適配器
         */
        if (isApp) {
            MyPageAdapter myPageAdapter = new MyPageAdapter();
            very_image_viewpager.setAdapter(myPageAdapter);
            very_image_viewpager.setEnabled(false);
        } else {
            adapter = new ViewPagerAdapter();
            very_image_viewpager.setAdapter(adapter);
            very_image_viewpager.setCurrentItem(code);
            page = code;
            very_image_viewpager.setOnPageChangeListener(this);
            very_image_viewpager.setEnabled(false);
            // 設定當前的頁數和總頁數
            if (selet == 2) {
                very_image_viewpager_text.setText((code + 1) + " / " + imageuri.size());
            }
        }
    }

    /**
     * 本應用圖片適配器
     */

    class MyPageAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return 1;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View view = getLayoutInflater().inflate(R.layout.viewpager_very_image, container, false);
            PhotoView zoom_image_view = (PhotoView) view.findViewById(R.id.zoom_image_view);
            ProgressBar spinner = (ProgressBar) view.findViewById(R.id.loading);
            spinner.setVisibility(View.GONE);
            if (imageId != 0) {
                zoom_image_view.setImageResource(imageId);
            }
            zoom_image_view.setOnPhotoTapListener(ViewBigImageActivity.this);
            container.addView(view, 0);
            return view;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            View view = (View) object;
            container.removeView(view);
        }
    }

    /**
     * ViewPager的適配器
     *
     * @author guolin
     */
    class ViewPagerAdapter extends PagerAdapter {

        LayoutInflater inflater;

        ViewPagerAdapter() {
            inflater = getLayoutInflater();
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View view = inflater.inflate(R.layout.viewpager_very_image, container, false);
            final PhotoView zoom_image_view = (PhotoView) view.findViewById(R.id.zoom_image_view);
            final ProgressBar spinner = (ProgressBar) view.findViewById(R.id.loading);
            // 保存網絡圖片的路徑
            String adapter_image_Entity = (String) getItem(position);
            //TODO
            String imageUrl;
            if (isLocal) {
                imageUrl = "file://" + adapter_image_Entity;
                tv_save_big_image.setVisibility(View.GONE);
            } else {
                imageUrl = adapter_image_Entity;
            }

            spinner.setVisibility(View.VISIBLE);
            spinner.setClickable(false);
            Glide.with(ViewBigImageActivity.this).load(imageUrl)
                    .crossFade(700)
                    .listener(new RequestListener<String, GlideDrawable>() {
                        @Override
                        public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                            Toast.makeText(getApplicationContext(), "資源加載異常", Toast.LENGTH_SHORT).show();
                            spinner.setVisibility(View.GONE);
                            return false;
                        }

                        //這個用於監聽圖片是否加載完成
                        @Override
                        public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
//                            Toast.makeText(getApplicationContext(), "圖片加載完成", Toast.LENGTH_SHORT).show();
                            spinner.setVisibility(View.GONE);

                            /**這裏應該是加載成功後圖片的高*/
                            int height = zoom_image_view.getHeight();

                            int wHeight = getWindowManager().getDefaultDisplay().getHeight();
                            if (height > wHeight) {
                                zoom_image_view.setScaleType(ImageView.ScaleType.CENTER_CROP);
                            } else {
                                zoom_image_view.setScaleType(ImageView.ScaleType.FIT_CENTER);
                            }
                            return false;
                        }
                    }).into(zoom_image_view);

            zoom_image_view.setOnPhotoTapListener(ViewBigImageActivity.this);
            container.addView(view, 0);
            return view;
        }

        @Override
        public int getCount() {
            if (imageuri == null || imageuri.size() == 0) {
                return 0;
            }
            return imageuri.size();
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            View view = (View) object;
            container.removeView(view);
        }

        Object getItem(int position) {
            return imageuri.get(position);
        }
    }

    /**
     * 下面是對Viewpager的監聽
     */
    @Override
    public void onPageScrollStateChanged(int arg0) {
    }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
    }

    /**
     * 本方法主要監聽viewpager滑動的時候的操作
     */
    @Override
    public void onPageSelected(int arg0) {
        // 每當頁數發生改變時重新設定一遍當前的頁數和總頁數
        very_image_viewpager_text.setText((arg0 + 1) + " / " + imageuri.size());
        page = arg0;
    }

    @Override
    public void onPhotoTap(View view, float x, float y) {
        finish();
    }

    @Override
    public void onOutsidePhotoTap() {
//        finish();
    }

    private void OnHttpUtilsDelete(String json, final int i) {
        ToastUtil.showToast("開始刪除圖片");
        HttpPost.LoginUrl(this, U.deleteRelationAttachFile(json,isFile), new OnLoginListener() {
            @Override
            public void loginSuccess(String response, int id) {
                boolean status = false;
                try {
                    JSONObject jsonob = new JSONObject(response);
                    status = jsonob.optBoolean("status");
                } catch (JSONException e) {
                    e.printStackTrace();
                    ToastUtil.showToast(UiUtils.getString(R.string.OkhttpDelete));
                    return;
                }
                if (status) {
                    imageuri.remove(i);
                    adapter.notifyDataSetChanged();
                    ToastUtil.showToast(UiUtils.getString(R.string.OkhttpDelete));
                } else {
                    ToastUtil.showToast(UiUtils.getString(R.string.OkhttpDeleteError));
                }
            }

            @Override
            public void loginError(Call call, Exception e, int id) {
                ToastUtil.showToast(UiUtils.getString(R.string.OkhttpError));
            }
        });
    }

    // 返回鍵返回事件
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (KeyEvent.KEYCODE_BACK == keyCode) {
            //根據 Tag 取消請求
            OkHttpUtils.getInstance().cancelTag(this);
            overridePendingTransition(R.anim.move_left_in_activity, R.anim.move_right_out_activity);
            Intent intent = new Intent();
            intent.putStringArrayListExtra(mKey, (ArrayList<String>) imageuri);
            //記錄下要返回給那個父親,可能還有什麼繼父什麼的
            setResult(150, intent);
            finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

也是複用了多次了的,所以判斷比較多,用到的第三方有 okhttputlis,Glide,uk.co.senab.photoview.

下面是圖片展示的類

public class AttachFileActivity extends BaseHeaderActivity implements BGARefreshLayout.BGARefreshLayoutDelegate {
    @BindView(R.id.id_gridView)
    GridView idGridView;
    AttachFileAdapter fileAdapter;
    @BindView(R.id.mRefreshLayout)
    BGARefreshLayout mRefreshLayout;
    @BindView(R.id.tv_context)
    TextView tvContext;
    @BindView(R.id.ll_error_refresh)
    LinearLayout llErrorRefresh;
    ArrayList<AttachFileBean> mRatingArray;
    final String mKey = "AttachFileActivity";
    final String mKeyFileis = "AttachFileActivityIs";
    final String mKeyFileNew = "AttachFileNewActivity";
    String RelationRecordCode;
    int isFile;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_attachfile;
    }

    @Override
    protected void initView() {
        mTitle.setText(R.string.AccessoryManagement);
        mAction.setText(R.string.NewlyAdded);
        if (getIntent().getStringExtra(mKey) != null) {
            RelationRecordCode = getIntent().getStringExtra(mKey);
            isFile=getIntent().getIntExtra(mKeyFileis,0);
        }
        mRatingArray = new ArrayList<>();
        fileAdapter = new AttachFileAdapter(this, mRatingArray, R.layout.item_attachfile);
        idGridView.setAdapter(fileAdapter);
        initHttpPost();
    }

    @Override
    public void initListener() {
        mRefreshLayout.setDelegate(this);
        BGAStickinessRefreshViewHolder stickinessRefreshViewHolder = new BGAStickinessRefreshViewHolder(this, false);
        stickinessRefreshViewHolder.setStickinessColor(R.color.colorAccent);
        stickinessRefreshViewHolder.setRotateImage(R.mipmap.bga_refresh_stickiness);
        mRefreshLayout.setRefreshViewHolder(stickinessRefreshViewHolder);
        idGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Bundle bundle = new Bundle();
                bundle.putInt("selet", 2);// 2,大圖顯示當前頁數,1,頭像,不顯示頁數
                bundle.putInt("code", position);//第幾張
                bundle.putSerializable("imageuribean", mRatingArray);
                bundle.putInt("isFile", isFile);//那個類型附件進來的
                Intent intent = new Intent(AttachFileActivity.this, ViewBigImageActivity.class);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
        mAction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(AttachFileActivity.this, AttachFileNewActivity.class);
                intent.putExtra(mKeyFileNew, RelationRecordCode);
                intent.putExtra(mKeyFileis, isFile);
                jumpToActivity(intent);
            }
        });

    }

    private void initHttpPost() {
        if (mRatingArray == null)
            initLoading(tvContext, llErrorRefresh);
        shouCustomProgressDialog("");
        HttpPost.LoginUrlACache(TAG, U.getAllAttachFile(RelationRecordCode,isFile), new OnLoginListener() {
            @Override
            public void loginSuccess(String response, int id) {
                boolean status = false;
                String list = null;
                try {
                    JSONObject jsonObject = new JSONObject(response);
                    status = jsonObject.optBoolean("status");
                    list = jsonObject.optString("list");
                } catch (JSONException e) {
                    e.printStackTrace();
                    dissmisToast(UiUtils.getString(R.string.OkhttpDataError));
                    initError(tvContext, llErrorRefresh, new OnLoading() {
                        @Override
                        public void Refresh(View v) {
                            initHttpPost();
                        }
                    });
                    return;
                }
                if (status) {
                    mRatingArray = APP.gson.fromJson(list,
                            new TypeToken<List<AttachFileBean>>() {
                            }.getType());
                    if (isSize(mRatingArray)) {
                        initTo();
                        initSuccess(llErrorRefresh);
                        dissmisCustomProgressDialog();
                    } else {
                        initRefresh(tvContext, R.string.http_no, llErrorRefresh);
                        dissmisToast(UiUtils.getString(R.string.http_no));
                    }
                } else {
                    dissmisToast(UiUtils.getString(R.string.OkhttpDataError));
                    initError(tvContext, llErrorRefresh, new OnLoading() {
                        @Override
                        public void Refresh(View v) {
                            initHttpPost();
                        }
                    });
                }
                mRefreshLayout.endRefreshing();
            }

            @Override
            public void loginError(Call call, Exception e, int id) {
                dissmisToast(UiUtils.getString(R.string.OkhttpError));
                initError(tvContext, llErrorRefresh, new OnLoading() {
                    @Override
                    public void Refresh(View v) {
                        initHttpPost();
                    }
                });
                mRefreshLayout.endRefreshing();
            }
        });
    }

    private void initTo() {
        fileAdapter.setData(mRatingArray);

    }

    @Override
    public void onBGARefreshLayoutBeginRefreshing(BGARefreshLayout refreshLayout) {
        HttpPost.isLogin = true;
        initHttpPost();
    }

    @Override
    public boolean onBGARefreshLayoutBeginLoadingMore(BGARefreshLayout refreshLayout) {
        return false;
    }
}

下面附上一些適配器什麼的用到的類以及用到的一些方法

展示圖片的繼承的通用適配器,百度一下就有的

public class AttachFileAdapter extends CommonAdapter<AttachFileBean> {
    /**
     * 構造函數
     *
     * @param context   上下文
     * @param data      顯示的數據
     * @param layout_id listview使用的條目的佈局文件id
     */
    public AttachFileAdapter(Context context, List<AttachFileBean> data, int layout_id) {
        super(context, data, layout_id);
    }

    public void setData(List<AttachFileBean> data) {
        this.data = data;
        notifyDataSetChanged();
    }

    @Override
    public void convert(ViewHolder h, AttachFileBean item, int i) {
        String prefix=item.getUrl().substring(item.getUrl().lastIndexOf(".")+1);
        if (prefix.equals("png")||prefix.equals("jpg")){
            h.setImageByUrl(R.id.iv_welfare, item.getUrl(), false);
        }else {
            h.setImageByUrl(R.id.iv_welfare,R.mipmap.img_default_meizi, false);
        }
        if (i % 2 == 0) {
            DensityUtil.setViewMargin((View) h.getViewById(R.id.iv_welfare),false, 12, 6, 12, 0);
        } else {
            DensityUtil.setViewMargin((View) h.getViewById(R.id.iv_welfare), false, 6, 12, 12, 0);
        }
    }
}
    /**
     * 設置某個View的margin
     *
     * @param view   需要設置的view
     * @param isDp   需要設置的數值是否爲DP
     * @param left   左邊距
     * @param right  右邊距
     * @param top    上邊距
     * @param bottom 下邊距
     * @return
     */
    public static ViewGroup.LayoutParams setViewMargin(View view, boolean isDp, int left, int right, int top, int bottom) {
        if (view == null) {
            return null;
        }

        int leftPx = left;
        int rightPx = right;
        int topPx = top;
        int bottomPx = bottom;
        ViewGroup.LayoutParams params = view.getLayoutParams();
        ViewGroup.MarginLayoutParams marginParams = null;
        //獲取view的margin設置參數
        if (params instanceof ViewGroup.MarginLayoutParams) {
            marginParams = (ViewGroup.MarginLayoutParams) params;
        } else {
            //不存在時創建一個新的參數
            marginParams = new ViewGroup.MarginLayoutParams(params);
        }

        //根據DP與PX轉換計算值
        if (isDp) {
            leftPx = dip2px(left);
            rightPx = dip2px(right);
            topPx = dip2px(top);
            bottomPx = dip2px(bottom);
        }
        //設置margin
        marginParams.setMargins(leftPx, topPx, rightPx, bottomPx);
        view.setLayoutParams(marginParams);
        view.requestLayout();
        return marginParams;
    }

上面用的一些方法

   /**
     * 爲ImageView設置圖片
     *
     * @param viewId
     * @param url
     * @param is 是否開啓內存緩存
     * @return
     */
    public void setImageByUrl(int viewId, String url,boolean is)
    {
        Glide.with(context)
                .load(url)
                .placeholder(Drawables.sPlaceholderDrawable)//設置資源加載過程中的佔位Drawable。
                .error(Drawables.sErrorDrawable)//設置load失敗時顯示的Drawable。
                //.centerCrop()
                .skipMemoryCache(is) //使用內存緩存
                .diskCacheStrategy(DiskCacheStrategy.NONE) //不使用硬盤緩存
                .into((ImageView) getViewById(viewId));

    }
 /**
     * 根據控件id獲取控件對象
     *
     * @param viewId
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> T getViewById(int viewId) {
        // 從集合中根據這個id獲取view視圖對象
        View view = mViews.get(viewId);
        // 如果爲空,說明是第一次獲取,裏面沒有,那就在佈局文件中找到這個控件,並且存進集合中
        if (view == null) {
            view = mContentView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        // 返回控件對象
        return (T) view;
    }

上傳的類的適配器,也是複用多次的

public class AttachFileNewAdapter extends BaseAdapter {
    private LayoutInflater inflater;
    ArrayList<String> list;
    Context context;

    public AttachFileNewAdapter(Context context, ArrayList<String> list) {
        inflater = LayoutInflater.from(context);
        this.context = context;
        this.list = list;
    }

    public void setUpdate(ArrayList<String> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        if (list.size() == 0) {
            return 1;
        } else {
            return list.size() + 1;// 加一個選擇圖片
        }
    }
    @Override
    public Object getItem(int i) {
        if (list.size() == 0 || i - 1 < 0
                || i > list.size() ) {
            return null;
        } else {
            return list.get(i-1);
        }
    }
    @Override
    public long getItemId(int i) {
        return i;
    }
    @Override
    public View getView(int i, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item_attachfilenew,
                    parent, false);
            holder = new ViewHolder();
            holder.image = (ImageView) convertView
                    .findViewById(R.id.item_grida_image);
            if (i % 3 == 0) {
                DensityUtil.setViewMargin(holder.image,false, 12, 6, 12, 0);
            } else {
                DensityUtil.setViewMargin(holder.image, false, 6, 12, 12, 0);
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        if(i == parent.getChildCount()){
            LogUtils.e("list.size()=",list.size()+"/position="+i);
            if (isShowAddItem(i)) {//若爲真,則表示沒有圖片,顯示添加圖片的標誌
                holder.image.setImageBitmap(BitmapFactory.decodeResource(
                        context.getResources(), R.mipmap.additem));
            }else {
                setImageByUrl(holder.image,list.get(i),false);
            }
            //正常調用
        }else{
            //系統爲計算item高度額外調用
        }
        return convertView;
    }

    public class ViewHolder {
        public ImageView image;
    }


    public void setImageByUrl(View v, String url,boolean is)
    {
        Glide.with(context)
                .load(url)
                .placeholder(Drawables.sPlaceholderDrawable)//設置資源加載過程中的佔位Drawable。
                .error(Drawables.sErrorDrawable)//設置load失敗時顯示的Drawable。
                .centerCrop()
                .override(APP.windowWidth/3, UiUtils.getDimension(R.dimen.x120))
                .skipMemoryCache(is) //使用內存緩存
                .diskCacheStrategy(DiskCacheStrategy.NONE) //不使用硬盤緩存
                .into((ImageView)v);
    }
    private boolean isShowAddItem(int position) {
        // mDataList == null則size=0,mDataList != null則size=mDataList.size();
        int size = list == null ? 0 : list.size();
        return position == size;
    }
}

相冊選擇的適配器

public class AlbumAdapter extends CommonAdapter<String> {

    /**
     * 用戶選擇的圖片,存儲爲圖片的完整路徑
     */
    public List<String> mSelectedImage = new LinkedList<String>();
    AlbumAdapterRe albumAdapterRe;
    /**
     * 文件夾路徑
     */
    private String mDirPath;

    public AlbumAdapter(Context context, List<String> mDatas, int itemLayoutId,
                        String dirPath) {
        super(context, mDatas, itemLayoutId);
        this.mDirPath = dirPath;
    }

    public void setAlbumAdapterRe(AlbumAdapterRe albumAdapterRe) {
        this.albumAdapterRe = albumAdapterRe;
    }

    public void setAlbumAdapter(List<String> mDatas, String dirPath) {
        this.data = mDatas;
        this.mDirPath = dirPath;
        notifyDataSetChanged();
    }

    @Override
    public void convert(final ViewHolder helper, final String item, int position) {
        //設置no_pic
     //   helper.setImageResource(R.id.id_item_image, R.mipmap.pictures_no);
        //設置no_selected
        helper.setImageResource(R.id.id_item_select,
                R.mipmap.picture_unselected);
        //設置圖片
        helper.setImageByUrl(R.id.id_item_image, mDirPath + "/" + item, false);

        final ImageView mImageView = helper.getViewById(R.id.id_item_image);
        final ImageView mSelect = helper.getViewById(R.id.id_item_select);

        mImageView.setColorFilter(null);
        //設置ImageView的點擊事件
        mImageView.setOnClickListener(new View.OnClickListener() {
            //選擇,則將圖片變暗,反之則反之
            @Override
            public void onClick(View v) { // 已經選擇過該圖片
                if (mSelectedImage.contains(mDirPath + "/" + item)) {
                    mSelectedImage.remove(mDirPath + "/" + item);
                    mSelect.setImageResource(R.mipmap.picture_unselected);
                    mImageView.setColorFilter(null);
                } else {// 未選擇該圖片
                    mSelectedImage.add(mDirPath + "/" + item);
                    mSelect.setImageResource(R.mipmap.pictures_selected);
                    mImageView.setColorFilter(Color.parseColor("#77000000"));
                }
                helper.setImageByUrl(R.id.id_item_image, mDirPath + "/" + item, false);
                if(albumAdapterRe!=null)
                    albumAdapterRe.ResultsetImageCount(mSelectedImage);
            }
        });
        /**
         * 已經選擇過的圖片,顯示出選擇過的效果
         */
        if (mSelectedImage.contains(mDirPath + "/" + item)) {
            mSelect.setImageResource(R.mipmap.pictures_selected);
            mImageView.setColorFilter(Color.parseColor("#77000000"));
        }
    }

    public void setToIntent() {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.addAll(mSelectedImage);
        Intent intent = new Intent(context, AttachFileNewActivity.class);
        intent = intent.putStringArrayListExtra("mSelectedImage", arrayList);
        ((AlbumActivity)context).setResult(33, intent);
        ((AlbumActivity)context).finish();
    }

    public interface AlbumAdapterRe {
        void ResultsetImageCount(List<String> arrayList);
    }

}

儲存圖片的bean

public class ImageFloder
{
    /**
     * 圖片的文件夾路徑
     */
    private String dir;

    /**
     * 第一張圖片的路徑
     */
    private String firstImagePath;

    /**
     * 文件夾的名稱
     */
    private String name;

    /**
     * 圖片的數量
     */
    private int count;

    public String getDir()
    {
        return dir;
    }

    public void setDir(String dir)
    {
        this.dir = dir;
        int lastIndexOf = this.dir.lastIndexOf("/");
        this.name = this.dir.substring(lastIndexOf);
    }

    public String getFirstImagePath()
    {
        return firstImagePath;
    }

    public void setFirstImagePath(String firstImagePath)
    {
        this.firstImagePath = firstImagePath;
    }

    public String getName()
    {
        return name;
    }
    public int getCount()
    {
        return count;
    }

    public void setCount(int count)
    {
        this.count = count;
    }



}

彈窗的類

public class ListImageDirPopupWindow extends BasePopupWindowForListView<ImageFloder>
{
    private ListView mListDir;

    public ListImageDirPopupWindow(int width, int height,
                                   List<ImageFloder> datas, View convertView)
    {
        super(convertView, width, height, true, datas);
    }

    @Override
    public void initViews()
    {
        mListDir = (ListView) findViewById(R.id.id_list_dir);
        mListDir.setAdapter(new CommonAdapter<ImageFloder>(context, mDatas,
                R.layout.list_dir_item)
        {
            @Override
            public void convert(ViewHolder helper, ImageFloder item, int i)
            {
                helper.setText(R.id.id_dir_item_name, item.getName());
                helper.setImageByUrl(R.id.id_dir_item_image,
                        item.getFirstImagePath(),false);
                helper.setText(R.id.id_dir_item_count, item.getCount() + "張");
            }
        });
    }

    public interface OnImageDirSelected
    {
        void selected(ImageFloder floder);
    }

    private OnImageDirSelected mImageDirSelected;

    public void setOnImageDirSelected(OnImageDirSelected mImageDirSelected)
    {
        this.mImageDirSelected = mImageDirSelected;
    }

    @Override
    public void initEvents()
    {
        mListDir.setOnItemClickListener(new OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id)
            {

                if (mImageDirSelected != null)
                {
                    mImageDirSelected.selected(mDatas.get(position));
                }
            }
        });
    }

    @Override
    public void init()
    {


    }

    @Override
    protected void beforeInitWeNeedSomeParams(Object... params)
    {

    }

}
public abstract class BasePopupWindowForListView<T> extends PopupWindow
{
    /**
     * 佈局文件的最外層View
     */
    protected View mContentView;
    protected Context context;
    /**
     * ListView的數據集
     */
    protected List<T> mDatas;

    public BasePopupWindowForListView(View contentView, int width, int height,
                                      boolean focusable)
    {
        this(contentView, width, height, focusable, null);
    }

    public BasePopupWindowForListView(View contentView, int width, int height,
                                      boolean focusable, List<T> mDatas)
    {
        this(contentView, width, height, focusable, mDatas, new Object[0]);

    }

    public BasePopupWindowForListView(View contentView, int width, int height,
                                      boolean focusable, List<T> mDatas, Object... params)
    {
        super(contentView, width, height, focusable);
        this.mContentView = contentView;
        context = contentView.getContext();
        if (mDatas != null)
            this.mDatas = mDatas;

        if (params != null && params.length > 0)
        {
            beforeInitWeNeedSomeParams(params);
        }

        setBackgroundDrawable(new BitmapDrawable());
        setTouchable(true);
        setOutsideTouchable(true);
        setTouchInterceptor(new OnTouchListener()
        {
            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                if (event.getAction() == MotionEvent.ACTION_OUTSIDE)
                {
                    dismiss();
                    return true;
                }
                return false;
            }
        });
        initViews();
        initEvents();
        init();
    }

    protected abstract void beforeInitWeNeedSomeParams(Object... params);

    public abstract void initViews();

    public abstract void initEvents();

    public abstract void init();

    public View findViewById(int id)
    {
        return mContentView.findViewById(id);
    }

    protected static int dpToPx(Context context, int dp)
    {
        return (int) (context.getResources().getDisplayMetrics().density * dp + 0.5f);
    }

}

上傳文件引用的okhttphutlis


    /**
     * 上傳文件的
     *
     * @param url
     * @param file  文件
     * @param image 文件名,後臺的字段
     * @param Login
     */
    public static void LoginAddFile(String url, File[] file, String[] image, String[] parameter, String[] content, final OnLoginListener Login) {
        PostFormBuilder postFormBuilder = OkHttpUtils.post().url(url);
        for (int i = 0; i < file.length; i++) {
            postFormBuilder.addFile(image[i], file[i].getName(), file[i]);
        }
        for (int i = 0; i < parameter.length; i++) {
            postFormBuilder.addParams(parameter[i], content[i]);
        }
        postFormBuilder.build().execute(new StringCallback() {
            @Override
            public void onError(Call call, Exception e, int id) {
                if (Login != null)
                    Login.loginError(call, e, id);
            }

            @Override
            public void onResponse(String response, int id) {
                if (Login != null)
                    Login.loginSuccess(response, id);
            }
        });
    }

好了,基本改貼的都貼完了,寫的比較草草,勿怪,有不清楚的地方也可以評論,我看到就會回覆的,或者諮詢我qq,demo我就沒寫了,因爲在項目裏,就沒抽取出來,勿怪qaq。

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