国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義View實現多圖片選擇控件

2019-12-12 05:42:00
字體:
來源:轉載
供稿:網友

前言

相信很多朋友在開發中都會遇到圖片上傳的情況,尤其是多圖上傳,最經典的莫過于微信的圖片選擇了。所有很多情況下會使用到多圖選擇,所以就有了這篇文章,今天抽點時間寫了個控件。
 •支持自定義選擇圖片的樣式
 •支持設置圖片選擇數量
 •支持圖片預覽,刪除
 •支持圖片拍照 

先來看看效果

實現分析

假如不定義控件,我們要實現這樣一個功能,無非是寫個GridView在item點擊的時候去顯示圖片進行選擇,在返回界面的時候進行GridView的數據刷新。我們把這些邏輯寫在我們自定義的GridView中,就成了一個新的控件。

1、GridView的效果展示,邏輯實現。

public class ImagePickerView extends GridView{ //圖片選擇數量 int maxImageSize = 9; //添加item布局 private int noImgResource; //列選擇數量 private int columnNumber = 3; Activity context; ImagesAdapter adapter; List<String> imageList;//圖片選擇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; } 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; } public ImagePickerView(Context context) { this(context,null); } public ImagePickerView(Context context, AttributeSet attrs) { this(context,attrs,0); } /** * 初始化ImagePickerView的一些信息 * @param context * @param attrs * @param defStyle */ public ImagePickerView(Context 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; } /** * 提供給外部調用用來再Activity返回時獲取圖片信息 * @param requestCode * @param resultCode * @param data */ public void onActivityResult(int requestCode, int resultCode, Intent data) { if (data!=null&& !TextUtils.isEmpty(data.getStringExtra("photoPath"))){//拍照  imageList.add(data.getStringExtra("photoPath")); }else if (data!=null&&data.getSerializableExtra("images")!=null){//圖片選擇  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 = getItemViewType(position);  if(itemViewType == TYPE_SHOW_ADD){//當前item為添加圖片item  if (noImgResource!=0){//加載用戶的添加item布局   convertView = LayoutInflater.from(context).inflate(noImgResource, parent, false);  }else {//默認的添加item布局   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) {//點擊選擇圖片   Intent intent = new Intent(context, ImagesGridActivity.class);//圖片選擇   Activity activity = context;   activity.startActivityForResult(intent,1001);   }  });  }else{//普通item,加載圖片,并對item設置點擊進行預覽  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) {//將選擇的圖片與當前postion傳過去。   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))   .setAutoRotateEnabled(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; }}

代碼比較簡單,都加了注釋。在view的初始化方法中獲取一些信息和GridView的展示信息,并且設置適配器關聯。

在GridView的 item中設置了點擊事件,并且提供給外部用來刷新數據的onActivityResult方法。

大家看上面的代碼應該就明白了。

2、圖片預覽和刪除

這一步很簡單,獲取到傳過來的imageList和postion對圖片進行展示,在點擊刪除的時候remove掉imageList對應的數據,并且刷新viewPager

直接上代碼

public class PreviewDelActivity extends AppCompatActivity implements View.OnClickListener { private static final String 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());// 圖片數量和當前圖片信息展示 initView(); AndroidImagePicker.getInstance().clearSelectedImages(); } private void initView() { mViewPager = (ViewPager)findViewById(R.id.viewpager); mAdapter = new TouchImageAdapter(getSupportFragmentManager()); mViewPager.setAdapter(mAdapter); mViewPager.setCurrentItem(mShowItemPosition, false);//設置顯示當前的圖片 mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {  @Override  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  }  @Override  public void onPageSelected(int position) {  mTitleCount.setText(position+1+"/" + mImageList.size());//滑動viewPager時更新顯示信息  }  @Override  public void onPageScrollStateChanged(int state) {  } }); } @Override public void onClick(View v) { int i = v.getId(); if (i == R.id.btn_del) {//刪除按鈕點擊  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){//返回  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 intent = 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 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(new OnPhotoTapListener() {  @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))   .setResizeOptions(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, animatable);   if (imageInfo == null) {   return;   }   photoDraweeView.update(imageInfo.getWidth(), imageInfo.getHeight());  }  });  photoDraweeView.setController(controller.build()); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  return photoDraweeView; } }}

相信大家都能看懂上面代碼,用ViewPager對圖片進行加載,在點擊回退和刪除完圖片的時候把ImageList傳回去。
這樣在onActivityResult中獲取到imageList,刷新adapter,gridview就重新渲染了。

使用

1、布局中引入ImagePickerView

<?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:paddingTop="@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="提交"/></LinearLayout>

2、在Activity中獲得ImagePickerView,并且在onActivityResult方法中調用ImagePickerView數據刷新方法
imagePicker.onActivityResult(requestCode,resultCode,data);

3、獲取選擇圖片的路徑
調用imagePicker.getImageList()即返回圖片選擇的List

下面是一段代碼示例

public class MainActivity extends AppCompatActivity { private ImagePickerView imagePicker; 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);//自定義imagePicker add item樣式 imagePicker.setColumnNumber(5);//設置顯示5列 } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { imagePicker.onActivityResult(requestCode,resultCode,data); }}

結語

看了ImagePickerView的實現,是不是發現一個自定義控件其實也很簡單。在我們做自定義控件的時候,其實大部分情況只是在Android系統提供的功能上多加一點我們的需求而已。站在巨人的肩膀上,才可以看的更遠嘛。

關于圖片加載和圖片選擇本文沒有提及,圖片加載我參考了文章,感興趣的朋友可以去github查看,https://github.com/easonline/AndroidImagePicker。我在自己的Demo中對源碼做了修改,并統一使用了Fresco加載圖片。

有需要參考源碼的同學請參考:源碼下載

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 香河县| 高雄市| 自贡市| 河东区| 汕尾市| 沂源县| 庄浪县| 普格县| 朝阳市| 通化县| 波密县| 泰安市| 长治县| 堆龙德庆县| 尚义县| 忻城县| 隆回县| 石门县| 新邵县| 长垣县| 资溪县| 镇康县| 青岛市| 清水河县| 义乌市| 紫阳县| 日喀则市| 都匀市| 临澧县| 渝中区| 武平县| 广汉市| 麦盖提县| 洞头县| 合肥市| 霞浦县| 成安县| 河西区| 雅安市| 大丰市| 台山市|