GradView的使用来做仿微信的动态添加图片以及上传

**一:本文使用GradView来做图片的展示,来达到仿微信的动态添加效果
这是效果图,正在整理项目,就没有重写一个Demo,直接将我关于GradView的东西展示出来,关于项目的我会隐藏。。。
**这里写图片描述
这里写图片描述
这里写图片描述
首先分析一波,要做这个玩意,需要对GradView有一个了解,当然,我相信看这篇文章的大佬都晓得,玩有和我一样的小白也不用怕,我会将代码全部刚出来,只需要整理进去Demo运行一波就ok,话不多说,做这个玩意,我是自己写了adapter,用adapter来适配,达到动态添加的目的。
先把adapter放出来

package bitmap;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.nanjingtechlogy.quanguanban.R;

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

import My_Utils.ListDataSave;

/**
 * com.bm.falvzixun.adapter.GridViewAddImgAdpter
 *
 * @author yuandl on 2015/12/24.
 *         添加上传图片适配器
 */
public class GridViewAddImgesAdpter extends BaseAdapter {
    private List<Map<String, Object>> datas;
    private List<File> mList = new ArrayList<>();
    private Context context;
    private LayoutInflater inflater;
    /**
     * 可以动态设置最多上传几张,之后就不显示+号了,用户也无法上传了
     * 默认4张
     */
    private int maxImages = 4;

    public GridViewAddImgesAdpter(List<Map<String, Object>> datas, Context context) {
        this.datas = datas;
        this.context = context;
        inflater = LayoutInflater.from(context);
    }

    /**
     * 获取最大上传张数
     *
     * @return
     */
    public int getMaxImages() {
        return maxImages;
    }

    /**
     * 设置最大上传张数
     *
     * @param maxImages
     */
    public void setMaxImages(int maxImages) {
        this.maxImages = maxImages;
    }

    /**
     * 让GridView中的数据数目加1最后一个显示+号
     *
     * @return 返回GridView中的数量
     */
    @Override
    public int getCount() {
        int count = datas == null ? 1 : datas.size() + 1;
        if (count >= maxImages) {
            return datas.size();
        } else {
            return count;
        }
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    public void notifyDataSetChanged(List<Map<String, Object>> datas) {
        this.datas = datas;
        this.notifyDataSetChanged();

    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {


        ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item_published_grida, parent, false);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        if (datas != null && position < datas.size()) {
            final File file = new File(datas.get(position).get("path").toString());
            Glide.with(context)
                    .load(file)
                    .priority(Priority.HIGH)
                    .into(viewHolder.ivimage);
            viewHolder.btdel.setVisibility(View.VISIBLE);
            viewHolder.btdel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //判断文件是否存在
                    if (file.exists()) {
                        file.delete();
                    }
                    //移除集合中的对象

                    //我会把这个类放出来,这个是我的工具类,关于sp存储,下边我会将此处代码详细说明
                    ListDataSave dataSave = new ListDataSave(context, "PaImage");
                    List<Object> dataList = dataSave.getDataList("PaImageitem");
                    dataList.remove(position);
                    dataSave.delateData();
                    dataSave.setDataList("PaImageitem",dataList);

                    notifyDataSetChanged();
                }
            });
        } else {

            Glide.with(context)
                    .load(R.mipmap.tianjiahzaopian)
                    .priority(Priority.HIGH)
                    .centerCrop()
                    .into(viewHolder.ivimage);
            viewHolder.ivimage.setScaleType(ImageView.ScaleType.FIT_XY);
            viewHolder.btdel.setVisibility(View.GONE);
        }

        return convertView;

    }

    public class ViewHolder {
        public final ImageView ivimage;
        public final ImageView btdel;
        public final View root;

        public ViewHolder(View root) {
            ivimage = (ImageView) root.findViewById(R.id.iv_image);
            btdel = (ImageView) root.findViewById(R.id.bt_del);
            this.root = root;
        }
    }
}

接下来我把adapter用到的xml文件刚下来,不知为什么,在这儿放看不到,特意放到文章末尾

没什么难度,大家应该都看的懂,这边我将sp存储的工具类放出来

package My_Utils;

import android.content.Context;
import android.content.SharedPreferences;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

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

/**
 * Created by Administrator on 2018/3/1 0001.
 */

public class ListDataSave {
    private SharedPreferences preferences;
    private SharedPreferences.Editor editor;

    public ListDataSave(Context mContext, String preferenceName) {
        preferences = mContext.getSharedPreferences(preferenceName, Context.MODE_PRIVATE);
        editor = preferences.edit();
    }

    /**
     * 保存List
     * @param tag
     * @param datalist
     */
    public <T> void setDataList(String tag, List<T> datalist) {
        if (null == datalist || datalist.size() <= 0)
            return;

        Gson gson = new Gson();
        //转换成json数据,再保存
        String strJson = gson.toJson(datalist);
        editor.clear();
        editor.putString(tag, strJson);
        editor.commit();

    }

    /**
     * 获取List
     * @param tag
     * @return
     */
    public <T> List<T> getDataList(String tag) {
        List<T> datalist=new ArrayList<T>();
        String strJson = preferences.getString(tag, null);
        if (null == strJson) {
            return datalist;
        }
        Gson gson = new Gson();
        datalist = gson.fromJson(strJson, new TypeToken<List<T>>() {
        }.getType());
        return datalist;

    }
    public void delateData(){
        preferences.edit().clear().commit();
    }
}

这个是sp工具类,我这边使用这个主要就是为了得到GradView所展示的数据,,,具体用来干什么我会在将代码搞完后文末说逻辑

二、activity里搞事情
1、首先是xml文件,其实无比简单,一个GradView就可以

 <GridView
                   android:layout_below="@id/wu004"
                    android:id="@+id/gw"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@color/white"
                    android:columnWidth="90dp"
                    android:gravity="center"
                    android:horizontalSpacing="5dp"
                    android:numColumns="3"
                    android:stretchMode="columnWidth"
                    android:verticalSpacing="5dp" />

这个很简单,如果对GradView效果不满意,可以查看GradView的文档,各种属性。
2、activity里搞事情

 private List<Map<String, Object>> datas;
    private GridViewAddImgesAdpter gridViewAddImgesAdpter;
    private final int PHOTO_REQUEST_CAREMA = 1;// 拍照
    private final int PHOTO_REQUEST_GALLERY = 2;// 从相册中选择private static final String PHOTO_FILE_NAME = "temp_photo.jpg";
    private File tempFile;
    private final String IMAGE_DIR = Environment.getExternalStorageDirectory() + "/gridview/";
    /* 头像名称 */
    private final String PHOTO_FILE_NAME = "temp_photo.jpg";
    List<String> mList = new ArrayList<>();
    private ListDataSave dataSave;
    int y = 1;
 gw = (GridView) findViewById(R.id.gw);
 gw.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                showdialog();
            }
        });

  private void showdialog() {
        LinearLayout tv_photo;
        LinearLayout tv_camera;
        //显示弹窗
        View mView = showdialogview(R.layout.dialog_user);
        tv_camera = showId(mView, R.id.tv_camera);

        tv_photo = showId(mView, R.id.tv_photo);
        tv_camera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                openCamraYes();

            }
        });
        tv_photo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDialog.dismiss();
                //动态权限
                if (ContextCompat.checkSelfPermission(PatrolLawEnforcementActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(PatrolLawEnforcementActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                    return;
                } else {
                    gallery();//打开相册
                }

            }
        });
    }
*弹窗设置
    private View showdialogview(@LayoutRes int layoutId) {
        //显示弹窗
        mDialog = new AlertDialog.Builder(PatrolLawEnforcementActivity.this).create();
        mDialog.show();
        View mView = LayoutInflater.from(PatrolLawEnforcementActivity.this).inflate(layoutId, null);
        mDialog.setContentView(mView);
        DisplayMetrics dm = new DisplayMetrics();
        //获取屏幕信息
        this.getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenWidth = dm.widthPixels;
        int screenHeigh = dm.heightPixels;
        Window mWindow = mDialog.getWindow();
        mWindow.getDecorView().setPadding(0, 0, 0, 0);//设置padding值
        WindowManager.LayoutParams mAttributes = mWindow.getAttributes();//属性参数
        mAttributes.width = screenWidth - 150;
        mAttributes.height = screenHeigh / 6;
        mWindow.setAttributes(mAttributes);
        mWindow.setGravity(Gravity.CENTER);
        return mView;
    }
    //动态权限
  public void openCamraYes() {
        mDialog.dismiss();
        if (Build.VERSION.SDK_INT >= 23) {
            int checkCallPhonePermission = ContextCompat.checkSelfPermission(PatrolLawEnforcementActivity.this, Manifest.permission.CAMERA);
            if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(PatrolLawEnforcementActivity.this, new String[]{Manifest.permission.CAMERA}, 222);
                return;
            } else {

                camera();
            }
        } else {

            camera();
        }
    }

    /**
     * 拍照
     */
    public void camera() {
        // 判断存储卡是否可以用,可用进行存储
        if (hasSdcard()) {

            File dir = new File(IMAGE_DIR);
            if (!dir.exists()) {
                dir.mkdir();
            }
            tempFile = new File(dir,
                    System.currentTimeMillis() + "_" + PHOTO_FILE_NAME);
            //从文件中创建uri
            Uri uri = Uri.fromFile(tempFile);
            Intent intent = new Intent();
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
            intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.addCategory(intent.CATEGORY_DEFAULT);
            // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA
            startActivityForResult(intent, PHOTO_REQUEST_CAREMA);
        } else {
            Toast.makeText(this, "未找到存储卡,无法拍照!", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 判断sdcard是否被挂载
     */
    public boolean hasSdcard() {
        return Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED);
    }
     /**
     * 从相册获取2
     */
    public void gallery() {
        Intent intent = new Intent(
                Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, PHOTO_REQUEST_GALLERY);
    }
 /**
     * 上传图片
     *
     * @param path
     */
    private void uploadImage(final String path) {
        new Thread() {
            @Override
            public void run() {
                if (new File(path).exists()) {
                    Log.d("images", "源文件存在" + path);
                } else {
                    Log.d("images", "源文件不存在" + path);
                }

                File dir = new File(IMAGE_DIR);
                if (!dir.exists()) {
                    dir.mkdir();
                }
                final File file = new File(dir + "/temp_photo" + System.currentTimeMillis() + ".jpg");
                NativeUtil.compressBitmap(path, file.getAbsolutePath(), 50);
                if (file.exists()) {
                    Log.d("images", "压缩后的文件存在" + file.getAbsolutePath());
                } else {
                    Log.d("images", "压缩后的不存在" + file.getAbsolutePath());
                }
                Message message = new Message();
                message.what = 0xAAAAAAAA;
                message.obj = file.getAbsolutePath();
                mHandler.sendMessage(message);

            }
        }.start();

    }

    public void photoPath(String path) {
        Map<String, Object> map = new HashMap<>();
        map.put("path", path);
        datas.add(map);
        if (y == 1) {
            mList.add(path);
            dataSave = new ListDataSave(this, "PaImage");
            dataSave.setDataList("PaImageitem", mList);
            y++;
        } else {
            List<Object> dataList = dataSave.getDataList("PaImageitem");
            dataSave.delateData();
            dataList.add(path);
            dataSave.setDataList("PaImageitem", dataList);
        }
        gridViewAddImgesAdpter.notifyDataSetChanged();
    }

//handler里边,用handler来进行更新UI
 private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0xAAAAAAAA:
                    photoPath(msg.obj.toString());
                   break;

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == PHOTO_REQUEST_GALLERY) {
                // 从相册返回的数据
                if (data != null) {
                    // 得到图片的全路径
                    Uri uri = data.getData();
                    String[] proj = {MediaStore.Images.Media.DATA};
                    //好像是android多媒体数据库的封装接口,具体的看Android文档
                    Cursor cursor = managedQuery(uri, proj, null, null, null);
                    //按我个人理解 这个是获得用户选择的图片的索引值
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    //将光标移至开头 ,这个很重要,不小心很容易引起越界
                    cursor.moveToFirst();
                    //最后根据索引值获取图片路径
                    String path = cursor.getString(column_index);


                    uploadImage(path);
                }

            } else if (requestCode == PHOTO_REQUEST_CAREMA) {
                if (resultCode != RESULT_CANCELED) {
                    // 从相机返回的数据
                    if (hasSdcard()) {
                        if (tempFile != null) {
                            uploadImage(tempFile.getPath());
                        } else {
                            Toast.makeText(this, "相机异常请稍后再试!", Toast.LENGTH_SHORT).show();
                        }

                        Log.i("images", "拿到照片path=" + tempFile.getPath());
                    } else {
                        Toast.makeText(this, "未找到存储卡,无法存储照片!", Toast.LENGTH_SHORT).show();
                    }
                }
            }

        }
    }

//下面这个是动态权限获取
  @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            //就像onActivityResult一样这个地方就是判断你是从哪来的。
            case 222:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission Granted
                    openCamra(0);
                } else {
                    // Permission Denied
                    Toast.makeText(PatrolLawEnforcementActivity.this, "很遗憾你把相机权限禁用了。请务必开启相机权限享受我们提供的服务吧。", Toast.LENGTH_SHORT)
                            .show();
                }
                break;
            default:
        }
    }

好了,主要代码全部上去了,应该是没什么遗漏,毕竟是整理嘛,这里写图片描述
这些代码和adapter代码对应,这是我为了获取GradView里边的信息,所搞得,我这边主要就是在页面下边进行点击将最终的图片数据传到服务器,又不能传加载 的哪一张图片,所有我就用sp存储来做,先在这边加数据添加,在adapter进行删除的时候在将删除的数据从adapter删除出去,取数据的时候直接从sp取就行,大家看代码应该能搞懂,其实用数据库也能做,但是这边需要进行好几次删除操作,我想了想就先用sp存储来做,可能要比数据库要好一点把。
到此结束,我贴代码还时比较全面的,基本该有的都有了,万一剩几个也是小事儿,大家随便就能补好,无伤大雅。
恩,就这样,大家万一有什么问题的话,直接在下方评论就行,我经常在网上查资料,看到就给大家解答。大家有好的解决GradView获取最终数据的方法欢迎留下,我急需啊,现在这个获取方法看着好难受,完全不够美观健壮。
*下方是adapter的xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="74dp"
    android:layout_height="80dp">
    <FrameLayout
        android:layout_width="74dp"
        android:layout_height="80dp">

        <ImageView
            android:id="@+id/iv_image"
            android:layout_width="68dp"
            android:layout_height="68dp"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="5dp"
            android:scaleType="fitXY"
            android:src="@mipmap/tianjiahzaopian" />

        <LinearLayout
            android:layout_width="74dp"
            android:layout_height="wrap_content"
            android:gravity="right">

            <ImageView
                android:id="@+id/bt_del"
                android:layout_width="18dp"
                android:layout_height="18dp"
                android:src="@mipmap/shanchu"
                android:visibility="gone" />
        </LinearLayout>
    </FrameLayout>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值