如何在适配器内实现 onActivityResult? [英] How can I implement onActivityResult inside an Adapter?

查看:56
本文介绍了如何在适配器内实现 onActivityResult?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能用一些代码片段解释一下,我们如何在适配器中恢复 onActivityResult 的结果?我已经阅读了一些关于接口的内容,但我无法尝试实现它.提前致谢!

Can someone explain me, with some code snippets, how we can recover the result of onActivityResult inside an Adapter? I've read some about interfaces, but i couldn't be able trying implementing this.Thanks in advance!

示例:在适配器内部我有一个 ViewHolder,里面是一个 ImageView.点击这个 ImageView 的事件会启动一个 startActivityForResult.但在同一个适配器中,我需要通过 onActivityResult 方法.

Example: Inside the adapter i have a ViewHolder, inside which is an ImageView.An event clicking on this ImageView starts an startActivityForResult.But in the same adapter i need to recover the result by onActivityResult method.

如何处理以下内容:

主要活动:

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private List<Filme> listaFilmes = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.recyclerView);

        //Listagem de filmes
        this.criarFilmes();

        //Configurar adapter
        final Adapter adapter = new Adapter(listaFilmes,getApplicationContext(),MainActivity.this);


        //Configurar Recyclerview
        //Para mostrar na horizontal: new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.HORIZONTAL,false);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.HORIZONTAL,false);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);
        recyclerView.addItemDecoration( new DividerItemDecoration(this, LinearLayout.VERTICAL));
        recyclerView.setAdapter(adapter);

    }

    public void criarFilmes(){
        Filme filme = new Filme("Homem Aranha - De volta ao lar","Aventura","2017");
        this.listaFilmes.add( filme );

    }
}

适配器:

public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {

    private List<Filme> listaFilmes;
    private Context context;
    private Activity activity;
    private ImageView imagem;
    private Uri photoURI;
    Uri filePath;
    String mCurrentPhotoPath;
    static final int REQUEST_TAKE_PHOTO = 1;



    public Adapter(List<Filme> listaFilmes, Context context,Activity activity) {
        this.listaFilmes = listaFilmes;
        this.context = context;
        this.activity = activity;
    }

    //Aqui ele cria apenas a visualização
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemLista = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.adapter_lista, parent, false);

        return new MyViewHolder(itemLista);
    }

    //A exibição dos itens ocorre aqui
    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {

        final Filme filme = listaFilmes.get(position);
        /*holder.titulo.setText(filme.getTituloFilme());
        holder.genero.setText(filme.getGenero());
        holder.ano.setText(filme.getAno());*/
        holder.imagem.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Toast.makeText(context, "imagem removida", Toast.LENGTH_SHORT).show();
                listaFilmes.remove(position);
                notifyDataSetChanged();
                return false;
            }
        });
        holder.imagem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "imagem clicada", Toast.LENGTH_SHORT).show();
                listaFilmes.add(position+1,filme);
                notifyDataSetChanged();
                selectImage();


            }
        });
    }

    //Retorna a quantidade de itens que serão exibidos
    @Override
    public int getItemCount() {
        return listaFilmes.size();
    }


    public class MyViewHolder extends RecyclerView.ViewHolder {

        /*TextView titulo;
        TextView ano;
        TextView genero;*/
        ImageView imagem;

        public MyViewHolder(View itemView) {
            super(itemView);

            imagem = itemView.findViewById(R.id.image_id);
            /*titulo = itemView.findViewById(R.id.textTitulo);
            ano    = itemView.findViewById(R.id.textAno);
            genero = itemView.findViewById(R.id.textGenero);*/
        }
    }

    /*Função seleciona foto da galeria ou tira foto*/
    public void selectImage() {

        final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" };
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("Add Photo!");
        builder.setItems(options, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int item) {
                if (options[item].equals("Take Photo"))
                {
                    dispatchTakePictureIntent(activity);
                }
                else if (options[item].equals("Choose from Gallery"))
                {
                    Intent intent = new   Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    ((Activity) context).startActivityForResult(intent, 2);
                }
                else if (options[item].equals("Cancel")) {
                    dialog.dismiss();
                }
            }
        });
        builder.show();
    }

    //ativa a camera para tirar foto
    public void dispatchTakePictureIntent(Activity currentActivity) {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //Ensure that there`s a camera activity to handle the intent
        if(takePictureIntent.resolveActivity( context.getApplicationContext().getPackageManager() ) != null ){ //getActivity
            //Create the File where the photo should go
            File photoFile = null;
            try{
                photoFile = createImageFile(currentActivity);
            }catch(IOException ex){
                //Error occurred while creating the File
                ex.printStackTrace();

            }
            //Continue only if the File was successfully created
            if(photoFile != null){
                Log.i("ENTFR11","photofile:"+ photoFile); //    /storage/emulated/0/Android/data/com.droidelivery.droidelivery/files/Pictures/JPEG_20171010_205010_1588304974.jpg
                photoURI = FileProvider.getUriForFile(context.getApplicationContext(), //getActivity
                        "com.example.lucas.recyclerview.fileprovider",
                        photoFile);
                Log.i("ENTFR12","photofURI:"+ photoURI); //    content://com.example.android.fileprovider/my_images/JPEG_20171010_205010_1588304974.jpg
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); //ESTUDAR ESSA LINHA ESTÄ COM PROBLEMA.COMO RECUPERAR EXTRA_OUTPUT
                Log.i("ENTFR13","photoURI: " + photoURI);
                ((Activity) context).startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }
    }

    //Create a collision-resistant file name
    public File createImageFile(Activity currentActivity) throws IOException {
        //Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault() ).format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = currentActivity.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName, /*prefix*/
                ".jpg",        /*suffix*/
                storageDir     /*directory*/
        );

        //Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }

    public void setPic() {
        // Get the dimensions of the View

        int targetW = imagem.getWidth();
        int targetH = imagem.getHeight();

        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        // Determine how much to scale down the image
        int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

        // Decode the image file into a Bitmap sized to fill the View
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        imagem.setImageBitmap(bitmap);

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK ) { //lembrar que activity que requisita foto nao retorna necessariamente uma URI!!!
            //filePath = data.getData();
            //filePath = photoURI;
            setPic();
        }
        if(requestCode == 2 && resultCode == RESULT_OK && data != null){
            Toast.makeText(context, "requestCode == 2", Toast.LENGTH_SHORT).show();
            try {
                //getting image from gallery
                Uri selectedImage = data.getData();
                Log.i("SSS","selectedImage: " + selectedImage);
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), selectedImage);//getContext

                imagem.setImageBitmap(bitmap);
            }catch(Exception e){
                e.printStackTrace();
            }

        }
    }
}

推荐答案

你可以定义一个接口...

You could define an interface...

public interface OnIntentReceived {
  void onIntent(Intent i, int resultCode);
}

在适配器上实现接口.注意:您只需要适配器中的 Context,而不需要 Activity 实例

Implement interface on the adapter. Note: You only need a Context in an adapter, not also an Activity instance

public class MyAdapter extends RecyclerView.Adapter<T> implements OnIntentReceived {

   private Context mContext;

   @Override public void onIntent(Intent i, int resultCode) {
      // TODO: Handle here
   }

   // Somewhere in here, mContext.startActivityForResult(MyActivity.REQUEST_CODE);

}

在activity中定义adapter并将intent结果转发给回调接口

In the activity, define the adapter and forward the intent result to the callback interface

public class MyActivity extends AppCompatActivity {

  public static final int REQUEST_CODE = 101;

  private MyAdapter mAdapter;
  private List data = new ArrayList();
  private OnIntentReceived mIntentListener;

  @Override protected void onCreate(Bundle b) {
     ... 

     mAdapter = new MyAdapter(this, data);
     mIntentListener = mAdapter;
  }

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE) {
        if (mIntentListener != null) {
          mIntentListener.onIntent(data, resultCode);
        }
    }
  }
}

这篇关于如何在适配器内实现 onActivityResult?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆