1. 程式人生 > >【Android app】DialogFragment上ViewPager+ RecyclerView實現多頁圖片list展示

【Android app】DialogFragment上ViewPager+ RecyclerView實現多頁圖片list展示

效果圖:

                                                        

 

專案用了三個框架,感謝開源大神們為安卓做出的貢獻。

    //glide
    implementation 'com.github.bumptech.glide:glide:4.7.1'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
    //PictureSelector
    implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.2.3'
    //andpermission
    implementation 'com.yanzhenjie:permission:2.0.0-rc12'

 

DialogFragment佈局:

<?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">

    <LinearLayout
        android:id="@+id/select_photo_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/choose_image_btn1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@color/colorLight"
                android:text="@string/choose_photo1" />

            <Button
                android:id="@+id/choose_image_btn2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@color/colorLight"
                android:text="@string/choose_photo2" />

            <Button
                android:id="@+id/choose_image_btn3"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@color/colorLight"
                android:text="@string/choose_photo3" />
        </LinearLayout>


        <android.support.v4.view.ViewPager
            android:id="@+id/resource_pager"
            android:layout_width="wrap_content"
            android:layout_height="108dp" />
    </LinearLayout>
</LinearLayout>

三個button加上一個viewpager

DialogFragment的程式碼:

package com.example.viewpagertest;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;

import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.Permission;

import java.util.ArrayList;
import java.util.List;

/**
 * date: 2018/9/18
 * description: TestDialogFragment
 **/
public class TestDialogFragment extends DialogFragment implements View.OnClickListener, ViewPager.OnPageChangeListener{
    private static final int CHOOSE_PHOTO_REQUEST_1 = 1000;
    private static final int CHOOSE_PHOTO_REQUEST_2 = 1001;
    private static final int CHOOSE_PHOTO_REQUEST_3 = 1002;

    private Dialog mDialog;
    private Context mContext;
    private ViewPager mViewPager;
    private ViewPagerAdapter mViewPagerAdapter;
    private RecyclerView[] mPhotoRvs;
    private PhotoRecycleAdapter[] mAdapters;
    private ArrayList<String>[] mLists;
    private Button[] mButtons;

    private List<View> mViewList;

    private int mFocusPosition;//當前button焦點

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Activity activity = getActivity();
        final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        LayoutInflater inflater = activity.getLayoutInflater();
        View view = inflater.inflate(R.layout.dialog_layout, null);
        builder.setView(view);
        mContext = activity.getApplicationContext();
        initUI(view);
        mDialog = builder.create();

        //mDialog.setCancelable(false);
        //mDialog.setCanceledOnTouchOutside(false);

        return mDialog;
    }

    private void initUI(View view){
        mViewPager = view.findViewById(R.id.resource_pager);
        mViewPager.addOnPageChangeListener(this);
        int []buttonResAry = {R.id.choose_image_btn1, R.id.choose_image_btn2, R.id.choose_image_btn3};
        int count = buttonResAry.length;
        mLists = new ArrayList[count];
        mButtons = new Button[count];
        mPhotoRvs = new RecyclerView[count];
        mAdapters = new PhotoRecycleAdapter[count];
        mViewList = new ArrayList<>();
        for(int i=0; i<count; i++){
            mButtons[i] = view.findViewById(buttonResAry[i]);
            mButtons[i].setOnClickListener(this);
        }
        for(int i=0; i<count; i++){
            mPhotoRvs[i] = (RecyclerView) View.inflate(mContext, R.layout.photo_recycler_view, null);
            mLists[i] = new ArrayList<>();
            mAdapters[i] = new PhotoRecycleAdapter(mContext, mLists[i]);
            RecyclerView.LayoutManager manager = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false);
            mPhotoRvs[i].setLayoutManager(manager);
            mPhotoRvs[i].setAdapter(mAdapters[i]);
            mViewList.add(mPhotoRvs[i]);
        }
        mViewPagerAdapter = new ViewPagerAdapter(mViewList);
        mViewPager.setAdapter(mViewPagerAdapter);
        mFocusPosition = 0;
        updateBtn(mFocusPosition);
    }

    private void updateBtn(int position){
        for (int i=0; i<mButtons.length; i++) {
            if(i == position){
                mButtons[i].setBackgroundResource(R.color.colorDeep);
            }else {
                mButtons[i].setBackgroundResource(R.color.colorLight);
            }
        }
    }

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.choose_image_btn1){
            mFocusPosition = 0;
            updateBtn(mFocusPosition);
            mViewPager.setCurrentItem(mFocusPosition);
            requestPermission(CHOOSE_PHOTO_REQUEST_1);
        }else if(v.getId() == R.id.choose_image_btn2){
            mFocusPosition = 1;
            updateBtn(mFocusPosition);
            mViewPager.setCurrentItem(mFocusPosition);
            requestPermission(CHOOSE_PHOTO_REQUEST_2);
        }else if(v.getId() == R.id.choose_image_btn3){
            mFocusPosition = 2;
            updateBtn(mFocusPosition);
            mViewPager.setCurrentItem(mFocusPosition);
            requestPermission(CHOOSE_PHOTO_REQUEST_3);
        }
    }

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

    }

    @Override
    public void onPageSelected(int position) {
        mFocusPosition = position;
        updateBtn(mFocusPosition);
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }


    /**
     * @param request :request code
     * description : 請求許可權
     */
    private void requestPermission(final int request){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            AndPermission.with(this)
                    .runtime()
                    .permission(Permission.WRITE_EXTERNAL_STORAGE, Permission.CAMERA)
                    .onGranted(new Action<List<String>>() {
                        @Override
                        public void onAction(List<String> data) {
                            choosePhoto(request);
                        }
                    })
                    .onDenied(new Action<List<String>>() {
                        @Override
                        public void onAction(List<String> data) {
                            if (AndPermission.hasAlwaysDeniedPermission(mContext, data)) {
                                AndPermission.with(mContext).runtime().setting().start();
                            }
                        }
                    })
                    .start();
        } else {
            choosePhoto(request);
        }
    }

    /**
     * @param request
     * description : 選擇圖片
     */
    private void choosePhoto(int request) {
        PictureSelector.create(this)
                .openGallery(PictureMimeType.ofImage())
                .maxSelectNum(8)
                .imageSpanCount(4)
                .previewImage(true)
                .previewVideo(false)
                .isCamera(true)
                .compress(true)
                .forResult(request);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == -1){//選擇照片成功
            List<LocalMedia> photoList = PictureSelector.obtainMultipleResult(data);
            if(requestCode == CHOOSE_PHOTO_REQUEST_1){
                mLists[0].clear();
                for(LocalMedia media : photoList){
                    mLists[0].add(media.getCompressPath());
                }
                mAdapters[0].notifyDataSetChanged();
            }else if(requestCode == CHOOSE_PHOTO_REQUEST_2){
                for(LocalMedia media : photoList){
                    mLists[1].add(media.getCompressPath());
                }
                mAdapters[1].notifyDataSetChanged();
            }else if(requestCode == CHOOSE_PHOTO_REQUEST_3){
                for(LocalMedia media : photoList){
                    mLists[2].add(media.getCompressPath());
                }
                mAdapters[2].notifyDataSetChanged();
            }
        }
    }
}

ViewPager的adapter裡動態新增三個RecyclerView,每個view頁跟隨button聯動,點選button的時候選擇圖片,圖片選完後在onActivityResult設定對應的RecyclerView的adapter元素,notify後展示到button當前的RecyclerView上

看一看RecyclerView的layout佈局,非常簡單

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android" />

剩下的adapter程式碼也貼出來吧。

PhotoRecycleAdapter.java
package com.example.viewpagertest;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;

import java.util.List;

/**
 * date: 2018/9/18
 * description: PhotoRecycleAdapter
 **/
public class PhotoRecycleAdapter extends RecyclerView.Adapter<PhotoRecycleAdapter.ViewHolder> implements View.OnClickListener{
    private Context mContext;
    private List<String> mData;
    private OnItemClickListener mItemClickListener;

    public PhotoRecycleAdapter(Context context, List<String> urlList){
        mContext = context;
        mData = urlList;
    }

    @NonNull
    @Override
    public PhotoRecycleAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.photo_items, parent, false);
        ViewHolder holder = new ViewHolder(view);
        view.setOnClickListener(this);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull PhotoRecycleAdapter.ViewHolder holder, int position) {
        String url = mData.get(position);
        RequestOptions ro = new RequestOptions().dontAnimate().dontTransform();
        Glide.with(mContext)
                .load(url)
                .apply(ro)
                .into(holder.mImageView);
        holder.itemView.setTag(position);
    }

    @Override
    public int getItemCount() {
        return mData == null ? 0 : mData.size();
    }

    @Override
    public void onClick(View v) {
        if(mItemClickListener != null){
            mItemClickListener.onPhotoItemClick((Integer) v.getTag());
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        private ImageView mImageView;
        public ViewHolder(View itemView) {
            super(itemView);
            mImageView = itemView.findViewById(R.id.photo_image_view);
        }
    }

    public interface OnItemClickListener{
        void onPhotoItemClick(int position);
    }

    public void setItemClickListener(OnItemClickListener itemClickListener) {
        mItemClickListener = itemClickListener;
    }
}

 

ViewPagerAdapter.java
package com.example.viewpagertest;

import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

/**
 * date: 2018/9/18
 * description: ViewPagerAdapter
 **/
public class ViewPagerAdapter extends PagerAdapter {
    private List<View> viewList;//資料來源

    public ViewPagerAdapter(List<View> list){
        viewList = list;
    }

    @Override
    public int getCount() {
        return viewList==null?0:viewList.size();
    }

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

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        if(viewList != null) {
            container.removeView(viewList.get(position));
        }
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        if(viewList != null) {
            container.addView(viewList.get(position));
            return viewList.get(position);
        }
        return super.instantiateItem(container, position);
    }
}

剩下的xml佈局檔案比較簡單,就不貼了

原始碼地址 https://github.com/jadennn/ViewPagerTest