GridView动态展示照片,长按删除,支持点击放大,裁剪实现

案列:进入页面,判断网络是否有资源照片,没有则默认展示添加的照片!

           点击进行图片相册的选择,这里也可以进行相机的拍照的选取!

           对照片进行裁剪,保存后上传网络!

           如需要删除,则长按删除即可!点击非第一个iten进行图片放大!

第一步:xml布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#f3f4f8"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--title-->
    <include layout="@layout/layout_title_bar"/>
    <!--请上传公司照片-->
    <TextView
        android:textSize="12sp"
        android:textColor="#979797"
        android:layout_marginTop="10dp"
        android:gravity="center_horizontal"
        android:text="请上传个人照片(9),长按可删除"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <!-- 网格显示图片 行列间距5dp 每列宽度90dp -->
    <GridView
        android:id="@+id/boss_playphoto_gridview"
        android:layout_width="fill_parent"
        android:paddingLeft="5dp"
        android:layout_height="400dp"
        android:layout_margin="10dp"
        android:layout_marginTop="20dp"
        android:columnWidth="90dp"
        android:gravity="center"
        android:horizontalSpacing="5dp"
        android:numColumns="4"
        android:stretchMode="columnWidth"
        android:verticalSpacing="5dp"/>
</LinearLayout>
第二步:封装数据到bean类中, id和imageUrl(id是后面根据它来删除对应的照片)

/**
 * @创建者 luck
 * @创建时间 ${DATA} 15:48
 * @描述 ${公司资料 - 展示照片}
 * @更新者 $Author$
 * @更新时间 $Date$
 * @更新描述 ${TODO}
 */
public class BossPersonPlayPhotoBean2{

    public Integer id;
    public String imgUrl;

    public BossPersonPlayPhotoBean2()
    {
        super();
    }

    public BossPersonPlayPhotoBean2(int id, String imgUrl)
    {
        super();
        this.id = id;
        this.imgUrl = imgUrl;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}
第三步:初始化控件

@BindView(R.id.btn_left)
Button mBtn_left;                                 //title back
@BindView(R.id.txt_title)
TextView mTxt_title;                              //title
@BindView(R.id.boss_playphoto_gridview)
GridView mBoss_playphoto_gridview;                //gridview
第四步:初始化事件(demo是直接将适配器写在这里,将数据添加到集合,在适配器那边直接在bean拿即可!)

/**
 * init-data
 */
private void initData() {
    mAdapter = new BossPersonPPAdapter(mPhotoData, UiUtils.getContext());
    mBoss_playphoto_gridview.setAdapter(mAdapter);
    mBoss_playphoto_gridview.setOnItemClickListener(this);
    mBoss_playphoto_gridview.setOnItemLongClickListener(this);
}
第五步:iten的点击事件处理(判断是否是第一个,以及展示大图的处理)

/**
 * gridview item点击
 * @param parent
 * @param view
 * @param position
 * @param id
 */
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    if (mPhotoData.size() == 10) {                               //第一张为默认图片
        UiUtils.toast("图片数9张已满");
        return;
    }
    if (position == 0) {                                        //item就添加图片,不是就展示图片
        UiUtils.toast("添加图片");                               //选择图片 这里可以设置选择的图片的格式

        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, REQUESTCODE_PICK);
    } else {                                                    //使用activity来展示大图
        Intent intent = new Intent(UiUtils.getContext(), BossPersonKeFuShowPhotoActivity.class);
        intent.putExtra("urlpath", urlpath);
        startActivity(intent);
    }
}
第六步:iten的长按点击处理

/**
 * 长按点击
 * @param parent
 * @param view
 * @param position
 * @param id
 * @return
 */
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    if (position == 0) {                     //长按的时候获取位置的信息,将其进行删除
        UiUtils.toast("请选择图片");
    } else {
        dialog(position);                    
    }
    return true;
}

第七步:长按点击进行弹框实现通知删除

/**
 * Dialog对话框提示用户删除操作
 * position为删除图片位置
 * @param position
 */
protected void dialog(final int position) {
    AlertDialog.Builder builder = new AlertDialog.Builder(BossPersonPlayPhotoActivity.this);
    builder.setMessage("确认移除已添加图片吗?");
    builder.setTitle("提示");
    builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
            BossPersonPlayPhotoBean.getInstance().postDeleteEliteImg(mPhotoData.get(position).getId());
            mPhotoData.remove(position);
            mAdapter.notifyDataSetChanged();
        }
    });
    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });
    builder.create().show();
}
第八步:进行回调设置

/**
 * 获取图片路径 响应startActivityForResult--回调
 * @param requestCode
 * @param resultCode
 * @param data
 */
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUESTCODE_PICK:                  // 直接从相册获取
            try {
                startPhotoZoom(data.getData());
            } catch (NullPointerException e) {
                e.printStackTrace();            // 用户点击取消操作
            }
            break;
        case REQUESTCODE_CUTTING:               // 取得裁剪后的图片
            if (data != null) {
                setPicToView(data);
            }
            break;
    }
}
第九步:进行裁剪的实现

/**
 * 裁剪图片方法实现
 * @param uri
 */
public void startPhotoZoom(Uri uri) {
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setDataAndType(uri, "image/*");
    // crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
    intent.putExtra("crop", "true");
    // intent.putExtra("circleCrop", "true");
    // aspectX aspectY 是宽高的比例
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    // outputX outputY 是裁剪图片宽高
    intent.putExtra("outputX", 300);
    intent.putExtra("outputY", 300);
    intent.putExtra("return-data", true);
    this.startActivityForResult(intent, REQUESTCODE_CUTTING);
}

第十步:将裁剪的可以设置到控件的上面 - 以及上传到网络

 /**
     * 保存裁剪之后的图片数据
     * @param picdata
     */
    private void setPicToView(Intent picdata) {
        Bundle extras = picdata.getExtras();
        if (extras != null) {
            mPhoto = extras.getParcelable("data");                  // 取得SDCard图片路径做显示
            Drawable drawable = new BitmapDrawable(null, mPhoto);
//            String name = "emper-icon-" + UserInfoOrSet.getAboutInt("employerId") + "_" + new SimpleDateFormat("yyyy-MM-dd-hh-MM-dd_hh:mm:ss").format(new Date());
            String name = "BossShowImg" +"_" + new SimpleDateFormat("yyyy-MM-dd-hh-MM-dd_hh:mm:ss").format(new Date());
            String path = Environment.getExternalStorageDirectory() + "/together";
            Log.d("log------------------","mPhoto="+mPhoto+"path="+path+"name="+name);
            urlpath = ImageTools.savePhotoToSDCard(mPhoto,path,name);
            Log.d("log","urlpath="+urlpath);
//            circleImageView.setImageDrawable(drawable);          //将照相的图片直接设置到图标上面--
            uploadIcon();                                          //上传 --   直接将图片进行上传即可
//            setPhoto();                                          //设置图片
        }
    }

总结:首先,我这边上传的是七牛云的服务器,因此上传的就没有进行展示吐舌头

之前,我用的是simpleadapter+gridview来写这个,如果写个demo直接展示mipmap下面的图片的时候,写的很方便,针对第一个iten的时候可以直接进行设置,但是显示设置显示网络的图片的时候会出现问题(也有两种方案解决),不注意的话也犯内存溢出问题。呵呵!还有一点就是和别人交流的就是simpleadapter的效率低的问题,难道是后面的映射等各方面可怜?不太明白!

         后来我就换了种思想:首先想到的是使用map集合实现,通过键值取对应键值,后面删除的话,也可以通过键找值取删除值,但是遇到了一问题就是在展示的时候,全部展示位同一张照片!且处理的默认图片也没有进行展示, 之后找到原因就是迭代器的hasNext();whlie循环的里面多走了一次,不知道大家是怎么解决的!可以交流哈。。。奋斗后来就直接封装到bean里面吧,用的时候直接拿吧,还可以基本上!

        后期如果扩展到照相去获取以及相册同时的话,就可以写一个popuwindow将两个添加到一起实现!

注意:展示图片可以用三方的imageoader即可!像glide也可以,其它的两个也行!比较懒,我这里用的是glide去展示,它里面的

BitmapTransformation
你可以直接去继承写圆形的或者圆角的都可以! 大笑

/**
 * 设置圆形图片
 */
public class GlideCircleTransform extends BitmapTransformation {
    public GlideCircleTransform(Context context) {
        super(context);
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;
        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;
        // TODO this could be acquired from the pool too
        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        return result;
    }

    @Override
    public String getId() {
        return getClass().getName();
    }
}
/**
 * 设置圆角方法
 */
public class GlideRoundTransform extends BitmapTransformation {

    private static float radius = 0f;

    public GlideRoundTransform(Context context) {
        this(context, 4);
    }

    public GlideRoundTransform(Context context, int dp) {
        super(context);
        this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
    }

    @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return roundCrop(pool, toTransform);
    }

    private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;
        
        int min = Math.min(source.getWidth(), source.getHeight());

        Bitmap result = pool.get(min, min, Bitmap.Config.ARGB_8888);
        //根据图片的不同分辨率,来计算切除的圆角
        radius = (Math.min(source.getWidth(), source.getHeight()) / 100f * 10f);
        
        if (result == null) {
            result = Bitmap.createBitmap(min,min, Bitmap.Config.ARGB_8888);
        }
        

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        //RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        //RectF rectF = new RectF((source.getWidth() - min)/2, (source.getHeight() - min)/2, min + (source.getWidth() - min)/2, min + (source.getHeight() - min)/2);
        RectF rectF = new RectF(0f, 0f, min, min);
        canvas.drawRoundRect(rectF, radius, radius, paint);
        return result;
    }

    @Override public String getId() {
        return getClass().getName() + Math.round(radius);
    }
}
使用:
Glide.with(imageView.getContext()).load(url).transform(new GlideRoundTransform(imageView.getContext()))
望大家指点!谢谢! 吐舌头




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在Android GridView动态添加列,可以遵循以下步骤: 1. 定义一个基本的GridView布局文件,包含GridView控件和适配器。 2. 创建一个数据源列表,用于存储GridView中要显示的数据。 3. 创建一个自定义适配器,该适配器用于将数据源列表中的数据绑定到GridView中的单元格中。 4. 在Activity或Fragment中,实例化GridView控件,并将自定义适配器设置为GridView的适配器。 5. 在需要动态添加列的时候,更新数据源列表,并调用适配器的notifyDataSetChanged()方法,以便GridView可以重新绘制。 6. 在适配器中,根据数据源列表的大小来确定GridView中应该显示的列数。可以使用GridView的setNumColumns()方法来设置列数。 以下是一个简单的示例代码,演示如何动态添加列到GridView中: ```java public class MainActivity extends AppCompatActivity { private GridView gridView; private CustomAdapter customAdapter; private List<String> dataList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gridView = findViewById(R.id.gridview); dataList = new ArrayList<>(); customAdapter = new CustomAdapter(dataList); gridView.setAdapter(customAdapter); // 动态添加一列 addColumn(); } private void addColumn() { // 更新数据源列表 dataList.add("New Column"); // 计算列数 int numColumns = (dataList.size() % 3 == 0) ? dataList.size() / 3 : (dataList.size() / 3) + 1; // 设置列数 gridView.setNumColumns(numColumns); // 刷新适配器 customAdapter.notifyDataSetChanged(); } class CustomAdapter extends BaseAdapter { private List<String> dataList; public CustomAdapter(List<String> dataList) { this.dataList = dataList; } @Override public int getCount() { return dataList.size(); } @Override public Object getItem(int position) { return dataList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false); } TextView textView = convertView.findViewById(R.id.textview); textView.setText(dataList.get(position)); return convertView; } } } ``` 在上面的示例中,我们在Activity的onCreate()方法中,实例化了一个GridView控件和一个自定义适配器。然后,我们调用了addColumn()方法,该方法会更新数据源列表,计算出应该显示的列数,并设置到GridView中。最后,我们调用了适配器的notifyDataSetChanged()方法,以便GridView可以重新绘制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值