如何在适配器内实现 onActivityResult? [英] How can I implement onActivityResult inside an Adapter?
问题描述
谁能用一些代码片段解释一下,我们如何在适配器中恢复 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屋!