从库中选择图像在 Android 的 Fragment 类中不起作用
Posted
技术标签:
【中文标题】从库中选择图像在 Android 的 Fragment 类中不起作用【英文标题】:select image from gallery not working in Fragment Class in Android 【发布时间】:2016-01-04 18:51:27 【问题描述】:从片段类中的图库中选择图像不起作用。
我尝试了更多的堆栈代码。
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
else
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
以上代码在活动类中工作。不适用于纯片段类。
【问题讨论】:
请解释“不工作”是什么意思。 我在尝试使用嵌套片段时遇到了这个问题。 嗨 Commonsware,从库中选择图片在 Fragment 类中不起作用 您是从某些覆盖方法(如 onclick 或其他方法)调用 Startactivity 吗? 据我了解,您必须使用子片段中的 onActivityResult 您可能想查看here 【参考方案1】:如果您从Fragment
调用startActivityForResult()
方法,您有两种选择:
-
直接拨打
startActivityForResult()
致电getActivity().startActivityForResult()
在您的情况下,如果您想处理 Activity
上的结果,请以这种方式更改您的代码:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
getActivity().startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
else
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
getActivity().startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
否则,如果您需要处理调用 Fragment
中的结果并且它当前无法正常工作,您可能会遇到 传播 问题。此类问题在this post中已被广泛描述。
关于startActivityForResult和嵌套片段的详细文章可以在here找到。
【讨论】:
嗨 Bonnyz,我尝试使用上面的 getActivity().startActivityForResult() 代码..这也不起作用..在这里,无需将数据从父活动发送到 fragent,或将片段发送到父活动。 . 只是,在片段类中,只需打开画廊并选择一个图像并在imageview中显示..就是这样..这些都只需要在片段类中完成.. @harikrishnan 因此,如果需要直接在片段中启动/接收 onActivtyResult,请查看关于传播问题的答案的第二部分【参考方案2】:如果上面的代码不起作用,你应该检查你的片段导入语句。
我认为您在片段中使用片段。如果是,请发布您的导入代码。
【讨论】:
是的 Rahul.. 我在这里使用 Material Tab FRagment.inside 一个 TabFragment 类。我想做,比如从图库中选择图像并将其上传到网络服务.. 代码只工作 startActivityForResult() 直到..下一个 public void onActivityResult(int requestCode, int resultCode, Intent data) 方法没有被调用..那是我的问题..我只想在里面做这个片段类。我不想将任何数据从 Fragment 传输到 Activity ..... ok 尝试使用 getActivity.startActivityForResult 并告诉我结果【参考方案3】:希望对您有所帮助。
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
// write this in your fragment or method or listener which will invoke gallery.
然后把它写在你的片段中
public void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == RESULT_LOAD_IMAGE && resultCode == getActivity().RESULT_OK
&& null != data)
Uri selectedImage = data.getData();
String[] filePathColumn = MediaStore.Images.Media.DATA ;
Cursor cursor = getActivity().getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
Log.d("Picture Path", "Picture Path:"+picturePath);
long total_Images_size=0;
File f=new File(picturePath);
//total_Images_size+=f.length();
/*if(total_Images_size>MAX_IMAGE_FILES_SIZE)
Toast.makeText(getActivity(), "Image attachments size cannot exceed 5MB(total).", Toast.LENGTH_LONG).show();
return;
*/
String selectedFilename=picturePath.substring(picturePath.lastIndexOf("/"));
addPicture(picturePath, imageCount);
尝试一下,如果有任何错误请告诉我。谢谢
【讨论】:
【参考方案4】:如果您在附加到 Activity 的 Fragment 上使用此代码,则:
getActivity().startActivityForResult()
将调用活动的onActivityResult()
。
startActivityForResult()
将调用活动和片段的onActivityResult()
。这里的问题是,片段的onActivityResult()
会得到正确的requestCode。但是那个activity的会得到一个修改过的requestCode。
但嵌套片段并非如此。在 NestedFragments 的情况下,始终调用getActivity().startActivityForResult()
并在活动的onActivityResult()
中处理结果。如果您不想在片段和活动之间创建强依赖关系,则必须有一个设计模式来进行这种解耦(我为此使用了 Otto 库)。更好的是始终从附加到活动的片段中调用getActivity().startActivityForResult()
,而不是嵌套的片段。
最佳实践:根据我的经验,仅在活动中处理onActivityResult()
!这将减少很多维护噩梦。使用其他机制将此委托给片段。
【讨论】:
【参考方案5】:由于您要做的就是从图库 Intent 中检索图像并填充 FRAGMENT 中存在的图像视图,因此您可以做的是在您的活动中保留对此图像视图的引用并使用 getActivity().startActivityForResult()
然后设置位图用于您活动中的图像视图参考。
代码:
// YOUR FRAGMENT
// fragment code...
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
else
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
// Update your activity's imageview reference
mListener.setImageViewRef(fragmentImgView);
getActivity().startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
// more code..
@Override
public void onAttach(Context context)
super.onAttach(context);
try
mListener = (OnFragmentInteractionListener) getActivity();
catch (ClassCastException e)
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
// Create interface to communicate with your activity
public interface OnFragmentInteractionListener
void setImageViewRef(ImageView imgView);
// END FRAGMENT CODE.
// YOUR ACTIVITY
public class MyActivity extends FragmentActivity implements MyFragment.OnFragmentInteractionListener
...
private ImageView myFragmentsImageViewReference;
...
@Override
void setImageViewRef(ImageView imgView)
this.myFragmentsImageViewReference = imgView;
public void onActivityResult(int requestCode, int resultCode, Intent data)
... get Image from intent ...
myFragmentsImageViewReference.setImageBitmap(myBitmapRetrievedFromIntent);
...
// END ACTIVITY CODE
【讨论】:
【参考方案6】:请检查您的活动的 onActivityResult() 方法,如果您没有在 Fragment 的 onActivityResult() 中获得回调,它将被调用。如果您在父活动中获得回调,那么您可以从那里调用 Fragment 的 onActivityResult() 方法...如果您需要更多帮助,请告诉我...
【讨论】:
以上是关于从库中选择图像在 Android 的 Fragment 类中不起作用的主要内容,如果未能解决你的问题,请参考以下文章