在Android开发中BaseAdapter经常使用,一般常用于列表中。接下来我就以拍照功能来介绍一下他的简单的使用方法。
拍照功能常常会出现不止拍一张的情况,连续拍多张放在一个列表里,这种情况时最常见的,也是最使用的。
首先我们建一个Activity页面命名为CamerDemo,然后在页面中添加操作组件。要做一个照片的列表,这里用GridView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".CamerDemo" android:background="@color/white" android:orientation="vertical"> <GridView android:id="@+id/grid_photo" android:layout_width="match_parent" android:layout_height="wrap_content" android:numColumns="4" /> </LinearLayout>
由于拍一张照片我就要动态添加一个imageView,然后放在GridView列表中去,所以我要建一个盛放照片的模具。所以添加一个页面为Camer_Item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="70dp" android:layout_height="70dp" android:background="#00F8F8FF"> <Button android:id="@+id/bt_del" android:layout_width="20dp" android:layout_height="20dp" android:layout_alignParentRight="true" android:background="@drawable/chahao" /> //这个时上图显示的❌好,就不放了,自己找个图就行。 <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="5dp" android:background="@color/white"> <ImageView android:id="@+id/iv_image" android:layout_width="60dp" android:layout_height="60dp" android:gravity="center" android:scaleType="centerCrop" /> </RelativeLayout> </RelativeLayout>
接下来就时调用相机拍照了:
首先要在AndroidManifest.xml添加网络权限:
调用相机权限:
<uses-permission android:name="android.permission.CAMERA" />
往服务器上上传图片,需要网络权限:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>`
然后就是Activity页面代码了:
动态获取相机权限,并调用相机拍照
public void openCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); intent.addCategory(Intent.CATEGORY_DEFAULT); uri = getImageUri(); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intent, 1); } public Uri getImageUri() { file = new File(Environment.getExternalStorageDirectory(), "/temp/" + System.currentTimeMillis() + ".png"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } String path = file.getPath(); filepath=path; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { uri = Uri.fromFile(file); } else { //兼容android7.0 使用共享文件的形式 ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.Images.Media.DATA, path); uri = this.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); } return uri; } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); //相机拍完照片后的回调 } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(permissions[0].equals(android.Manifest.permission.CAMERA)){ if(grantResults[0]== PackageManager.PERMISSION_GRANTED){ Toast.makeText(CamerDemo.this,"已授权",Toast.LENGTH_SHORT).show(); }else { Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show(); } } } /** * 判断是否授权开启摄像机功能 */ private void isOpenPhoto(){ if(Build.VERSION.SDK_INT>=23){ ActivityCompat.requestPermissions(CamerDemo.this,new String[]{android.Manifest.permission.CAMERA},0); int permission = ContextCompat.checkSelfPermission(CamerDemo.this.getApplicationContext(), android.Manifest.permission.CAMERA); if(permission== PackageManager.PERMISSION_GRANTED){ //如果有了相机的权限就调用相机 }else { AlertDialog.Builder builder=new AlertDialog.Builder(CamerDemo.this); builder.setTitle("提示"); builder.setMessage("是否开启相机权限"); builder.setPositiveButton("是", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //去请求相机权限 ActivityCompat.requestPermissions(CamerDemo.this,new String[]{android.Manifest.permission.CAMERA},0); } }); builder.setNegativeButton("否", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(CamerDemo.this, "您拒绝了开启相机权限", Toast.LENGTH_SHORT).show(); } }); builder.show(); } } }
相机拍完后要显示在app上,最简单的方法就是直接在页面上建一个Imageview,把照片放到Imageview中,但是这样很明显有点弊端,那就是在实际应用中,拍多少照片时不固定的,所以之恶能动态生成显示照片。
所以我们要定义一个 GridViewAdapter 继承BaseAdapter然后通过适配器完成。
public class GridViewAdapter extends BaseAdapter { private Context context; private List<CamerIcon> list; LayoutInflater layoutInflater; private ImageView mImageView; private Button delbtn; public GridViewAdapter(Context context, List<CamerIcon> list) { this.context = context; this.list = list; layoutInflater = LayoutInflater.from(context); } //添加一个元素 public void add(CamerIcon data) { if (list == null) { list = new ArrayList<>(); } list.add(data); notifyDataSetChanged(); } //往特定位置,添加一个元素 public void add(int position, CamerIcon data) { if (list == null) { list= new ArrayList<>(); } list.add(position, data); notifyDataSetChanged(); } //移除当前数据的组件 public void remove(CamerIcon data) { if (list != null) { list.remove(data); } notifyDataSetChanged(); } //移除当前位置的组件 public void remove(int position) { if (list != null) { list.remove(position); } notifyDataSetChanged(); } public void clear() { if (list != null) { list.clear(); } notifyDataSetChanged(); } @Override public int getCount() { return list.size()+1;//注意此处 } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = layoutInflater.inflate(R.layout.camer_item, null); mImageView = convertView.findViewById(R.id.iv_image); delbtn=convertView.findViewById(R.id.bt_del); if (position < list.size()) { mImageView.setImageURI(list.get(position).getUri()); delbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { remove(position); } }); mImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LayoutInflater inflater = LayoutInflater.from(CamerDemo.this); View imgEntryView = inflater.inflate(R.layout.largeicon, null); // 加载自定义的布局文件 final AlertDialog dialog = new AlertDialog.Builder(CamerDemo.this).create(); ImageView img = imgEntryView.findViewById(R.id.large_image); Bitmap bitmap = ((BitmapDrawable) mImageView.getDrawable()).getBitmap(); img.setImageBitmap(bitmap); dialog.setView(imgEntryView); // 自定义dialog dialog.show(); // 点击布局文件(也可以理解为点击大图)后关闭dialog,这里的dialog不需要按钮 imgEntryView.setOnClickListener(new View.OnClickListener() { public void onClick(View paramView) { dialog.cancel(); } }); } }); }else{ delbtn.setVisibility(View.GONE); mImageView.setBackgroundResource(R.drawable.jiahao);//最后一个显示加号图片 mImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhrenli),"")); openCamera(); } }); } return convertView; } }
largeicon是查看大图的布局文件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/black" xmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:layout_height="wrap_content" android:id="@+id/large_image" android:adjustViewBounds="true" android:layout_width="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true"> </ImageView> </RelativeLayout>
适配的模型:
package com.example.appview;
import android.net.Uri;
public class CamerIcon {
private Uri uri;
private String path;//这个是照片拍照完成后存放在本地的图片路径
public CamerIcon() {
}
public CamerIcon( Uri uri, String path) {
this.uri=uri;
this.path=path;
}
public String getPath() {
return path;
}
public Uri getUri() {
return uri;
}
public void setPath(String path) {
this.path = path;
}
public void setUri(Uri uri) {
this.uri = uri;
}
}
完整代码:
package com.example.appview; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.app.Dialog; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.GridView; import android.widget.ImageView; import android.widget.Toast; import java.io.File; import java.util.ArrayList; import java.util.List; public class CamerDemo extends AppCompatActivity { private List<CamerIcon> mDatas; private GridView mGridView; // private GridViewAdapter adapter; private File file= null; private Uri uri; private String filepath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camer_demo); mGridView=findViewById(R.id.grid_photo); isOpenPhoto(); initDatas(); adapter=new GridViewAdapter(CamerDemo.this,mDatas); mGridView.setAdapter(adapter); } private void initDatas() { mDatas=new ArrayList<>(); //mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); // mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); // mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); // mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); // mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); } /** * 得到资源文件中图片的Uri * @param context 上下文对象 * @param id 资源id * @return Uri */ public Uri getUriFromDrawableRes(Context context, int id) { Resources resources = context.getResources(); String path = ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + resources.getResourcePackageName(id) + "/" + resources.getResourceTypeName(id) + "/" + resources.getResourceEntryName(id); return Uri.parse(path); } public void openCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); intent.addCategory(Intent.CATEGORY_DEFAULT); uri = getImageUri(); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intent, 1); } public Uri getImageUri() { file = new File(Environment.getExternalStorageDirectory(), "/temp/" + System.currentTimeMillis() + ".png"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } String path = file.getPath(); filepath=path; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { uri = Uri.fromFile(file); } else { //兼容android7.0 使用共享文件的形式 ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.Images.Media.DATA, path); uri = this.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); } return uri; } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode==1){ adapter.add(new CamerIcon(uri,"")); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(permissions[0].equals(android.Manifest.permission.CAMERA)){ if(grantResults[0]== PackageManager.PERMISSION_GRANTED){ Toast.makeText(CamerDemo.this,"已授权",Toast.LENGTH_SHORT).show(); }else { Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show(); } } } /** * 判断是否授权开启摄像机功能 */ private void isOpenPhoto(){ if(Build.VERSION.SDK_INT>=23){ ActivityCompat.requestPermissions(CamerDemo.this,new String[]{android.Manifest.permission.CAMERA},0); int permission = ContextCompat.checkSelfPermission(CamerDemo.this.getApplicationContext(), android.Manifest.permission.CAMERA); if(permission== PackageManager.PERMISSION_GRANTED){ //如果有了相机的权限就调用相机 }else { AlertDialog.Builder builder=new AlertDialog.Builder(CamerDemo.this); builder.setTitle("提示"); builder.setMessage("是否开启相机权限"); builder.setPositiveButton("是", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //去请求相机权限 ActivityCompat.requestPermissions(CamerDemo.this,new String[]{android.Manifest.permission.CAMERA},0); } }); builder.setNegativeButton("否", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(CamerDemo.this, "您拒绝了开启相机权限", Toast.LENGTH_SHORT).show(); } }); builder.show(); } } }
public class GridViewAdapter extends BaseAdapter {
private Context context;
private List<CamerIcon> list;
LayoutInflater layoutInflater;
private ImageView mImageView;
private Button delbtn;
public GridViewAdapter(Context context, List<CamerIcon> list) {
this.context = context;
this.list = list;
layoutInflater = LayoutInflater.from(context);
}
//添加一个元素
public void add(CamerIcon data) {
if (list == null) {
list = new ArrayList<>();
}
list.add(data);
notifyDataSetChanged();
}
//往特定位置,添加一个元素
public void add(int position, CamerIcon data) {
if (list == null) {
list= new ArrayList<>();
}
list.add(position, data);
notifyDataSetChanged();
}
//移除当前数据的组件
public void remove(CamerIcon data) {
if (list != null) {
list.remove(data);
}
notifyDataSetChanged();
}
//移除当前位置的组件
public void remove(int position) {
if (list != null) {
list.remove(position);
}
notifyDataSetChanged();
}
public void clear() {
if (list != null) {
list.clear();
}
notifyDataSetChanged();
}
@Override
public int getCount() {
return list.size()+1;//注意此处
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = layoutInflater.inflate(R.layout.camer_item, null);
mImageView = convertView.findViewById(R.id.iv_image);
delbtn=convertView.findViewById(R.id.bt_del);
if (position < list.size()) {
mImageView.setImageURI(list.get(position).getUri());
delbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
remove(position);
}
});
mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LayoutInflater inflater = LayoutInflater.from(CamerDemo.this);
View imgEntryView = inflater.inflate(R.layout.largeicon, null); // 加载自定义的布局文件
final AlertDialog dialog = new AlertDialog.Builder(CamerDemo.this).create();
ImageView img = imgEntryView.findViewById(R.id.large_image);
Bitmap bitmap = ((BitmapDrawable) mImageView.getDrawable()).getBitmap();
img.setImageBitmap(bitmap);
dialog.setView(imgEntryView); // 自定义dialog
dialog.show();
// 点击布局文件(也可以理解为点击大图)后关闭dialog,这里的dialog不需要按钮
imgEntryView.setOnClickListener(new View.OnClickListener() {
public void onClick(View paramView) {
dialog.cancel();
}
});
}
});
}else{
delbtn.setVisibility(View.GONE);
mImageView.setBackgroundResource(R.drawable.jiahao);//最后一个显示加号图片
mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhrenli),""));
openCamera();
}
});
}
return convertView;
}
}
}
运行后效果:
由于用到BasdAdapter次数太多了,每次都要在当前页面新建一个类来继承BaseAdapter太麻烦了,每次都基本是拿以前的复制粘贴,然后修改不一样的地方。所以我就想着如何将共有的部分分装成一个通用类,需要改变的还在当前页面实现,这样就回省很多力气了。
我们分析一下那些事公用的,首先适配这一块适应所有。不同的地方也就是布局页面,有的可能是一个imageview,有的可能是Button,或者EditText.这些都要根据不同页面来定义,所以这个就要在当前页面初始化。至于动态添加和删除都是通用的。接下来我们就在自己封装一下。
首先建一个通用的适配器AdapterHelper继承BaseAdapter,这个类会被所有页面用到。
package com.example.appview; import android.content.Context; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.List; /* T1:传入自定义得Model模型 T2:定义组件得类 */ public class AdapterHelper<T1 ,T2 extends AdapterInterface> extends BaseAdapter implements AdapterInterface { private Context context; public List<T1> list; //用于存放模型Model private T2 t; //初始化布局页面组件的类 private int Rid; LayoutInflater layoutInflater; public AdapterHelper(){ } public AdapterHelper(Context context,List<T1> list,T2 t,int rid) { this.context = context; this.list = list; this.t=t; this.Rid=rid; layoutInflater = LayoutInflater.from(context); } //添加一个元素 public void add(T1 data) { if (list == null) { list = new ArrayList<>(); } list.add(data); notifyDataSetChanged(); } //往特定位置,添加一个元素 public void add(int position, T1 data) { if (list == null) { list= new ArrayList<>(); } list.add(position, data); notifyDataSetChanged(); } //移除当前数据的组件 public void remove(T1 data) { if (list != null) { list.remove(data); } notifyDataSetChanged(); } //移除当前位置的组件 public void remove(int position) { if (list != null) { list.remove(position); } notifyDataSetChanged(); } public void clear() { if (list != null) { list.clear(); } notifyDataSetChanged(); } @Override public int getCount() { return list.size()+1;//注意此处 } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView= layoutInflater.inflate(Rid, null); return getView(convertView,position); } @Override public View getView(View view,int position) { return t.getView(view,position); } }
我们定义一个接口:
package com.example.appview;
import android.view.View;
public interface AdapterInterface{
public View getView(View view,int position);
}
我们就以上面的拍照页面在页面上定义布局页面组件的初始化类:
private class CamerView implements AdapterInterface { @Override public View getView(View view, int position) { Button delbtn = view.findViewById(R.id.bt_del); ImageView imageView = view.findViewById(R.id.iv_image); if (position < adapter.getCount()-1) { imageView.setImageURI(adapter.list.get(position).getUri()); delbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { adapter.remove(position); } }); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LayoutInflater inflater = LayoutInflater.from(CamerDemo.this); View imgEntryView = inflater.inflate(R.layout.largeicon, null); // 加载自定义的布局文件 final AlertDialog dialog = new AlertDialog.Builder(CamerDemo.this).create(); ImageView img = imgEntryView.findViewById(R.id.large_image); Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); // bigImageLoader(bitmap); img.setImageBitmap(bitmap); dialog.setView(imgEntryView); // 自定义dialog dialog.show(); // 点击布局文件(也可以理解为点击大图)后关闭dialog,这里的dialog不需要按钮 imgEntryView.setOnClickListener(new View.OnClickListener() { public void onClick(View paramView) { dialog.cancel(); } }); } }); }else{ delbtn.setVisibility(View.GONE); imageView.setBackgroundResource(R.drawable.jiahao);//最后一个显示加号图片 imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhrenli),"")); openCamera(); } }); } return view; } }
调用:
private List<CamerIcon> mDatas; private GridView mGridView; private AdapterHelper<CamerIcon,CamerView> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camer_demo); mGridView=findViewById(R.id.grid_photo); isOpenPhoto(); mDatas=new ArrayList<>(); //adapter=new GridViewAdapter(CamerDemo.this,mDatas); adapter= new AdapterHelper<>(CamerDemo.this, mDatas, new CamerView(), R.layout.camer_item); mGridView.setAdapter(adapter); }
整体代码:
package com.example.appview; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.app.Dialog; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.GridView; import android.widget.ImageView; import android.widget.Toast; import java.io.File; import java.util.ArrayList; import java.util.List; public class CamerDemo extends AppCompatActivity { private List<CamerIcon> mDatas; private GridView mGridView; // private GridViewAdapter adapter; private AdapterHelper<CamerIcon,CamerView> adapter; private File file= null; private Uri uri; private String filepath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camer_demo); mGridView=findViewById(R.id.grid_photo); isOpenPhoto(); initDatas(); //adapter=new GridViewAdapter(CamerDemo.this,mDatas); adapter= new AdapterHelper<>(CamerDemo.this, mDatas, new CamerView(), R.layout.camer_item); mGridView.setAdapter(adapter); } private void initDatas() { mDatas=new ArrayList<>(); //mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); // mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); // mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); // mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); // mDatas.add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhgongzuobaogao),"")); } /** * 得到资源文件中图片的Uri * @param context 上下文对象 * @param id 资源id * @return Uri */ public Uri getUriFromDrawableRes(Context context, int id) { Resources resources = context.getResources(); String path = ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + resources.getResourcePackageName(id) + "/" + resources.getResourceTypeName(id) + "/" + resources.getResourceEntryName(id); return Uri.parse(path); } public void openCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); intent.addCategory(Intent.CATEGORY_DEFAULT); uri = getImageUri(); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intent, 1); } public Uri getImageUri() { file = new File(Environment.getExternalStorageDirectory(), "/temp/" + System.currentTimeMillis() + ".png"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } String path = file.getPath(); filepath=path; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { uri = Uri.fromFile(file); } else { //兼容android7.0 使用共享文件的形式 ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.Images.Media.DATA, path); uri = this.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); } return uri; } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); // Bundle bundle = data.getExtras(); // Bitmap bitmap = (Bitmap) bundle.get("data");// 获取相机返回的数据,并转换为Bitmap图片格式 // Uri uri; // if (data.getData() != null) // { // uri = data.getData(); // } // else // { // uri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, null,null)); // } if (requestCode==1){ // adapter.add(adapter.getCount()-2,new CamerIcon(uri,"dfsfs")); adapter.add(new CamerIcon(uri,"")); // Log.i("拍照","调用相机成功"); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(permissions[0].equals(android.Manifest.permission.CAMERA)){ if(grantResults[0]== PackageManager.PERMISSION_GRANTED){ Toast.makeText(CamerDemo.this,"已授权",Toast.LENGTH_SHORT).show(); }else { Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show(); } } } /** * 判断是否授权开启摄像机功能 */ private void isOpenPhoto(){ if(Build.VERSION.SDK_INT>=23){ ActivityCompat.requestPermissions(CamerDemo.this,new String[]{android.Manifest.permission.CAMERA},0); int permission = ContextCompat.checkSelfPermission(CamerDemo.this.getApplicationContext(), android.Manifest.permission.CAMERA); if(permission== PackageManager.PERMISSION_GRANTED){ //如果有了相机的权限就调用相机 }else { AlertDialog.Builder builder=new AlertDialog.Builder(CamerDemo.this); builder.setTitle("提示"); builder.setMessage("是否开启相机权限"); builder.setPositiveButton("是", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //去请求相机权限 ActivityCompat.requestPermissions(CamerDemo.this,new String[]{android.Manifest.permission.CAMERA},0); } }); builder.setNegativeButton("否", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(CamerDemo.this, "您拒绝了开启相机权限", Toast.LENGTH_SHORT).show(); } }); builder.show(); } } } private class CamerView implements AdapterInterface { @Override public View getView(View view, int position) { Button delbtn = view.findViewById(R.id.bt_del); ImageView imageView = view.findViewById(R.id.iv_image); if (position < adapter.getCount()-1) { imageView.setImageURI(adapter.list.get(position).getUri()); delbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { adapter.remove(position); } }); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LayoutInflater inflater = LayoutInflater.from(CamerDemo.this); View imgEntryView = inflater.inflate(R.layout.largeicon, null); // 加载自定义的布局文件 final AlertDialog dialog = new AlertDialog.Builder(CamerDemo.this).create(); ImageView img = imgEntryView.findViewById(R.id.large_image); Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); // bigImageLoader(bitmap); img.setImageBitmap(bitmap); dialog.setView(imgEntryView); // 自定义dialog dialog.show(); // 点击布局文件(也可以理解为点击大图)后关闭dialog,这里的dialog不需要按钮 imgEntryView.setOnClickListener(new View.OnClickListener() { public void onClick(View paramView) { dialog.cancel(); } }); } }); }else{ delbtn.setVisibility(View.GONE); imageView.setBackgroundResource(R.drawable.jiahao);//最后一个显示加号图片 imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // add(new CamerIcon(getUriFromDrawableRes(CamerDemo.this,R.drawable.zhrenli),"")); openCamera(); } }); } return view; } } }
这里已经封装完了,这样以后自定义的适配器就可以保持通用。
这里要注意一个细节,我定义了接口,为什么要定义这个接口。其实这个接口非常重要,没有这个接口好多事情都很难做到。
我们来分析一下适配器类是如何继承的,首先传入两个参数,第二个参数被约束了必须是继承AdapterInterface接口,而适配器类本身也继承了该接口。为什么要约束。因为T2传入的这个就是初始化布局页面中的组件类的。
也就是如果通过适配器来初始化布局页面中的组件,那么适配器类必须要调用页面中的CamerView类来初始化,但是如果这个类没有的话,那么适配器类根本没法调用CamerView中的初始化方法GetView来初始化。
如何把该方法放在接口AdapterInterface中,然后在AdapterHelper适配器方法T2参数约束他必须继承Adapterinterface接口。那么我就可以确定这个方法在camerView类中一定存在。也就是说无论这个类存不存在,我都可以在AdapterHelper中调用GetView()方法。那么我怎末知道是adapterHelper调用的是哪个类呢?
在初始化AdapterHelper的时候直接传入当前页面的类T2的实例。和当前布局页面的id值。就完美解决了。
这样我们就通过泛型约束,和接口实现了适配器通用类的封装。