Android Custom View Implementation multi-picture selection control _android

Source: Internet
Author: User

Objective

Believe that a lot of friends in the development will encounter picture upload situation, in particular, multiple upload, the most classic is the micro-letter pictures selected. In many cases you will use a multiple-image selection, so with this article, take a moment to write a control today.
• Supports custom selection of pictures style
• Support for setting the number of picture selections
• Support Picture preview, delete
• Support Picture Photography

Let's see the effect first.

Implementation analysis

If you do not define a control, we want to implement such a function, is to write a GridView in the item click to display the picture to choose, the data back to the interface when the GridView to refresh. We write these logic in our custom GridView and become a new control.

1, the effect of the GridView demonstration, logical realization.

public class Imagepickerview extends gridview{//Picture selection quantity int maximagesize = 9;

 Add Item layout private int noimgresource;

 Number of column selections private int columnnumber = 3;
 Activity context;

 Imagesadapter adapter;
 list<string> imagelist;//picture selection list private static final int type_show_add = 0;

 private static final int type_no_show_add = 1;

 Private Boolean isshowadd = true;

 int imagegridsize;
 public void Setnoimgresource (int noimgresource) {this.noimgresource = Noimgresource;
 The public void setcolumnnumber (int columnnumber) {if (columnnumber>5) {columnnumber = 5;
 } this.columnnumber = ColumnNumber;
 This.setnumcolumns (ColumnNumber);
 } public void Setshowadd (Boolean showadd) {isshowadd = Showadd;
 public void SetImageList (list<string> imageList) {this.imagelist = imageList;
 Adapter.setimagelist (imageList);
 Public list<string> getimagelist () {return imageList;
 {This (context,null) is public imagepickerview; } PubLic Imagepickerview (context, AttributeSet attrs) {this (context,attrs,0); /** * Initialization Imagepickerview Some information * @param context * @param attrs * @param defstyle/public Imagepickerview (Contex
 T context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
 This.context = (activity) context;
 adapter = new Imagesadapter ();
 This.setadapter (adapter);
 if (imagelist==null) {imageList = new arraylist<> ();
 } this.setnumcolumns (ColumnNumber);
 This.setverticalspacing (10);
 This.sethorizontalspacing (10); Imagegridsize = (This.context.getWindowManager (). Getdefaultdisplay (). GetWidth ()-util.dp2px (context, 2) * 2)/
 ColumnNumber; /** * Provides an external call to retrieve picture information when the activity returns * @param requestcode * @param resultcode * @param data/public void Onactiv Ityresult (int requestcode, int resultcode, Intent data) {if (data!=null&&!)
 Textutils.isempty (Data.getstringextra ("Photopath"))) {//Photo Imagelist.add (Data.getstringextra ("PhotoPath")); }else if (Data!=null&&data.getserializableextra ("Images")!=null) {//Picture selection imageList = (list<string>)
 Data.getserializableextra ("Images");
  }else{list<imageitem> List = Androidimagepicker.getinstance (). Getselectedimages ();
  for (int i=0;i<list.size (); i++) {Imagelist.add (List.get (i). path);
 } androidimagepicker.getinstance (). Setselectlimit (Maximagesize-imagelist.size ());
 Adapter.setimagelist (imageList);

 Class Imagesadapter extends Baseadapter {list<string> imageList;
 Public Imagesadapter () {this.imagelist = new ArrayList ();
  public void SetImageList (list<string> imageList) {this.imagelist = imageList;
 Notifydatasetchanged ();
  @Override public int GetCount () {if (Isshowadd) {if imageList = null | | imagelist.isempty ()) {return 1;
  } if (Imagelist.size () >= maximagesize) {return maximagesize;
  return imagelist.size () + 1;
  } if (Imagelist.size () >= maximagesize) {return maximagesize; } RETurn imagelist.size () +1;
  @Override public String getitem (int position) {if (Isshowadd) {if (Position==imagelist.size ()) {return null;
  Return Imagelist.get (position-1);
 return Imagelist.get (position);
 @Override public long getitemid (int position) {return 0;
 @Override public int Getviewtypecount () {return 2; @Override public int Getitemviewtype (int position) {if (Isshowadd) {return position==imagelist.size ()?
  Type_show_add:type_no_show_add;
  }else{return type_no_show_add; } @Override Public View getview (final int position, View Convertview, viewgroup parent) {int itemviewtype = GetIt
  Emviewtype (position); if (Itemviewtype = = Type_show_add) {//current item is add Picture item if (noimgresource!=0) {//Load user's Add Item layout Convertview = Layoutinflate
  R.from (context). Inflate (Noimgresource, parent, false);
  }else {///default Add Item Layout Convertview = Layoutinflater.from (context). Inflate (R.layout.grid_item_camera, parent, false); } convertview.setTag (NULL); Convertview.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {//Click to select Picture Inten
   T intent = new Intent (context, imagesgridactivity.class);//Picture selection activity activity = context;
   Activity.startactivityforresult (intent,1001);
  }
  });
  }else{//general item, load picture, and click on item set to preview final Viewholder holder;
   if (Convertview = = null) {Convertview = Layoutinflater.from (context). Inflate (R.layout.image_grid_item, NULL);
   Holder = new Viewholder ();
   Holder.ivpic = (Simpledraweeview) Convertview.findviewbyid (R.ID.IV_THUMB);
   Holder.cbpanel = Convertview.findviewbyid (R.id.thumb_check_panel);
  Convertview.settag (holder);
  }else{holder = (viewholder) convertview.gettag (); Convertview.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) {//will select the picture with the current postion
   Pass through.
   Intent Intent = new Intent (context, previewdelactivity.class);
   Intent.putextra ("Images", (Serializable) imageList); Intent.putextRA ("position", position);
   Context.startactivityforresult (intent,1002);
  }
  }); Imagerequestbuilder Requestbuilder = Imagerequestbuilder.newbuilderwithsource (Uri.parse (String.format ("file://%s") , Imagelist.get (position))). Setresizeoptions (New Resizeoptions (Imagegridsize, Imagegridsize)). setautorotateenabl
  Ed (true); Pipelinedraweecontroller controller = (Pipelinedraweecontroller) fresco.newdraweecontrollerbuilder ().
  Setoldcontroller (Holder.ivPic.getController ()). Setimagerequest (Requestbuilder.build ()). build ();
  Holder.ivPic.setController (Controller);
 return convertview;
 } class viewholder{Simpledraweeview ivpic;
 View Cbpanel;

 }
}

The code is simple, with comments added. Get some information and display information about the GridView in the View initialization method, and set the adapter association.

A click event is set in the GridView item and provided to the external Onactivityresult method used to refresh the data.

You should see the code above.

2, picture preview and delete

This step is very simple, get to pass over the ImageList and postion to show the picture, click Delete Remove the ImageList corresponding data, and refresh Viewpager

Directly on the code

public class Previewdelactivity extends Appcompatactivity implements View.onclicklistener {private static final Strin

 G TAG = ImagePreviewActivity.class.getSimpleName ();
 TextView Mtitlecount;
 TextView Mbtnok;

 Private ImageView backbtn;

 List<string> mimagelist;


 int mshowitemposition = 0;

 Viewpager Mviewpager;


 Touchimageadapter Madapter;
 @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);

 Setcontentview (R.layout.activity_preview_del);
 Mimagelist = (list<string>) getintent (). Getserializableextra ("Images");

 Mshowitemposition = Getintent (). Getintextra ("position", 0);
 Mbtnok = (TextView) Findviewbyid (R.id.btn_del);
 BACKBTN = (ImageView) Findviewbyid (r.id.btn_backpress);
 Mbtnok.setonclicklistener (this);

 Backbtn.setonclicklistener (this);
 Mtitlecount = (TextView) Findviewbyid (R.id.tv_title_count);

 Mtitlecount.settext (mshowitemposition+1+ "/" + mimagelist.size ());//Picture quantity and current picture information show Initview (); AndroidimAgepicker.getinstance (). Clearselectedimages ();
 private void Initview () {Mviewpager = (Viewpager) Findviewbyid (R.id.viewpager);
 Madapter = new Touchimageadapter (Getsupportfragmentmanager ());
 Mviewpager.setadapter (Madapter); Mviewpager.setcurrentitem (Mshowitemposition, false);//setting Displays the current picture Mviewpager.addonpagechangelistener (new Viewpager.onpagechangelistener () {@Override public void onpagescrolled (int position, float positionoffset, int positi onoffsetpixels) {} @Override public void onpageselected (int position) {Mtitlecount.settext (position+1+ "/" + MI
 Magelist.size ())///Viewpager update display information when sliding to @Override public void onpagescrollstatechanged (int state) {}});
 @Override public void OnClick (View v) {int i = V.getid (); if (i = = R.id.btn_del) {//delete button click Madapter.remove (Mviewpager.getcurrentitem ());//Mtitlecount.settext (
  Mviewpager.getcurrentitem () +1+ "/" + mimagelist.size ());
  if (Mimagelist.size () ==0) {Intent Intent = new Intent (); Intent.putexTRA ("Images", (Serializable) mimagelist);
  Setresult (result_ok,intent);
  Finish ();
  }}else if (i==r.id.btn_backpress) {//return Intent Intent = new Intent ();
  Intent.putextra ("Images", (Serializable) mimagelist);
  Setresult (result_ok,intent);
 Finish (); @Override public boolean onKeyDown (int keycode, keyevent event) {if (keycode==keyevent.keycode_back) {Intent I
  ntent = new Intent ();
  Intent.putextra ("Images", (Serializable) mimagelist);
  Setresult (result_ok,intent);
  Finish ();
 return true;
 Return Super.onkeydown (KeyCode, event); Class Touchimageadapter extends Fragmentstatepageradapter {public touchimageadapter (fragmentmanager FM) {SUPER (FM
 );
 @Override public int GetCount () {return mimagelist.size ();
  public void Remove (int position) {mimagelist.remove (position);
 Notifydatasetchanged ();
 @Override public int GetItemPosition (object) {return position_none; @Override public Fragment getitem (int position) {SinglePreviewfragment fragment = new Singlepreviewfragment ();
  Bundle Bundle = new Bundle ();
  Bundle.putserializable (Singlepreviewfragment.key_url, mimagelist.get (position));
  Fragment.setarguments (bundle);
 return fragment;  }} @SuppressLint ("Validfragment") Private class Singlepreviewfragment extends Fragment {public static final String
 Key_url = "Key_url";
 Private Photodraweeview Photodraweeview;

 Private String URL;
  @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);

  Bundle Bundle = getarguments ();
  url = (String) bundle.getserializable (Key_url);

  LOG.I (TAG, "=====current Show Image path:" + URL);
  Photodraweeview = new Photodraweeview (getactivity ());
  Photodraweeview.setbackgroundcolor (0xff000000); Viewgroup.layoutparams params = new Viewgroup.layoutparams (ViewGroup.LayoutParams.MATCH_PARENT,
  ViewGroup.LayoutParams.MATCH_PARENT);

  Photodraweeview.setlayoutparams (params); Photodraweeview.setonphototaplistener (NewOnphototaplistener () {@Override public void Onphototap (view view, float x, float y) {getactivity (). Finish ();
  }
  });
  if (!url.startswith ("http://") &&!url.startswith ("https://")) {URL = "file://" +url; } Imagerequestbuilder Requestbuilder = Imagerequestbuilder.newbuilderwithsource (uri.parse (URL)). setResizeOption

  S (New Resizeoptions (768,1280)). Setautorotateenabled (True);
  Pipelinedraweecontrollerbuilder controller = Fresco.newdraweecontrollerbuilder ();
  Controller.setoldcontroller (Photodraweeview.getcontroller ());
  Controller.setimagerequest (Requestbuilder.build ()); Controller.setcontrollerlistener (New basecontrollerlistener<imageinfo> () {@Override public void Onfinalimageset (String ID, imageinfo imageinfo, animatable animatable) {super.onfinalimageset (ID, imageinfo, animatabl
   e);
   if (Imageinfo = = null) {return;
  } photodraweeview.update (Imageinfo.getwidth (), Imageinfo.getheight ());
  }
  }); Photodraweeview.setcoNtroller (Controller.build ()); @Override public View Oncreateview (layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) {retur
 n Photodraweeview;

 }

 }

}

I believe we can read the above code, with Viewpager to load the picture, in the click Back and delete the picture when the ImageList pass back.
In this way, the ImageList is acquired in the Onactivityresult, and the refresh Adapter,gridview is rendered again.

Use

1, the introduction of Imagepickerview in the layout

 <?xml version= "1.0" encoding= "Utf-8"?> "<linearlayout xmlns:android=" http:// Schemas.android.com/apk/res/android "xmlns:tools=" Http://schemas.android.com/tools "android:layout_width=" Match_ Parent "android:layout_height=" match_parent "android:paddingbottom=" @dimen/activity_vertical_margin "Android: paddingleft= "@dimen/activity_horizontal_margin" android:paddingright= "@dimen/activity_horizontal_margin" Android :p addingtop= "@dimen/activity_vertical_margin" android:orientation= "vertical" tools:context= " Com.qiangyu.test.imagepickerviewdemo.MainActivity "> <com.redare.imagepicker.widget.imagepickerview Android : id= "@+id/imagepicker" android:layout_width= "match_parent" android:layout_height= "wrap_content" > </ com.redare.imagepicker.widget.imagepickerview> <button android:id= "@+id/commit_btn" android:layout_width= " Match_parent "android:layout_height=" Wrap_content "android:text=" Submit "/> </LinearLayout> 

2. Obtain Imagepickerview in activity and invoke Imagepickerview data Refresh method in Onactivityresult method
Imagepicker.onactivityresult (requestcode,resultcode,data);

3. Get the path to select the picture
Call Imagepicker.getimagelist () returns the list of selected pictures

Here's a code example

 public class Mainactivity extends Appcompatactivity {private Imagepickerview Imagepic

 Ker

 Private Button commitbtn;
 @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
 Setcontentview (R.layout.activity_main);


 Fresco.initialize (this);
 Imagepicker = (Imagepickerview) Findviewbyid (R.id.imagepicker);
 COMMITBTN = (Button) Findviewbyid (R.ID.COMMIT_BTN); Commitbtn.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {for (int i=0;i<
  Imagepicker.getimagelist (). Size (); i++) {log.d ("yqy", Imagepicker.getimagelist (). get (i));
 }
  }
 }); Imagepicker.setnoimgresource (r.layout.add_img);//Custom Imagepicker Add Item style Imagepicker.setcolumnnumber (5); Set display 5 column} @Override protected void Onactivityresult (int requestcode, int resultcode, Intent data) {Imagepicker.onac
 Tivityresult (Requestcode,resultcode,data); }
}

Conclusion

See the implementation of Imagepickerview, is not found a custom control is actually very simple. When we do custom controls, much of what we do is simply to add a little bit more to the functionality provided by the Android system. Standing on the shoulders of giants, you can see farther.

About picture loading and picture selection This article does not mention that the pictures loaded I refer to the article, interested friends can go to GitHub view, Https://github.com/easonline/AndroidImagePicker. I have in my demo to the source code has been modified, and unified use of fresco loading pictures.

Have the need to refer to the source of the classmate please refer to: Source download

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.