您的位置:首页 > 移动开发 > Android开发

Android之基于RecycleVew的相册选择器

2016-07-23 06:34 609 查看
本文主要记录一个Android自定义的相册

相册可以实现选择图片,视频,gif(或其他任何格式文件)

源码:https://github.com/CL-window/my_photo_view

看看效果





其中RecycleView的分割线修改了一下,基本上可以实现万能分割线类了

package com.example.photoview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;

/**
* <p>Description: 分割线  (近乎万能)</p>
* Created by slack on 2016/7/21 13:56 .
*/
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {

private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable mDivider;
private int type = 0; // 分割线种类  0:水平(默认)   1:垂直   2 :网格
private int mDividerHeight = 2;//分割线高度,默认为1px
private Paint mPaint;

/**
* 默认分割线:高度为2px,颜色为灰色
* @param context
*/
public DividerGridItemDecoration(Context context) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
mDividerHeight = mDivider.getIntrinsicHeight();
a.recycle();
}

/**
* @param type  分割线种类  0:水平(默认)   1:垂直   2 :网格
*/
public DividerGridItemDecoration(Context context, int type) {
this.type = type;
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
mDividerHeight = mDivider.getIntrinsicHeight();
a.recycle();
}

/**
* @param drawableId  分割线图片(自定义drawable)
*/
public DividerGridItemDecoration(Context context, int type,int drawableId) {
this.type = type;
mDivider =  ContextCompat.getDrawable(context, drawableId);
mDividerHeight = mDivider.getIntrinsicHeight();
}

/**
* @param dividerHeight  分割线高度
* @param dividerColor  分割线颜色
*/
public DividerGridItemDecoration(Context context, int type,int dividerHeight, int dividerColor) {
this.type = type;
mDividerHeight = dividerHeight;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(dividerColor);
mPaint.setStyle(Paint.Style.FILL);

}

//绘制分割线
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {

if (type == 0) {
drawHorizontal(c, parent);
} else if (type == 1) {
drawVertical(c, parent);
}else{
drawVertical(c, parent);
drawHorizontal(c, parent);
}

}

private int getSpanCount(RecyclerView parent) {
// 列数
int spanCount = -1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {

spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
spanCount = ((StaggeredGridLayoutManager) layoutManager)
.getSpanCount();
}
return spanCount;
}

//绘制横向 item 分割线
public void drawHorizontal(Canvas canvas, RecyclerView parent) {
int childCount = parent.getChildCount();
final int left = parent.getPaddingLeft();
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDividerHeight;
if (mDivider != null) {
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
}

//绘制纵向 item 分割线
public void drawVertical(Canvas canvas, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);

final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();

final int left = child.getRight() + params.rightMargin;
final int right = left +  mDividerHeight;
if (mDivider != null) {
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
}

private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
} else {
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
return true;
}
}
return false;
}

private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
int childCount) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
return true;
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
// StaggeredGridLayoutManager 且纵向滚动
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
childCount = childCount - childCount % spanCount;
// 如果是最后一行,则不需要绘制底部
if (pos >= childCount)
return true;
} else
// StaggeredGridLayoutManager 且横向滚动
{
// 如果是最后一行,则不需要绘制底部
if ((pos + 1) % spanCount == 0) {
return true;
}
}
}
return false;
}

//获取分割线尺寸
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(0, 0, 0, mDividerHeight);
}

}
看看adapter怎么写的,图片选择时是加了一个颜色过滤器

package com.example.photoview;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* <p>Description:  </p>
* Created by slack on 2016/7/21 13:28 .
*/
public class PhotoViewAdapter extends RecyclerView.Adapter<PhotoViewAdapter.PhotoViewHolder>{

protected RecyclerView mRecyclerView;
private List<String> testData; // test
private List<Map<String,String>> data; //  title +  uri
private String[] fileType = {"video","photo","gif"};
private GifView gifView ;
private PopupWindow popwindow ;
private float downX,downY;
private int selectColor;
public boolean operation;
//    public  List<Map<String,String>> selectData = new ArrayList<>();
public String[] selectPath;//感觉使用数组会好一些,处理浪费空间
private Handler mHandler;

public PhotoViewAdapter(RecyclerView recyclerView, List<Map<String,String>> data) {
this.mRecyclerView = recyclerView;
this.data = data;
gifView = new GifView(mRecyclerView.getContext());
popwindow = new PopupWindow(gifView, FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, false);
popwindow.setAnimationStyle(R.style.popwin_anim_style); // 动画
selectColor = Color.parseColor("#77000000");
selectPath = new String[data.size()];
mHandler = new Handler(Looper.getMainLooper());

}
//    public PhotoViewAdapter(Context context, List<String> data) {
//        this.context = context;
//        this.testData = data;
//    }

@Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new PhotoViewHolder(LayoutInflater.from(mRecyclerView.getContext()).inflate(R.layout.photo_item,parent,false));
}

@Override
public void onBindViewHolder(PhotoViewHolder holder, int position) {
//缩
holder.photoView.setImageBitmap(ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(data.get(position).get("pic_path")), 300, 300));
//        holder.photoInfo.setText(data.get(position).get("title").toString());

//        holder.photoInfo.setText(testData.get(position));
}

@Override
public int getItemCount() {
return data.size();
//        return testData.size();
}

/**
* 子线程里执行,操作防止时间过长
*/
public void cancleSelect(){
new Thread(new Runnable() {
@Override
public void run() {
operation = false;
for(int i = 0; i < selectPath.length; i++){
if(!TextUtils.isEmpty(selectPath[i])){
final RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(i);
final int opt = i;
if(viewHolder != null && viewHolder instanceof PhotoViewHolder){
mHandler.post(new Runnable() {
@Override
public void run() {
((PhotoViewHolder) viewHolder).unSelect(opt);
}
});
}
}
}
}
}).start();

}

class PhotoViewHolder extends RecyclerView.ViewHolder {

ImageView photoView,selcetView;
//        TextView photoInfo;
public PhotoViewHolder(View itemView) {
super(itemView);
photoView = (ImageView) itemView.findViewById(R.id.photo_item_img);
selcetView = (ImageView) itemView.findViewById(R.id.photo_item_selcet);
//            photoInfo = (TextView)itemView.findViewById(R.id.photo_item_info);
photoView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int pos = getAdapterPosition();
//                    Log.i("slack","click..." + pos + " " + testData.get(pos) );
//                    Log.i("slack","click..." + pos + " " + data.get(pos) );
if(operation){
if (selcetView.getVisibility() == View.GONE) {
select(pos);
} else {
unSelect(pos);
}
}

}
});
photoView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
int pos = getAdapterPosition();
Log.i("slack","onLongClick..." + pos + " " + data.get(pos) );
if(fileType[2].equals(data.get(pos).get("file_type"))){
// popwindow show
// 设置好参数之后再show
gifView.setMovieResource(data.get(pos).get("pic_path"));
//                        popwindow.showAsDropDown(view);
popwindow.showAtLocation(view,Gravity.CENTER,0,0);// 显示在整个屏幕的中央
return true;
}
return false ; // 调用 onClick 事件,dissmiss
}
});
/**
* 好坑呀,一旦按住时移动,ontouch事件就不执行了
* 只能通过按住点的坐标来判断了
*/
photoView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
//                    Log.i("slack","onTouch..." + motionEvent.getX() + "," + motionEvent.getY());
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:
downX = motionEvent.getX();
downY = motionEvent.getY();
break;
case MotionEvent.ACTION_UP:
dissmissPoup();
break;
default:
if(isMove(motionEvent.getX(),motionEvent.getY()) ){
dissmissPoup();
}
break;
}

return false;
}
});

}

private void select(int pos) {
photoView.setColorFilter(selectColor);
selcetView.setVisibility(View.VISIBLE);
selectPath[pos] = data.get(pos).get("pic_path");
//                            Map<String,String> map = new HashMap<>();
//                            map.put("select_position",pos+"");
//                            map.put("pic_path",data.get(pos).get("pic_path"));
//                            selectData.add(pos,map);
}

private void unSelect(int pos) {
photoView.setColorFilter(null);
selcetView.setVisibility(View.GONE);
//                            selectData.remove() // 删还需要遍历
selectPath[pos] = "";
}

}

public void removeData(final int position) {
data.remove(position);
mHandler.post(new Runnable() {
@Override
public void run() {
notifyItemRemoved(position);
}
});
}

private void dissmissPoup() {
if( popwindow != null && popwindow.isShowing()){
popwindow.dismiss();
}
}

private boolean isMove(float x, float y) {
if(Math.abs(x - downX) > 0 || Math.abs(y - downY) > 0){
return  true;
}
return false;
}
}
gif的显示是用的前辈们的代码,mainActivtity里分别实现了图片,视频获取缩略图(直接查询数据库),获取GIF(文件夹深度遍历)

package com.example.photoview;

import android.app.Dialog;
import android.app.LoaderManager;
import android.content.CursorLoader;
import android.content.DialogInterface;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

private String filePath;
private RecyclerView mRecyclerView;
private PhotoViewAdapter mPhotoViewAdapter;
private List<Map<String, String>> mediaList = new ArrayList<>();
private List<Map<String, String>> imageList = new ArrayList<>();
private List<Map<String, String>> gifList = new ArrayList<>();
DividerGridItemDecoration mDividerGridItemDecoration;

String[] imagesColums = new String[]{
MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Media.TITLE,
MediaStore.Images.Media.MIME_TYPE,
MediaStore.Images.Media.DATE_MODIFIED
};
String[] mediaThumbColumns = new String[]{
MediaStore.Video.Thumbnails.DATA,
MediaStore.Video.Thumbnails.VIDEO_ID
};
String[] mediaColumns = new String[]{
MediaStore.Video.Media.DATA,
MediaStore.Video.Media._ID,
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.MIME_TYPE,
MediaStore.Images.Media.DATE_MODIFIED
};

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

initView();
//        initData();
//        scanImage();
//        scanVideo();

scanGif();
}

private void scanGif() {
new Thread(new Runnable() {
@Override
public void run() {
scanGif("gif", filePath);
if (gifList.size() > 0) {
Log.i("slack", "size:" + gifList.size());
if (gifList.size() <= 4) {
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
mRecyclerView.removeItemDecoration(mDividerGridItemDecoration);
mDividerGridItemDecoration = new DividerGridItemDecoration(MainActivity.this);
mRecyclerView.addItemDecoration(mDividerGridItemDecoration);
}
mPhotoViewAdapter = new PhotoViewAdapter(mRecyclerView, gifList);
mRecyclerView.setAdapter(mPhotoViewAdapter);
}
}
}).start();
}

// 根据文件夹路径读取里面的 gif 图片
private void scanGif(String type, String path) {
File file = new File(path);
if (!file.exists()) {
return;
}
File[] files = file.listFiles();
Map<String, String> map;
if (files != null) {
for (File f : files) {
if (!f.isDirectory()) {
if (isType(type, f.getName())) {
map = new HashMap<>();
map.put("pic_path", f.getAbsolutePath());
map.put("file_type", type);
gifList.add(map);
//                        Log.i("slack","path " +  f.getPath() + "    " +
//                        f.getAbsolutePath());
}
} else {
scanGif(type, path + File.separator + f.getName());
}
}
}
}

private boolean isType(String type, String name) {
if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) {
return false;
}
if (name.length() > (type.length() + 1)) {
if (type.equals(name.substring(name.lastIndexOf(".") + 1))) {
return true;
}
}
return false;
}

//  缩略图路径 thumbPath 文件路径filePath
private void scanVideo() {
getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// SELECT * FROM TABLE limit 0, 1 SORT BY DATE_MODIFIED DESC
return new CursorLoader(MainActivity.this,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, mediaColumns, null, null, MediaStore.Images.Media.DATE_MODIFIED + " DESC");
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (data != null && !data.isClosed() && data.getCount() > 0) {
Log.i("slack", "Count: " + data.getCount());
//                    data.moveToFirst();
String path;
Map<String, String> map;
File file;
while (data.moveToNext()) {
path = data.getString(data.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
map = new HashMap<>();
map.put("file_path", path);
//                        Log.i("slack", "filePath: " + path);
//                        Log.i("slack", "title: " + data.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE) );
//获取当前Video对应的Id,然后根据该ID获取其Thumb
int id = data.getInt(data.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
Cursor thumbCursor = getContentResolver().query(MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, mediaThumbColumns, MediaStore.Video.Thumbnails.VIDEO_ID + "=?", new String[]{id + ""}, null);

if (thumbCursor.moveToFirst()) {
path = thumbCursor.getString(thumbCursor.getColumnIndexOrThrow(MediaStore.Video.Thumbnails.DATA));
//                            Log.i("slack","thumbPath: " + path);
map.put("pic_path", path);
}
Log.i("slack", map.get("file_path") + "," + map.get("pic_path"));
mediaList.add(map);
}
data.close();
System.gc();
} else {
Log.i("slack", "no data");
}
Log.i("slack", "mediaList: " + mediaList.size());
mPhotoViewAdapter = new PhotoViewAdapter(mRecyclerView, mediaList);
mRecyclerView.setAdapter(mPhotoViewAdapter);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
});
}

private void scanImage() {

getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// SELECT * FROM TABLE limit 0, 1 SORT BY DATE_MODIFIED DESC
return new CursorLoader(MainActivity.this,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imagesColums, null, null, MediaStore.Images.Media.DATE_MODIFIED + " DESC");
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (data != null && !data.isClosed() && data.getCount() > 0) {
Log.i("slack", "Count: " + data.getCount());
data.moveToFirst();
String path;
Map<String, String> map;
File file;
while (data.moveToNext()) {
path = data.getString(data.getColumnIndex(MediaStore.Images.Media.DATA));
map = new HashMap<>();
map.put("pic_path", path);
imageList.add(map);
//                        Log.i("slack", "Path: " + path);
//                        Log.i("slack", "Date: " + data.getString(data.getColumnIndex(MediaStore.Images.Media.DATE_MODIFIED)));
}
data.close();
System.gc();
} else {
Log.i("slack", "no data");
}
Log.i("slack", "imageList: " + imageList.size());
mPhotoViewAdapter = new PhotoViewAdapter(mRecyclerView, imageList);
mRecyclerView.setAdapter(mPhotoViewAdapter);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
});
}

private void initData() {
//        ArrayList<String> mDatas = new ArrayList<String>();
//        for (int i = 'A'; i < 'z'; i++){
//            mDatas.add("" + (char) i);
//        }
//        mPhotoViewAdapter = new PhotoViewAdapter(this,mDatas);
}

TextView right;
View cancleView;

private void initView() {
filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Movies";
mDividerGridItemDecoration = new DividerGridItemDecoration(this, 2);
mRecyclerView = (RecyclerView) findViewById(R.id.photo_recyclerview);
//设置布局管理器
//        mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));  // 现行管理器,支持横向、纵向。
//        mRecyclerView.setLayoutManager(new GridLayoutManager(this,4));  // 网格布局,没行4个
// 瀑布流式的布局 VERTICAL代表有多少列   HORIZONTAL 就代表有多少行
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.HORIZONTAL));
//设置adapter
//        mRecyclerView.setAdapter(mPhotoViewAdapter);

//设置Item增加、移除动画
//        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//添加分割线
mRecyclerView.addItemDecoration(mDividerGridItemDecoration);

right = (TextView) findViewById(R.id.head_rigth);
cancleView = findViewById(R.id.cancle_view);
cancleView.setVisibility(View.GONE);
right.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//                Log.i("slack","click...right");
if (cancleView.getVisibility() == View.GONE) {
cancleView.setVisibility(View.VISIBLE);
right.setText("删除");
mPhotoViewAdapter.operation = true;
} else {
Log.i("slack", "click...del");
deleteSelect();
}
}
});
findViewById(R.id.cancle).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//                Log.i("slack","click...cancle");
cancleSelect();

}
});
}

private void cancleSelect() {
cancleView.setVisibility(View.GONE);
right.setText("操作");
mPhotoViewAdapter.cancleSelect();
}

private void deleteSelect() {
new AlertDialog.Builder(this).setMessage("确认删除这些吗?")
.setTitle("温馨提示")
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < mPhotoViewAdapter.selectPath.length; i++) {
if (!TextUtils.isEmpty(mPhotoViewAdapter.selectPath[i])) {
mPhotoViewAdapter.removeData(i);
new File(mPhotoViewAdapter.selectPath[i]).delete();
}
}
}
}).start();
cancleSelect();
dialog.dismiss();
}
}).setNegativeButton("取消", null).show();

}
}
图片单击进入预览的没有做,不是本次的重点,其实list里有图片的路径,这个功能实现也简单,把那个路径传过去,把图片加载出来就可以了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息