1. 程式人生 > >使用RecyclerView選擇圖片並上傳

使用RecyclerView選擇圖片並上傳

先看效果圖:

這裡寫圖片描述

在專案中如果多處用到需要上傳照片,每次都寫重複的程式碼,未免冗餘浪費時間,本文通過封裝一個fragment,每次用時只需要在xml檔案中寫name就可以實現。
即:在當前需要上傳圖片Activity中,佈局檔案如下(fragment_select_image):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical" android:paddingLeft="12dp" android:paddingRight="12dp" tools:context="com.exiu.fragment.selectimageview.MainActivity"
>
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="22dp"> <fragment android:id="@+id/fr_image_select" android:name="com.exiu.fragment.selectimageview.SelectImageFragment"
android:layout_width="match_parent" android:layout_height="wrap_content" tools:layout="@layout/fragment_select_image">
</fragment> </LinearLayout> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="22dp" android:background="@drawable/btn_background" android:text="上傳照片" android:textColor="#ffffff" android:textSize="14sp"/> </LinearLayout>

所以,具體看一下fragment中是如何實現的:
佈局檔案僅需要一個recyclerView就可以了,如下:

public class SelectImageFragment extends Fragment {
    private RecyclerView mRecyclerView;
    private View mView;
    private ShowImageAdapter mShowImageAdapter;
    /**
     * 每次拿到的圖片url list集合
     */
    private ArrayList<String> mImageList = new ArrayList<>();
    /**
     * 一共所選擇圖片url list集合
     */
    private ArrayList<String> mTotalImageList = new ArrayList<>();
    public static final int REQUEST_CODE = 999;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.fragment_select_image, container, false);
        initViews();
        initEvents();
        return mView;
    }
    private void initViews() {
        mRecyclerView = (RecyclerView) mView.findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3));
        mShowImageAdapter = new ShowImageAdapter(getContext());
        mRecyclerView.setAdapter(mShowImageAdapter);
    }

     private void initEvents() {
        mShowImageAdapter.setOnPickerListener(new ShowImageAdapter.OnPickerListener() {
            @Override
            public void onPicker(int position) {
                //根據位置大小判斷
                // 當前是跳轉到選擇圖片Activity(MultiImageSelectorActivity)中還是預覽Activity(PhotoPreviewActivity)中
                if (position == mImageList.size()) {
                    if (position != ShowImageAdapter.MAX_NUMBER) {
                        //此處intent中攜帶的引數是根據MultiImageSelectorActivity的引數互相匹配使用,個人可根據自己的專案要求進行設定
                        Intent intent = new Intent(getActivity(), MultiImageSelectorActivity.class);
                        intent.putExtra(MultiImageSelectorActivity.EXTRA_SHOW_CAMERA, true);
                        intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_COUNT, ShowImageAdapter.MAX_NUMBER);
                        intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_MODE, MultiImageSelectorActivity.MODE_MULTI);
                        if (mImageList != null && mImageList.size() > 0) {
                            intent.putStringArrayListExtra(MultiImageSelectorActivity.EXTRA_DEFAULT_SELECTED_LIST, mImageList);
                        }
                        startActivityForResult(intent, REQUEST_CODE);
                    }
                } else {
                    //跳轉到圖片預覽介面
                    PhotoPreviewActivity.startActivity(getActivity(), position, mImageList);

                }
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CODE:
                if (getActivity().RESULT_OK == resultCode) {
                    //獲取圖片url
                    mImageList = data.getStringArrayListExtra(MultiImageSelectorActivity.EXTRA_RESULT);
                    mTotalImageList.clear();
                    for (String imageUrl : mImageList) {
                        mTotalImageList.add(imageUrl);
                    }
                    mShowImageAdapter.setImageUrlList(mTotalImageList);
                }
                break;
        }
    }
}

在這裡說明一下,MultiImageSelectorActivity 是github中開源專案MultiImageSelectorActivity ,根據其所提供的引數進行選擇引用即可。

接下來再看一下recyclerView中的Adapter的實現:
佈局item檔案:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:padding="5dp"
             android:layout_height="80dp"
             android:orientation="vertical">
    <ImageView
        android:id="@+id/iv_pic"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@mipmap/xiangji"/>
    <ImageView
        android:id="@+id/iv_del"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top|end"
        android:src="@mipmap/image_show_piceker_del"/>
</FrameLayout>

Adapter中實現主要onBindViewHolder()判斷顯示的型別,以及監聽介面設定:

public class ShowImageAdapter extends RecyclerView.Adapter<ShowImageAdapter.ViewHolder> {
    /**
     * 圖片路徑url
     */
    private List<String> mImageUrlList=new ArrayList<>();
    private Context mContext;
    /**
     * 最大選擇圖片的數量
     */
    public static final int MAX_NUMBER = 9;
    private OnPickerListener mOnPickerListener;

    public ShowImageAdapter(Context context) {
        this.mContext = context;
    }

    public void setImageUrlList(List<String> imageUrlList){
        this.mImageUrlList=imageUrlList;
        this.notifyDataSetChanged();
    }

    public void setOnPickerListener(OnPickerListener onPickerListener) {
        mOnPickerListener = onPickerListener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
        ViewHolder viewHolder=new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        //判斷位置顯示的內容
        // 如果當前圖片的數量是0,或者大於所選擇圖片的數量則顯示一個帶選擇圖片的image,同時隱藏刪除按鈕
        if (mImageUrlList.size() == 0 || mImageUrlList.size() == position) {
            holder.mImageViewDel.setVisibility(View.GONE);
            holder.mImageView.setImageBitmap(BitmapFactory.decodeResource(mContext.getResources(),R.mipmap.xiangji));
        } else {
            //否則每個圖片直接顯示刪除按鈕,並載入顯示圖片
            holder.mImageViewDel.setVisibility(View.VISIBLE);
            //glide載入圖片
            Glide.with(mContext)
                    .load(mImageUrlList.get(position))
                    .placeholder(R.mipmap.xiangji)
                    .into(holder.mImageView);

        }


    }

    @Override
    public int getItemCount() {
        return mImageUrlList.size() < MAX_NUMBER ? mImageUrlList.size() + 1 : mImageUrlList.size();
    }


    class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        ImageView mImageView, mImageViewDel;

        public ViewHolder(View itemView) {
            super(itemView);
            mImageViewDel = (ImageView) itemView.findViewById(R.id.iv_del);
            mImageView = (ImageView) itemView.findViewById(R.id.iv_pic);
            mImageViewDel.setOnClickListener(this);
            mImageView.setOnClickListener(this);

        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.iv_pic:
                    mOnPickerListener.onPicker(getLayoutPosition());
                    break;
                case R.id.iv_del:
                    mImageUrlList.remove(getLayoutPosition());
                    notifyItemRemoved(getLayoutPosition());
                    break;
                default:
                    break;
            }

        }

    }

    /**
     * recyclerView設定的監聽介面
     */
    public interface OnPickerListener{
        void onPicker(int position);
    }


}

基本流程就是這樣的,在實現了自定義fragment後,專案中需要用到上傳照片的介面直接在佈局檔案中引用即可,很方便。