Android Studio 适配器BaseAdapter的使用

时间:2024-03-12 11:34:50

        在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值。就完美解决了。

 

 

这样我们就通过泛型约束,和接口实现了适配器通用类的封装。