1. 程式人生 > 其它 >仿朋友圈相簿圖片選擇以及畫廊效果

仿朋友圈相簿圖片選擇以及畫廊效果

技術標籤:Androidandroid仿微信朋友圈畫廊效果

仿朋友圈相簿圖片選擇以及畫廊效果

1.效果展示

該demo適配Android 6、7、10。畫廊效果,支援縮放效果。
視訊展示:
(等我B站視訊稽核通過再來修改)
部分截圖:在這裡插入圖片描述
在這裡插入圖片描述
文章有點長,如果沒時間就拉到最底下下載原始碼,再給個一鍵三聯哈(* ̄︶ ̄)

2.匯入相關第三方庫依賴

站在巨人的肩膀上,敲程式碼便可事半功倍。

在這裡插入圖片描述

    //圖片載入框架
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    //黃油刀
    implementation 'com.jakewharton:butterknife:10.2.3'
    annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
    // 圖片選擇器
    api 'com.zhihu.android:matisse:0.5.3-beta3'
//動態許可權申請 implementation 'com.yanzhenjie:permission:2.0.3' //rv implementation 'androidx.recyclerview:recyclerview:1.0.0' //rv第三方萬能介面卡 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4' //頂部標題欄 implementation 'com.wuhenzhizao:titlebar:1.0.7' //圖片縮放框架 implementation 'com.github.chrisbanes:PhotoView:2.3.0'

3.編寫選擇圖片頁面

在這裡插入圖片描述

a.編寫佈局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:orientation="vertical">

    <com.wuhenzhizao.titlebar.widget.CommonTitleBar
        android:id="@+id/title"
        style="@style/StyleTitle"
        app:centerText="@string/wechat_zone"
        app:leftType="none"
        app:showBottomLine="true" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@mipmap/home_bg_float"
        android:orientation="vertical">

        <EditText
            android:id="@+id/et_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"
            android:focusable="true"
            android:gravity="top"
            android:hint="@string/hint_text"
            android:lineSpacingExtra="9dp"
            android:lineSpacingMultiplier="1.2"
            android:maxLength="400"
            android:minHeight="200dp"
            android:paddingLeft="15dp"
            android:paddingTop="20dp"
            android:paddingRight="15dp"
            android:paddingBottom="20dp"
            android:textColor="@color/text_primary"
            android:textColorHint="@color/dialog_cancel_text_color"
            android:textSize="13sp" />

        <TextView
            android:id="@+id/tv_count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:layout_marginRight="15dp"
            android:layout_marginBottom="5dp"
            android:text="0/400"
            android:textColor="@color/dialog_cancel_text_color"
            android:textSize="14sp" />

        <View style="@style/StyleLine" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_photo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/dp_10" />
    </LinearLayout>

    <Button
        android:id="@+id/btn_submit"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_margin="@dimen/dp_10"
        android:background="@mipmap/home_bg_float"
        android:text="@string/submit" />
</LinearLayout>

b.編寫Activity

public class MainActivity extends AppCompatActivity implements OnItemClickListener, OnItemChildClickListener, TextWatcher {
    @BindView(R.id.rv_photo)
    RecyclerView mRvPhoto;
    @BindView(R.id.activity_main)
    LinearLayout mActivityMain;
    @BindView(R.id.title)
    CommonTitleBar mTitle;
    @BindView(R.id.et_content)
    EditText mEtContent;
    @BindView(R.id.tv_count)
    TextView mTvCount;
    @BindView(R.id.btn_submit)
    Button mBtnSubmit;
    private PhotoAdapter mPhotoAdapter;
    //點選item的時候通過判斷是否有照片檔案list,有值跳畫廊ac,沒值彈框
    private List<PhotoVo> mPhotoList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initViews();
    }

    private void initViews() {
        mPhotoAdapter = new PhotoAdapter();
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
        mRvPhoto.setLayoutManager(gridLayoutManager);
        mPhotoAdapter.setList(dealWithList(mPhotoList));
        mRvPhoto.setAdapter(mPhotoAdapter);
        mPhotoAdapter.setOnItemClickListener(this);
        mPhotoAdapter.setOnItemChildClickListener(this);
        mEtContent.addTextChangedListener(this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case CameraAlbumUtil.REQUEST_CODE_TAKE_PHOTO://相機回撥
                    String contentPath = CameraAlbumUtil.getInstance().getCameraPath();
                    mPhotoList.add(new PhotoVo(contentPath, new File(contentPath)));
                    mPhotoAdapter.setList(dealWithList(mPhotoList));
                    break;
                case CameraAlbumUtil.REQUEST_CODE_ALBUM://相簿回撥
                    List<String> pathList;
                    if (data != null) {
                        pathList = Matisse.obtainPathResult(data);
                        if (pathList.size() > 0) {
                            for (int i = 0; i < pathList.size(); i++) {
                                String s = pathList.get(i);
                                Uri uri = FileUtil.getImageContentUri(this, pathList.get(i));
                                mPhotoList.add(new PhotoVo(s, FileUtil.changeFile(this, uri)));
                            }
                            mPhotoAdapter.setList(dealWithList(mPhotoList));
                        }
                    }

                    break;
            }
        }
    }

    private List<PhotoVo> dealWithList(List<PhotoVo> list) {
        List<PhotoVo> newList = new ArrayList<>();
        if (list != null) newList.addAll(list);
        if (newList.size() < 4) newList.add(null);//最多隻能4張
        return newList;
    }

    @Override
    public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view,
                            int position) {
        if (adapter.getData().get(position) == null) {
            CameraAlbumUtil.getInstance().showCameraAlbumDialog(this);
        } else {
            Intent intent = new Intent(this, GalleryActivity.class);
            intent.putExtra("photoList", (Serializable) mPhotoList);
            startActivity(intent);
        }
    }

    @Override
    public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view,
                                 int position) {
        if (view.getId() == R.id.iv_delete) {//刪除按鈕
            mPhotoList.remove(mPhotoList.get(position));
            mPhotoAdapter.setList(dealWithList(mPhotoList));
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        mTvCount.setText(s.length() + "/400");
    }


}

c.相簿選擇工具類部分程式碼

/**
 * @author LJW
 * @create 2020/11/16
 * @Describe 開啟相機相簿工具類
 */
public class CameraAlbumUtil {
    public static final int REQUEST_CODE_TAKE_PHOTO = 1000;
    public static final int REQUEST_CODE_ALBUM = 1001;
    private static final String ALBUM = "ALBUM";
    private static MediaStoreCompat mediaStoreCompat;

    private CameraAlbumUtil() {
    }

    /**
     *
     * @param activity
     */
    public void showCameraAlbumDialog(Activity activity) {
        DialogUtil dialogUtil = new DialogUtil();
        dialogUtil.setClickListenerInterface(new DialogUtil.ClickListenerInterface() {
            @Override
            public void onAlbumClickListener() {
                getPermission(activity, ALBUM, REQUEST_CODE_ALBUM);
            }

            @Override
            public void onCameraClickListener() {
                getPermission(activity, "", REQUEST_CODE_TAKE_PHOTO);
            }
        });
        dialogUtil.showDialog(activity);
    }

    /**
     * @param activity    哪個介面
     * @param type        開啟相簿傳"ALBUM",其他傳""
     * @param requestCode 請求碼
     */
    public void getPermission(Activity activity, String type, int requestCode) {
        if (!AndPermission.hasPermissions(activity, Permission.CAMERA, Permission.WRITE_EXTERNAL_STORAGE)) {
            AndPermission.with(activity)
                    .runtime()
                    .permission(Permission.CAMERA, Permission.WRITE_EXTERNAL_STORAGE)
                    .onGranted(permissions -> {
                        switch (type) {
                            case ALBUM:
                                gotoAlbum(activity, requestCode);
                                break;
                            default:
                                gotoCamera(activity, requestCode);
                                break;
                        }
                    })
                    .onDenied(permissions -> {
                    })
                    .start();
        } else {
            switch (type) {
                case ALBUM:
                    gotoAlbum(activity, requestCode);
                    break;
                default:
                    gotoCamera(activity, requestCode);
                    break;
            }
        }
    }

    /**
     * 開啟相機
     *
     * @param activity
     * @param requestCode 請求碼
     */
    public void gotoCamera(Activity activity, int requestCode) {
        mediaStoreCompat = new MediaStoreCompat(activity);
        mediaStoreCompat.setCaptureStrategy(new CaptureStrategy(false,
                "com.example.viewpagegallery.fileProvider",
                "preventpro"));
        mediaStoreCompat.dispatchCaptureIntent(activity, requestCode);
    }

    /**
     * 開啟相簿
     *
     * @param activity
     * @param requestCode 請求碼
     */
    public void gotoAlbum(Activity activity, int requestCode) {
        Matisse.from(activity)
                .choose(MimeType.ofAll())
                .countable(true)
                .maxSelectable(4)
                .gridExpectedSize(activity.getResources().getDimensionPixelSize(R.dimen.grid_expected_size))
                .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
                .thumbnailScale(0.85f)
                .imageEngine(new GlideEngine())
                .showPreview(false) // Default is `true`
                .capture(false) //是否提供拍照功能
                .captureStrategy(new CaptureStrategy(true, "com.example.viewpagegallery.fileProvider"))//儲存到哪裡
                .forResult(requestCode);
    }

    /**
     * 獲取拍照後的地址,方便上傳使用
     *
     * @return
     */
    public String getCameraPath() {
        return mediaStoreCompat.getCurrentPhotoPath();
    }

    public static class SingleInstance {
        private static CameraAlbumUtil cameraAlbumSingle = new CameraAlbumUtil();
    }

    public static CameraAlbumUtil getInstance() {
        return SingleInstance.cameraAlbumSingle;
    }
}

d.相簿4宮圖介面卡

public class PhotoAdapter extends BaseQuickAdapter<PhotoVo, BaseViewHolder> {
    public PhotoAdapter() {
        super(R.layout.item_phtoto);
    }

    @Override
    protected void convert(@NotNull BaseViewHolder holder, PhotoVo photoVo) {
        if (photoVo != null && photoVo.getFile() != null) {//空圖
            CornerTransform transformation = new CornerTransform(getContext(), ScreenUtils.dip2px(getContext(), 10));
            Glide.with(getContext()).load(photoVo.getFile().getPath())
                    .transform(transformation)
                    .into((ImageView) holder.getView(R.id.iv_img));
            holder.setVisible(R.id.iv_empty, false);
            holder.setVisible(R.id.iv_delete, true);
            holder.setVisible(R.id.iv_img, true);
        } else {//有圖
            holder.setVisible(R.id.iv_empty, true);
            holder.setGone(R.id.iv_delete, true);
            holder.setGone(R.id.iv_img, true);
        }

        holder.getView(R.id.iv_delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setOnItemChildClick(v, holder.getAdapterPosition());
            }
        });
    }
}

4.編寫畫廊頁面

在這裡插入圖片描述

a.編寫畫廊頁面

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFC0CB"
    android:clipChildren="false">

    <com.wuhenzhizao.titlebar.widget.CommonTitleBar
        android:id="@+id/title"
        style="@style/StyleTitle"
        app:centerText="@string/gallery_title"
        app:showBottomLine="true" />

    <com.example.viewpagegallery.MyViewPager
        android:id="@+id/viewPager"
        android:layout_width="240dp"
        android:layout_height="400dp"
        android:layout_centerInParent="true"
        android:clipChildren="false" />

    <TextView
        tools:text="1/4"
        android:id="@+id/tv_num_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center_horizontal|bottom"
        android:layout_marginBottom="30dp"
        android:textColor="#909090"
        android:textSize="18sp" />
</RelativeLayout>

b.編寫Activity


public class GalleryActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {

    @BindView(R.id.viewPager)
    MyViewPager viewPager;
    @BindView(R.id.tv_num_title)
    TextView tvNumTitle;
    @BindView(R.id.title)
    CommonTitleBar mTitle;
    private GalleryAdapter mGalleryAdapter;
    private List<PhotoVo> mPhotoList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gallery);
        ButterKnife.bind(this);
        initViews();
    }

    @SuppressLint("DefaultLocale")
    private void initViews() {
        mTitle.setListener((v, action, extra) -> {
            switch (action) {
                case CommonTitleBar.ACTION_LEFT_BUTTON:
                    finish();
                    break;
                case CommonTitleBar.ACTION_RIGHT_TEXT:
                    break;
            }
        });
        mPhotoList = (List<PhotoVo>) getIntent().getSerializableExtra("photoList");
        mGalleryAdapter = new GalleryAdapter(mPhotoList, this);
        tvNumTitle.setText(String.format("%d/%d", 1, mPhotoList.size()));
        viewPager.setAdapter(mGalleryAdapter);
        viewPager.addOnPageChangeListener(this);
        viewPager.setPageTransformer(true, new RotationPageTransForm());
        viewPager.setOffscreenPageLimit(2); //下面會說到
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        // 每當頁數發生改變時重新設定一遍當前的頁數和總頁數
        tvNumTitle.setText((position + 1) + "/" + mPhotoList.size());
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

c.畫廊介面卡

public class GalleryAdapter extends PagerAdapter {
    private List<PhotoVo> mPhotos;
    private Context mContext;

    public GalleryAdapter(List<PhotoVo> mPhotos, Context mContext) {
        this.mPhotos = mPhotos;
        this.mContext = mContext;
    }

    @Override
    public int getCount() {
        return mPhotos.size();
    }

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

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_gallery, container, false);
        PhotoView photoView = view.findViewById(R.id.photo_view);
        Glide.with(mContext).load(mPhotos.get(position).getFile().getPath())
                .into(photoView);
        container.addView(view);
        return view;
    }

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

5.原始碼

在這裡插入圖片描述
創作不易,給博主一鍵三聯,可免費領取博主的愛心程式碼(詳情聯絡QQ:2872960735)(* ̄︶ ̄)
原始碼下載地址