【Android app】DialogFragment上ViewPager+ RecyclerView實現多頁圖片list展示
阿新 • • 發佈:2018-11-03
效果圖:
專案用了三個框架,感謝開源大神們為安卓做出的貢獻。
//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佈局檔案比較簡單,就不貼了