微信朋友圈的圖片上傳,多圖上傳怎么去擼才合適?我們一起來(lái)實(shí)現(xiàn)吧_第1頁(yè)
微信朋友圈的圖片上傳,多圖上傳怎么去擼才合適?我們一起來(lái)實(shí)現(xiàn)吧_第2頁(yè)
微信朋友圈的圖片上傳,多圖上傳怎么去擼才合適?我們一起來(lái)實(shí)現(xiàn)吧_第3頁(yè)
微信朋友圈的圖片上傳,多圖上傳怎么去擼才合適?我們一起來(lái)實(shí)現(xiàn)吧_第4頁(yè)
微信朋友圈的圖片上傳,多圖上傳怎么去擼才合適?我們一起來(lái)實(shí)現(xiàn)吧_第5頁(yè)
已閱讀5頁(yè),還剩10頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、微信朋友圈的圖片上傳,多圖上傳怎么去擼才合適?我們一起來(lái)實(shí)現(xiàn)吧!圖片上傳是非常常見(jiàn)的功能,而多圖上傳在大多數(shù)應(yīng)用中也是非常常見(jiàn)的,比如微信的朋友圈,微博的動(dòng)態(tài),都是有九宮格圖片的,那這里肯定涉及了多圖上傳,所以今天我們來(lái)一起擼一下,怎么去思考這個(gè)實(shí)現(xiàn)邏輯!這里我想到的思路是比較簡(jiǎn)單的,首先,我們有一個(gè)按鈕,按鈕是上傳圖片,點(diǎn)擊之后彈出某個(gè)界面進(jìn)行圖片的選擇,一般是九張圖片或者十二張,選完之后就直接上傳了,大致的流程應(yīng)該是這個(gè)樣子,那我們首先來(lái)寫(xiě)個(gè)按鈕activity_main.xml<?xml version="1.0" encoding="utf-8&qu

2、ot;?><LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> <Button android:id="+id/btnAddPhoto" android:layout_width="match_

3、parent" android:layout_height="wrap_content" android:text="上傳圖片"/></LinearLayout>他只是一個(gè)主頁(yè),我們只要實(shí)現(xiàn)它的點(diǎn)擊事件就好了,點(diǎn)擊之后跳轉(zhuǎn)到我們的上傳圖片的ActivcityMainActivitypackage com.liuguilin.uploadphotossample;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import

4、 android.os.Bundle;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity private Button btnAddPhoto; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /點(diǎn)擊事件 findV

5、iewById(R.id.btnAddPhoto).setOnClickListener(new View.OnClickListener() Override public void onClick(View view) startActivity(new Intent(MainActivity.this,UploadPhotoActivity.class); ); 這些都是可以一筆帶過(guò)的,真正的邏輯全部都在這個(gè)UploadPhotoActivity,我們用GridView顯示圖片,并且進(jìn)行多選,下面有一個(gè)按鈕負(fù)責(zé)顯示已選圖片的數(shù)量以及完成上傳的功能activity_upload.xml&l

6、t;?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical"> <GridView and

7、roid:id="+id/mGradView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:numColumns="3"/> <Button android:id="+id/btnOk" android:layout_width="200dp" android:layout_height=&qu

8、ot;wrap_content" android:layout_margin="10dp" android:background="color/colorAccent" android:text="2/12 完成" android:textColor="android:color/white"/></LinearLayout>我們現(xiàn)在就要分析我們?cè)趺慈?shí)現(xiàn)了,這個(gè)GridView肯定是要寫(xiě)的,但是我們首先得要拿到我們的圖片,圖片怎么拿?肯定是看相冊(cè)的源碼來(lái)分析他是怎么去拿的,這里呢,我們

9、使用的是ContentResolver內(nèi)容訪問(wèn)者,我們查看下源碼,我們主要還是看MediaProvider這個(gè)項(xiàng)目我們只要看他最先的一段靜態(tài)塊static URI_MATCHER.addURI("media", "*/images/media", IMAGES_MEDIA); URI_MATCHER.addURI("media", "*/images/media/#", IMAGES_MEDIA_ID); URI_MATCHER.addURI("media", "*/images/th

10、umbnails", IMAGES_THUMBNAILS); URI_MATCHER.addURI("media", "*/images/thumbnails/#", IMAGES_THUMBNAILS_ID); URI_MATCHER.addURI("media", "*/audio/media", AUDIO_MEDIA); URI_MATCHER.addURI("media", "*/audio/media/#", AUDIO_MEDIA_ID); URI_M

11、ATCHER.addURI("media", "*/audio/media/#/genres", AUDIO_MEDIA_ID_GENRES); URI_MATCHER.addURI("media", "*/audio/media/#/genres/#", AUDIO_MEDIA_ID_GENRES_ID); URI_MATCHER.addURI("media", "*/audio/media/#/playlists", AUDIO_MEDIA_ID_PLAYLISTS);

12、URI_MATCHER.addURI("media", "*/audio/media/#/playlists/#", AUDIO_MEDIA_ID_PLAYLISTS_ID); URI_MATCHER.addURI("media", "*/audio/genres", AUDIO_GENRES); URI_MATCHER.addURI("media", "*/audio/genres/#", AUDIO_GENRES_ID); URI_MATCHER.addURI("

13、;media", "*/audio/genres/#/members", AUDIO_GENRES_ID_MEMBERS); URI_MATCHER.addURI("media", "*/audio/genres/all/members", AUDIO_GENRES_ALL_MEMBERS); URI_MATCHER.addURI("media", "*/audio/playlists", AUDIO_PLAYLISTS); URI_MATCHER.addURI("media

14、", "*/audio/playlists/#", AUDIO_PLAYLISTS_ID); URI_MATCHER.addURI("media", "*/audio/playlists/#/members", AUDIO_PLAYLISTS_ID_MEMBERS); URI_MATCHER.addURI("media", "*/audio/playlists/#/members/#", AUDIO_PLAYLISTS_ID_MEMBERS_ID); URI_MATCHER.addUR

15、I("media", "*/audio/artists", AUDIO_ARTISTS); URI_MATCHER.addURI("media", "*/audio/artists/#", AUDIO_ARTISTS_ID); URI_MATCHER.addURI("media", "*/audio/artists/#/albums", AUDIO_ARTISTS_ID_ALBUMS); URI_MATCHER.addURI("media", "

16、*/audio/albums", AUDIO_ALBUMS); URI_MATCHER.addURI("media", "*/audio/albums/#", AUDIO_ALBUMS_ID); URI_MATCHER.addURI("media", "*/audio/albumart", AUDIO_ALBUMART); URI_MATCHER.addURI("media", "*/audio/albumart/#", AUDIO_ALBUMART_ID); UR

17、I_MATCHER.addURI("media", "*/audio/media/#/albumart", AUDIO_ALBUMART_FILE_ID); URI_MATCHER.addURI("media", "*/video/media", VIDEO_MEDIA); URI_MATCHER.addURI("media", "*/video/media/#", VIDEO_MEDIA_ID); URI_MATCHER.addURI("media",

18、"*/video/thumbnails", VIDEO_THUMBNAILS); URI_MATCHER.addURI("media", "*/video/thumbnails/#", VIDEO_THUMBNAILS_ID); URI_MATCHER.addURI("media", "*/media_scanner", MEDIA_SCANNER); URI_MATCHER.addURI("media", "*/fs_id", FS_ID); URI_M

19、ATCHER.addURI("media", "*/version", VERSION); URI_MATCHER.addURI("media", "*/mtp_connected", MTP_CONNECTED); URI_MATCHER.addURI("media", "*", VOLUMES_ID); URI_MATCHER.addURI("media", null, VOLUMES); / Used by MTP implementation UR

20、I_MATCHER.addURI("media", "*/file", FILES); URI_MATCHER.addURI("media", "*/file/#", FILES_ID); URI_MATCHER.addURI("media", "*/object", MTP_OBJECTS); URI_MATCHER.addURI("media", "*/object/#", MTP_OBJECTS_ID); URI_MATCHER.

21、addURI("media", "*/object/#/references", MTP_OBJECT_REFERENCES); /* * deprecated use the 'basic' or 'fancy' search Uris instead */ URI_MATCHER.addURI("media", "*/audio/" + SearchManager.SUGGEST_URI_PATH_QUERY, AUDIO_SEARCH_LEGACY); URI_MATCHER.

22、addURI("media", "*/audio/" + SearchManager.SUGGEST_URI_PATH_QUERY + "/*", AUDIO_SEARCH_LEGACY); / used for search suggestions URI_MATCHER.addURI("media", "*/audio/search/" + SearchManager.SUGGEST_URI_PATH_QUERY, AUDIO_SEARCH_BASIC); URI_MATCHER.addUR

23、I("media", "*/audio/search/" + SearchManager.SUGGEST_URI_PATH_QUERY + "/*", AUDIO_SEARCH_BASIC); / used by the music app's search activity URI_MATCHER.addURI("media", "*/audio/search/fancy", AUDIO_SEARCH_FANCY); URI_MATCHER.addURI("media&quo

24、t;, "*/audio/search/fancy/*", AUDIO_SEARCH_FANCY); 這段代碼塊就是我們?cè)L問(wèn)系統(tǒng)數(shù)據(jù)庫(kù)索要獲取任意數(shù)據(jù)的URI,而我們?cè)L問(wèn)圖片的URI是URI_MATCHER.addURI("media", "*/images/media", IMAGES_MEDIA);11不過(guò)既然是內(nèi)容提供者,google也是封裝好了一些方法供我們使用 /* * 初始化數(shù)據(jù) */ private void initData() /獲取手機(jī)相冊(cè)圖片 訪問(wèn)本機(jī)數(shù)據(jù)庫(kù) ContentResolver mContentRes

25、olver = getContentResolver(); /圖片數(shù)據(jù)的url(外部存儲(chǔ)) Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; /查詢 Cursor cursor = mContentResolver.query(uri,null,null,null,null); /遍歷 while (cursor.moveToNext() PhotoBean bean = new PhotoBean(); /獲取路徑 String path = cursor.getString(cursor.getColumnIndex(Media

26、Store.Images.Media.DATA); /設(shè)置路徑 bean.setPath(path); /默認(rèn)fasle bean.setSelect(false); /保存 mList.add(bean); OK,當(dāng)我們拿到這些相冊(cè)的圖片肯定是要去存儲(chǔ),那我們?cè)趺慈ゴ鎯?chǔ)?一般都是用個(gè)實(shí)體對(duì)象的PhotoBeanpackage com.liuguilin.uploadphotossample;/* * 項(xiàng)目名: UploadPhotosSample * 包名: com.liuguilin.uploadphotossample * 文件名: PhotoBean * 創(chuàng)建者: LGL * 創(chuàng)建時(shí)間

27、: 2016/8/31 13:14 * 描述: 圖片存儲(chǔ)對(duì)象 */import android.graphics.Bitmap;public class PhotoBean /路徑 private String path; /是否選擇 private boolean isSelect; /位圖轉(zhuǎn)換 private Bitmap bitmap; public String getPath() return path; public void setPath(String path) this.path = path; public boolean isSelect() return isSele

28、ct; public void setSelect(boolean select) isSelect = select; public Bitmap getBitmap() return bitmap; public void setBitmap(Bitmap bitmap) this.bitmap = bitmap; OK,現(xiàn)在可以專(zhuān)心的來(lái)寫(xiě)我們的Adapter,也就是數(shù)據(jù)適配器了GridAdapterpackage com.liuguilin.uploadphotossample;/* * 項(xiàng)目名: UploadPhotosSample * 包名: com.liuguilin.upload

29、photossample * 文件名: GridAdapter * 創(chuàng)建者: LGL * 創(chuàng)建時(shí)間: 2016/8/31 13:32 * 描述: 數(shù)據(jù)適配器 */import android.content.Context;import android.graphics.Bitmap;import android.os.AsyncTask;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;impor

30、t android.widget.ImageView;import java.util.List;public class GridAdapter extends BaseAdapter /數(shù)據(jù) private List<PhotoBean> mList; /布局加載器 private LayoutInflater mInflater; /實(shí)體類(lèi) private PhotoBean bean; /上下文 private Context mContext; /屏幕寬高 private int w, h; /* * param mContext * param mList */ pub

31、lic GridAdapter(Context mContext, List<PhotoBean> mList) this.mContext = mContext; this.mList = mList; /系統(tǒng)服務(wù) mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); getPhoneWH(); /* * 獲取手機(jī)屏幕的寬高 */ private void getPhoneWH() w = mContext.getResources().getDisplay

32、Metrics().widthPixels; h = mContext.getResources().getDisplayMetrics().heightPixels; Override public int getCount() return mList.size(); Override public Object getItem(int i) return mList.get(i); Override public long getItemId(int i) return i; Override public View getView(int i, View view, ViewGroup

33、 viewGroup) ViewHolder viewHolder = null; if (view = l) viewHolder = new ViewHolder(); view = mInflater.inflate(R.layout.list_item, null); /初始化 viewHolder.img = (ImageView) view.findViewById(R.id.img); /設(shè)置圖片最小寬高 viewHolder.img.setMinimumWidth(w / 3); viewHolder.img.setMinimumHeight(h / 3); viewHolde

34、r.img_select = (ImageView) view.findViewById(R.id.img_select); view.setTag(viewHolder); else viewHolder = (ViewHolder) view.getTag(); /獲取position bean = mList.get(i); /是否選中 if (bean.isSelect() viewHolder.img_select.setVisibility(View.VISIBLE); else viewHolder.img_select.setVisibility(View.INVISIBLE)

35、; /是否有圖片 if (bean.getBitmap() = null) /圖片加載,異步加載 new ImgTask().execute(bean.getPath(), String.valueOf(i); else /設(shè)置圖片 viewHolder.img.setImageBitmap(bean.getBitmap(); return view; /* * 緩存 */ static class ViewHolder private ImageView img; private ImageView img_select; /* * 異步任務(wù) */ private class ImgTask

36、 extends AsyncTask<String, Void, Bitmap> /* * 后臺(tái)加載 * * param strings * return */ Override protected Bitmap doInBackground(String. strings) /圖片路徑 String path = strings0; /position int position = Integer.parseInt(strings1); /圖片壓縮 Bitmap bitmap = BitmapUtils.getScaleBitmapPath(mContext, path); /設(shè)

37、置圖片 mList.get(position).setBitmap(bitmap); return bitmap; /* * 刷新視圖 * * param bitmap */ Override protected void onPostExecute(Bitmap bitmap) super.onPostEute(bitmap); /刷新 GridAdapter.this.notifyDataSetChanged(); 我們?cè)诶锩孀隽撕芏嗟氖虑?,首選是ViewHolder的優(yōu)化,然后就是異步加載圖片了,接著獲取屏幕的高寬去適配,當(dāng)然,這里做了一個(gè)bitmap的工具類(lèi)BitmapUtilspac

38、kage com.liuguilin.uploadphotossample;/* * 項(xiàng)目名: UploadPhotosSample * 包名: com.liuguilin.uploadphotossample * 文件名: BitmapUtils * 創(chuàng)建者: LGL * 創(chuàng)建時(shí)間: 2016/8/31 14:18 * 描述: 圖片壓縮處理 */import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class BitmapUtils

39、/* * 本地圖片壓縮處理 * * param mContext 上下文 * param path 路徑 * return */ public static Bitmap getScaleBitmapPath(Context mContext, String path) Bitmap bitmap; int w; BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; bitmap = BitmapFactory.decodeFile(path, option

40、s); w = options.outWidth; if (w < 50) options.inSampleSize = w / 50; options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(path, options); else bitmap = BitmapFactory.decodeFile(path); return bitmap; 現(xiàn)在我們可以把我們的數(shù)據(jù)加載進(jìn)去了 /* * 初始化View */ private void initView() btnOk = (Button) findVi

41、ewById(R.id.btnOk); btnOk.setOnClickListener(this); mGridView = (GridView) findViewById(R.id.mGridView); /設(shè)置數(shù)據(jù) adapter = new GridAdapter(this, mList); mGridView.setAdapter(adapter); 這樣,我們其實(shí)是可以看到加載的效果的,這就是相冊(cè)實(shí)現(xiàn)的最基本原理了到這里,基本上就成功了一半了,現(xiàn)在開(kāi)始做點(diǎn)擊了,只要點(diǎn)擊圖片,就顯示勾選,那我們就要監(jiān)聽(tīng)他的點(diǎn)擊事件了 /* * 點(diǎn)擊事件 */ mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() Override p

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論