【问题标题】:select image from gallery not working in Fragment Class in Android从库中选择图像在 Android 的 Fragment 类中不起作用
【发布时间】: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

标签: android fragment android-dialogfragment android-gallery


【解决方案1】:

如果您Fragment 调用startActivityForResult() 方法,您有两种选择

  1. 直接拨打startActivityForResult()
  2. 致电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 上使用此代码,则:

    1. getActivity().startActivityForResult() 将调用活动的onActivityResult()

    2. 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() 方法...如果您需要更多帮助,请告诉我...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-10-03
          • 2011-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多