欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现QQ图片说说照片选择效果

程序员文章站 2023-11-28 21:15:04
本文实例为大家分享了android实现qq图片说说照片选择的具体代码,供大家参考,具体内容如下 效果展示 布局文件 布局是很简单的,一个gridview,直接上布局:...

本文实例为大家分享了android实现qq图片说说照片选择的具体代码,供大家参考,具体内容如下

效果展示

Android实现QQ图片说说照片选择效果布局文件

布局是很简单的,一个gridview,直接上布局:

layout/activity_add_photo.xml

<?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"
 android:orientation="vertical">

 <relativelayout
  android:layout_width="match_parent"
  android:layout_height="60dp"
  android:background="#00bb9c">

  <textview
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerinparent="true"
   android:text="写动态"
   android:textappearance="?android:attr/textappearancelarge"
   android:textcolor="@android:color/white" />

  <textview
   android:id="@+id/send"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_alignparentright="true"
   android:layout_centervertical="true"
   android:layout_marginright="10dp"
   android:text="发送"
   android:textappearance="?android:attr/textappearancelarge"
   android:textcolor="@android:color/white" />

 </relativelayout>

 <linearlayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_margin="16dp"
  android:orientation="vertical">

  <edittext
   android:layout_width="match_parent"
   android:layout_height="100dp"
   android:enabled="false"
   android:focusable="false"
   android:gravity="top"
   android:hint="分享您的那点新鲜事儿..."
   android:maxlines="5" />

  <linearlayout
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:padding="5dp">

   <gridview
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:numcolumns="4" />

  </linearlayout>  

 </linearlayout>

</linearlayout>

layout/activity_add_photo_gv_items.xml 使用了自定义的view使得布局为正方形

<?xml version="1.0" encoding="utf-8"?>
<com.shenhua.tabhostdemo.selectimg.squarerelativelayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content">

 <imageview
  android:id="@+id/main_gridview_item_photo"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_centerinparent="true"
  android:contentdescription="@null"
  android:padding="5dp"
  android:scaletype="fitxy" />

 <checkbox
  android:id="@+id/main_gridview_item_cb"
  android:layout_width="20dp"
  android:layout_height="20dp"
  android:layout_alignparentend="true"
  android:layout_alignparentright="true"
  android:layout_alignparenttop="true"
  android:layout_margin="2dp"
  android:background="@drawable/ic_delete"
  android:backgroundtint="#00bb9c"
  android:button="@null" />

</com.shenhua.tabhostdemo.selectimg.squarerelativelayout>

代码实现

squarerelativelayout.java:

package com.shenhua.tabhostdemo.selectimg;

import android.content.context;
import android.util.attributeset;
import android.widget.relativelayout;

/**
 * 自定义方形布局
 * created by shenhua on 4/25/2016.
 */
public class squarerelativelayout extends relativelayout {
 public squarerelativelayout(context context, attributeset attrs, int defstyle) {
  super(context, attrs, defstyle);
 }

 public squarerelativelayout(context context, attributeset attrs) {
  super(context, attrs);
 }

 public squarerelativelayout(context context) {
  super(context);
 }

 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
  setmeasureddimension(getdefaultsize(0, widthmeasurespec), getdefaultsize(0, heightmeasurespec));
  int childwidthsize = getmeasuredwidth();
  widthmeasurespec = measurespec.makemeasurespec(childwidthsize, measurespec.exactly);
  heightmeasurespec = widthmeasurespec;
  super.onmeasure(widthmeasurespec, heightmeasurespec);
 }
}

uploadphotoactivity.java: 主activity

package com.shenhua.tabhostdemo.selectimg;

import android.content.intent;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.net.uri;
import android.os.bundle;
import android.support.annotation.nullable;
import android.support.v7.app.appcompatactivity;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.widget.adapterview;
import android.widget.baseadapter;
import android.widget.checkbox;
import android.widget.gridview;
import android.widget.imageview;
import android.widget.textview;
import android.widget.toast;

import com.shenhua.tabhostdemo.r;

import java.io.bytearrayoutputstream;
import java.util.arraylist;
import java.util.list;

/**
 * created by shenhua on 4/25/2016.
 */
public class uploadphotoactivity extends appcompatactivity {

 private static final int img_count = 8;
 private static final string img_add_tag = "a";
 private gridview gridview;
 private gvadapter adapter;
 private textview textview;
 private imageview img;
 private list<string> list;

 @override
 protected void oncreate(@nullable bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_add_photo);
  gridview = (gridview) findviewbyid(r.id.gridview);
  textview = (textview) findviewbyid(r.id.send);
  textview.setonclicklistener(new view.onclicklistener() {
   @override
   public void onclick(view v) {
    system.out.println("发送:" + integer.tostring(list.size() - 1));
    upload();
   }
  });
  initdata();
 }

 private void upload() {
  bitmap bitmap;
  bitmap bmpcompressed;
  for (int i = 0; i < list.size() - 1; i++) {
   bitmap = bitmapfactory.decodefile(list.get(i));
   bmpcompressed = bitmap.createscaledbitmap(bitmap, 640, 480, true);
   bytearrayoutputstream bos = new bytearrayoutputstream();
   bmpcompressed.compress(bitmap.compressformat.jpeg, 100, bos);
   byte[] data = bos.tobytearray();
   system.out.println(data);
  }

 }

 private void initdata() {
  if (list == null) {
   list = new arraylist<>();
   list.add(img_add_tag);
  }
  adapter = new gvadapter();
  gridview.setadapter(adapter);
  gridview.setonitemclicklistener(new adapterview.onitemclicklistener() {

   @override
   public void onitemclick(adapterview<?> parent, view view, int position, long id) {
    if (list.get(position).equals(img_add_tag)) {
     if (list.size() < img_count) {
      intent i = new intent(intent.action_pick, android.provider.mediastore.images.media.external_content_uri);
      startactivityforresult(i, 0);
     } else
      toast.maketext(uploadphotoactivity.this, "最多只能选择7张照片!", toast.length_short).show();
    }
   }
  });
  refreshadapter();
 }

 private void refreshadapter() {
  if (list == null) {
   list = new arraylist<>();
  }
  if (adapter == null) {
   adapter = new gvadapter();
  }
  adapter.notifydatasetchanged();
 }

 private class gvadapter extends baseadapter {

  @override
  public int getcount() {
   return list.size();
  }

  @override
  public object getitem(int position) {
   return null;
  }

  @override
  public long getitemid(int position) {
   return 0;
  }

  @override
  public view getview(final int position, view convertview, viewgroup parent) {
   final viewholder holder;
   if (convertview == null) {
    convertview = layoutinflater.from(getapplication()).inflate(r.layout.activity_add_photo_gv_items, parent, false);
    holder = new viewholder();
    holder.imageview = (imageview) convertview.findviewbyid(r.id.main_gridview_item_photo);
    holder.checkbox = (checkbox) convertview.findviewbyid(r.id.main_gridview_item_cb);
    convertview.settag(holder);
   } else {
    holder = (viewholder) convertview.gettag();
   }
   string s = list.get(position);
   if (!s.equals(img_add_tag)) {
    holder.checkbox.setvisibility(view.visible);
    holder.imageview.setimagebitmap(imagetool.createimagethumbnail(s));
   } else {
    holder.checkbox.setvisibility(view.gone);
    holder.imageview.setimageresource(r.mipmap.ic_photo_upload);
   }
   holder.checkbox.setonclicklistener(new view.onclicklistener() {
    @override
    public void onclick(view v) {
     list.remove(position);
     refreshadapter();
    }
   });
   return convertview;
  }

  private class viewholder {
   imageview imageview;
   checkbox checkbox;
  }

 }

 @override
 protected void onactivityresult(int requestcode, int resultcode, intent data) {
  super.onactivityresult(requestcode, resultcode, data);
  if (data == null) {
   system.out.println("data null");
   return;
  }
  if (requestcode == 0) {
   final uri uri = data.getdata();
   string path = imagetool.getimageabsolutepath(this, uri);
   system.out.println(path);
   if (list.size() == img_count) {
    removeitem();
    refreshadapter();
    return;
   }
   removeitem();
   list.add(path);
   list.add(img_add_tag);
   refreshadapter();
  }
 }

 private void removeitem() {
  if (list.size() != img_count) {
   if (list.size() != 0) {
    list.remove(list.size() - 1);
   }
  }
 }

}

imagetool.java: 图片工具类

package com.shenhua.tabhostdemo.selectimg;

import android.annotation.targetapi;
import android.app.activity;
import android.content.contenturis;
import android.content.context;
import android.database.cursor;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.net.uri;
import android.os.environment;
import android.provider.documentscontract;
import android.provider.mediastore;

/**
 * created by shenhua on 4/26/2016.
 */
public class imagetool {

 /**
  * 获取图片的绝对路径,需要添加用户权限
  */
 @targetapi(19)
 public static string getimageabsolutepath(activity context, uri imageuri) {
  if (context == null || imageuri == null)
   return null;
  if (android.os.build.version.sdk_int >= android.os.build.version_codes.kitkat && documentscontract.isdocumenturi(context, imageuri)) {
   if (isexternalstoragedocument(imageuri)) {
    string docid = documentscontract.getdocumentid(imageuri);
    string[] split = docid.split(":");
    string type = split[0];
    if ("primary".equalsignorecase(type)) {
     return environment.getexternalstoragedirectory() + "/" + split[1];
    }
   } else if (isdownloadsdocument(imageuri)) {
    string id = documentscontract.getdocumentid(imageuri);
    uri contenturi = contenturis.withappendedid(uri.parse("content://downloads/public_downloads"), long.valueof(id));
    return getdatacolumn(context, contenturi, null, null);
   } else if (ismediadocument(imageuri)) {
    string docid = documentscontract.getdocumentid(imageuri);
    string[] split = docid.split(":");
    string type = split[0];
    uri contenturi = null;
    if ("image".equals(type)) {
     contenturi = mediastore.images.media.external_content_uri;
    } else if ("video".equals(type)) {
     contenturi = null;//不获取视频
    } else if ("audio".equals(type)) {
     contenturi = null;//不获取音频
    }
    string selection = mediastore.images.media._id + "=?";
    string[] selectionargs = new string[]{split[1]};
    return getdatacolumn(context, contenturi, selection, selectionargs);
   }
  } // mediastore (and general)
  else if ("content".equalsignorecase(imageuri.getscheme())) {
   if (isgooglephotosuri(imageuri))
    return imageuri.getlastpathsegment();
   return getdatacolumn(context, imageuri, null, null);
  }
  // file
  else if ("file".equalsignorecase(imageuri.getscheme())) {
   return imageuri.getpath();
  }
  return null;
 }

 public static string getdatacolumn(context context, uri uri, string selection, string[] selectionargs) {
  cursor cursor = null;
  string column = mediastore.images.media.data;
  string[] projection = {column};
  try {
   cursor = context.getcontentresolver().query(uri, projection, selection, selectionargs, null);
   if (cursor != null && cursor.movetofirst()) {
    int index = cursor.getcolumnindexorthrow(column);
    return cursor.getstring(index);
   }
  } finally {
   if (cursor != null)
    cursor.close();
  }
  return null;
 }

 /**
  * @param uri the uri to check.
  * @return whether the uri authority is externalstorageprovider.
  */
 public static boolean isexternalstoragedocument(uri uri) {
  return "com.android.externalstorage.documents".equals(uri.getauthority());
 }

 /**
  * @param uri the uri to check.
  * @return whether the uri authority is downloadsprovider.
  */
 public static boolean isdownloadsdocument(uri uri) {
  return "com.android.providers.downloads.documents".equals(uri.getauthority());
 }

 /**
  * @param uri the uri to check.
  * @return whether the uri authority is mediaprovider.
  */
 public static boolean ismediadocument(uri uri) {
  return "com.android.providers.media.documents".equals(uri.getauthority());
 }

 /**
  * @param uri the uri to check.
  * @return whether the uri authority is google photos.
  */
 public static boolean isgooglephotosuri(uri uri) {
  return "com.google.android.apps.photos.content".equals(uri.getauthority());
 }

 /**
  * 创建图片缩略图
  *
  * @param filepath
  * @return
  */
 public static bitmap createimagethumbnail(string filepath) {
  bitmap bitmap = null;
  bitmapfactory.options opts = new bitmapfactory.options();
  opts.injustdecodebounds = true;
  bitmapfactory.decodefile(filepath, opts);
  opts.insamplesize = computesamplesize(opts, -1, 128 * 128);
  opts.injustdecodebounds = false;
  try {
   bitmap = bitmapfactory.decodefile(filepath, opts);
  } catch (exception e) {
   // todo: handle exception
  }
  return bitmap;
 }

 public static int computesamplesize(bitmapfactory.options options, int minsidelength, int maxnumofpixels) {
  int initialsize = computeinitialsamplesize(options, minsidelength, maxnumofpixels);
  int roundedsize;
  if (initialsize <= 8) {
   roundedsize = 1;
   while (roundedsize < initialsize) {
    roundedsize <<= 1;
   }
  } else {
   roundedsize = (initialsize + 7) / 8 * 8;
  }
  return roundedsize;
 }

 private static int computeinitialsamplesize(bitmapfactory.options options, int minsidelength, int maxnumofpixels) {
  double w = options.outwidth;
  double h = options.outheight;
  int lowerbound = (maxnumofpixels == -1) ? 1 : (int) math.ceil(math.sqrt(w * h / maxnumofpixels));
  int upperbound = (minsidelength == -1) ? 128 : (int) math.min(math.floor(w / minsidelength), math.floor(h / minsidelength));
  if (upperbound < lowerbound) {
   // return the larger one when there is no overlapping zone.
   return lowerbound;
  }
  if ((maxnumofpixels == -1) && (minsidelength == -1)) {
   return 1;
  } else if (minsidelength == -1) {
   return lowerbound;
  } else {
   return upperbound;
  }
 }
}

因为 android4.4以上版本获得的图片uri是com.xxxxx的,因此需要在工具类里做判断,否则得不到图片的绝对地址。

工具类参考了别人的一篇博客,忘了留博客地址了,请原博主谅解。

最后需要加上一个权限:

<uses-permission android:name="android.permission.read_external_storage" />

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。