Android Studio 適配器BaseAdapter的使用


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

 

 

這樣我們就通過泛型約束,和接口實現了適配器通用類的封裝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM