Android 사용자 정의 View 다 중 이미지 선택 컨트롤 구현
많은 친구 들 이 개발 과정 에서 사진 이 올 라 오 는 상황 을 만 날 수 있 을 것 이 라 고 믿 습 니 다.특히 여러 그림 이 올 라 오 면 가장 전형 적 인 것 은 위 챗 의 사진 선택 입 니 다.모든 경우 다 중 그림 선택 에 사용 되 기 때문에 이 글 이 있 습 니 다.오늘 은 시간 을 내 서 컨트롤 을 썼 습 니 다.
•사용자 정의 그림 선택 스타일 지원
•그림 선택 수량 설정 지원
•그림 미리 보기,삭제 지원
•사진 촬영 지원
일단 효 과 를 볼 게 요.
실현 분석
컨트롤 이 정의 되 지 않 으 면 우 리 는 이러한 기능 을 실현 해 야 합 니 다.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 에 클릭 이 벤트 를 설정 하고 외부 에서 데 이 터 를 새로 고 치 는 onActivity Result 방법 을 제공 합 니 다.
여러분 은 위의 코드 를 보시 면 아 실 겁 니 다.
2.그림 미리 보기 및 삭제
이 단 계 는 간단 합 니 다.전 송 된 imageList 와 postion 을 가 져 와 그림 을 보 여 줍 니 다.삭 제 를 클릭 할 때 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 를 돌려 보 냅 니 다.이렇게 하면 onActivity Result 에서 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 를 얻 고 onActivity Result 방법 에서 ImagePickerView 데이터 새로 고침 방법 을 호출 합 니 다.imagePicker.onActivityResult(requestCode,resultCode,data);
3.선택 한 그림 을 가 져 오 는 경로
이미지 Picker.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 의 실현 을 보고 사용자 정의 컨트롤 을 발견 하 는 것 도 간단 하지 않 습 니까?우리 가 사용자 정의 컨트롤 을 할 때,사실 대부분의 상황 은 안 드 로 이 드 시스템 이 제공 하 는 기능 에 우리 의 요 구 를 조금 더 추가 할 뿐이다.거인 의 어깨 위 에 서 야 더 멀리 볼 수 있 잖 아.
사진 로드 와 사진 선택 에 대해 본 고 는 언급 하지 않 았 습 니 다.사진 로드 는 저 는 글 을 참고 하 였 습 니 다.관심 이 있 는 친 구 는 github 에 가서 볼 수 있 습 니 다https://github.com/easonline/AndroidImagePicker나 는 자신의 데모 에서 원본 코드 를 수정 하고 Fresco 로 그림 을 불 러 왔 다.
소스 코드 를 참고 해 야 하 는 학생 이 있 으 면 참고 하 세 요원본 코드 다운로드
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.