简体   繁体   中英

getActivity().startActivityForResult() is not working in fragments

I am working in Fragment in which I need to select an image from gallery and set it to an imageView but getActivity().startActivityForResult() is now working

I have already checked many Links but all are saying that call this method in parent activity but I dont have any parent activity as this fragment is inside a another fragment. I have checked this link too

startActivityForResult is not working in Fragment

Here is my code :-

MainActivity Class:-

public class SabaKuchHomeActivity extends FragmentActivity {

private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;

// nav drawer title
private CharSequence mDrawerTitle;

// used to store app title
private CharSequence mTitle;

// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;

private ArrayList<NavDrawerItem> navDrawerItems=new ArrayList<NavDrawerItem>();
private NavDrawerListAdapter adapter;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    setContentView(R.layout.home_activity);
    mTitle = mDrawerTitle = getTitle();


    // load slide menu items
    navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

    // nav drawer icons from resources
    navMenuIcons = getResources()
            .obtainTypedArray(R.array.nav_drawer_icons);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

    // adding nav drawer items to array
            // Home
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
            // Find People
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
            // Photos
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
            // Communities, Will add a counter here
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1), true, "22"));
            // Pages
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
            // What's hot, We  will add a counter here
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1), true, "50+"));
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[6], navMenuIcons.getResourceId(6, -1)));

            // Recycle the typed array
            navMenuIcons.recycle();

            mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

            // setting the nav drawer list adapter
            adapter = new NavDrawerListAdapter(getApplicationContext(),
                    navDrawerItems);
            mDrawerList.setAdapter(adapter);

            // enabling action bar app icon and behaving it as toggle button
            getActionBar().setDisplayHomeAsUpEnabled(true);
            getActionBar().setHomeButtonEnabled(true);
            //getActionBar().setDisplayShowHomeEnabled(false);


            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                    R.drawable.ic_drawer, //nav menu toggle icon
                    R.string.app_name, // nav drawer open - description for accessibility
                    R.string.app_name // nav drawer close - description for accessibility
            ) {
                @TargetApi(Build.VERSION_CODES.HONEYCOMB)
                public void onDrawerClosed(View view) {
                    getActionBar().setTitle(mTitle);
                    //getActionBar().show();
                    // calling onPrepareOptionsMenu() to show action bar icons
                    invalidateOptionsMenu();
                }

                public void onDrawerOpened(View drawerView) {
                    getActionBar().setTitle(mDrawerTitle);
                    // calling onPrepareOptionsMenu() to hide action bar icons
                    //getActionBar().hide();
                    invalidateOptionsMenu();
                }
            };
            mDrawerLayout.setDrawerListener(mDrawerToggle);

            if (savedInstanceState == null) {
                // on first time display view for first nav item
                displayView(0);
            }
        }

        /**
         * Slide menu item click listener
         * */
        private class SlideMenuClickListener implements
                ListView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                // display view for selected nav drawer item
                displayView(position);
            }
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // toggle nav drawer on selecting action bar app icon/title
            if (mDrawerToggle.onOptionsItemSelected(item)) {
                return true;
            }
            // Handle action bar actions click
            switch (item.getItemId()) {
            case R.id.action_search:

                Intent TrendIntent = new Intent(SabaKuchHomeActivity.this,TrendsActivity.class);
                startActivity(TrendIntent);

                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }

        /* *
         * Called when invalidateOptionsMenu() is triggered
         */
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public boolean onPrepareOptionsMenu(Menu menu) {
            // if nav drawer is opened, hide the action items
            boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
            menu.findItem(R.id.action_search).setVisible(!drawerOpen);
            return super.onPrepareOptionsMenu(menu);
        }

        /**
         * Diplaying fragment view for selected nav drawer list item
         * */


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
private void displayView(int position) {
    // update the main content by replacing fragments
    android.support.v4.app.Fragment fragment = null;
    switch (position) {
    case 0:
        fragment = new OzoneFragment();
        break;
    case 1:
        fragment = new MyZoneFragment();
        break;
    case 2:
        fragment = new BizZoneFragment();
        break;
    case 3:
        fragment = new EventsFragment();
        break;
    case 4:
        fragment = new PrivacySettingFragment();
        break;
    case 5:
        fragment = new ProfileSettingFragment(); ***This is the fragment where I am moving now***
        break;

    case 6:

        AppContoller.getInstance().pref=getSharedPreferences(AppContoller.getInstance().PREF_NAME, 0);
        Editor editer=AppContoller.getInstance().pref.edit();
        editer.putString(AppContoller.getInstance().USER_ID, "0");
        editer.commit();

        finish();

        break ;

    default:
        break;
    }

    if (fragment != null) {
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();

        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getActionBar().setTitle(mTitle);
}

/**
 * When using the ActionBarDrawerToggle, you must call it during
 * onPostCreate() and onConfigurationChanged()...
 */

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggls
    mDrawerToggle.onConfigurationChanged(newConfig);
}

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

}

here is ProfileSettingFragment() fragment :-

 @SuppressLint("NewApi")
public class ProfileSettingFragment extends android.support.v4.app.Fragment implements TabListener {

private ViewPager mPager;
private MyPageAdapter adapter;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
         View rootView = inflater.inflate(R.layout.profile_setting_fragment, container, false);

         mPager=(ViewPager)rootView.findViewById(R.id.pager);

            mPager.setOffscreenPageLimit(5);
            adapter=new MyPageAdapter(getChildFragmentManager());
            mPager.setAdapter(adapter);


            TabPageIndicator indicater=(TabPageIndicator)rootView.findViewById(R.id.indicator1);
            indicater.setViewPager(mPager);

            indicater.setOnPageChangeListener(new OnPageChangeListener() {

                @Override
                public void onPageSelected(int arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrollStateChanged(int arg0) {
                    // TODO Auto-generated method stub

                }
            });

            /*mPager.setOnPageChangeListener(new OnPageChangeListener() {

                @Override
                public void onPageSelected(int position) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrollStateChanged(int arg0) {
                    // TODO Auto-generated method stub

                }
            });*/

            /*actionBar.addTab(actionBar.newTab().setText("Home").setTabListener(this));
            actionBar.addTab(actionBar.newTab().setText("MiZone").setTabListener(this));
            actionBar.addTab(actionBar.newTab().setText("Top Trending").setTabListener(this));
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);*/

            return rootView;
    }

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

    private class MyPageAdapter extends FragmentStatePagerAdapter
       {
            private List<android.support.v4.app.Fragment> fragments;

        public MyPageAdapter(FragmentManager fm) {
            super(fm);
            // TODO Auto-generated constructor stub
            this.fragments=new ArrayList<android.support.v4.app.Fragment>();
            fragments.add(new ProfileGeneralSetting());
            fragments.add(new ProfileOzoneSetting());
            fragments.add(new ProfileMyzoneSetting());
            fragments.add(new ProfileBizzoneSetting());
            fragments.add(new ProfilePasswordSetting());

        }

        @Override
        public android.support.v4.app.Fragment getItem(int arg0) {
            // TODO Auto-generated method stub
            return fragments.get(arg0);
        }

        @Override
        public CharSequence getPageTitle(int position) {
        // TODO Auto-generated method stub
             switch (position) {
                case 0:
                    return "General";
                case 1:
                    return "Ozone";
                case 2:
                    return "MyZone";
                case 3:
                    return "Biz Zone";
                case 4 :
                    return "Password Setting";
            }
             return null;
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return fragments.size();
        }

       }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
        mPager.setCurrentItem(tab.getPosition());

    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

}

here is Nested Fragment from where I have to change the image :-

public class ProfileOzoneSetting extends Fragment implements MiFeelingBase, OnClickListener{

 NetworkImageView genSetOzoneUserImage;

 private ArrayList<String>arrCategoryId=new ArrayList<String>();
 List<String> interestList = new ArrayList<String>();
 String[] interest;
 Boolean setImg ;


 private static final int SELECT_PICTURE = 1;
 private String selectedImagePath;


 Button SettingOzSave;
 private MultipartEntity reqEntity;

 String[] y ={""};


 private String strUserID;
 ImageLoader imageLoader = AppContoller.getInstance().getImageLoader();

 OzoneSettingData ozSettingList = new OzoneSettingData();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    View rootView = inflater.inflate(R.layout.profiesettingozone, container, false);


    genSetOzoneUserImage = (NetworkImageView)rootView.findViewById(R.id.genSetOzoneUserImage);

    SettingOzSave = (Button)rootView.findViewById(R.id.SettingOzSave);

    SettingOzSave.setOnClickListener(this);

    genSetOzoneUserImage.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Log.d("first time", "before method");

            Intent intent  = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
        //startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);

            Log.d("first time", "before method11");
            //startActivityForResult(intent, SELECT_PICTURE);
            getParentFragment().startActivityForResult(intent, SELECT_PICTURE);
            //startActivityForResult(intent, SELECT_PICTURE);
            //((SabaKuchHomeActivity)getActivity()).startActivitForResult(intent, SELECT_PICTURE);
            //getContext().getApplicationContext.startActivityforResult(intent, SELECT_PICTURE);
            //fragment.getApplicationContext.startActivityforResult(intent, SELECT_PICTURE);
            //getActivity().startActivityForResult(intent, SELECT_PICTURE);
            //startActivityForResult(intent, SELECT_PICTURE);
            //((SabaKuchHomeActivity)getActivity()).startActivitForResult(intent, SELECT_PICTURE);

            Log.d("first time", "before method22");

        }
    });


    APIAccess.fetchData(ProfileOzoneSetting.this, getActivity(), getActivity());
    return rootView;
}
@Override
 public void onActivityResult(int requestCode, int resultCode, Intent data) {


    Log.d("first time", "before method33");
      super.onActivityResult(requestCode, resultCode, data);

        Log.d("first time", "before method44");

        if (requestCode == SELECT_PICTURE && resultCode ==Activity.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);
            cursor.close();
            genSetOzoneUserImage.setImageBitmap(BitmapFactory.decodeFile(picturePath));

            setImg = true;
         }
          }

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
     AppContoller.getInstance().pref=getActivity().getSharedPreferences(AppContoller.getInstance().PREF_NAME, 0);



@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
}

public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = getActivity().managedQuery(uri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

Please let me know what mistake I am doing here???

Update

I did update SabaKuchHomeActivity and ProfileSettingFragment

The problem is that you are implementing onActivityResult in your Fragment and calling getActivity().startActivityForResult(...) . Because you are launching Activity from Activity, the onActivityResult(...) method call goes to the Activity that launches new Activity.

So all you need to do is remove the getActivity() part and your onActivityResult(...) will be called in your Fragment!

EDIT: As you can see from GrepCode, the code in Fragment 's startActivityForResult is different from Activity 's startActivityForResult . That sure ain't coincidence....

You should not use

getActivity().startActivityForResult(...)

Simply use

startActivityForResult(...)

This way the onActivityResult in your fragment will be called.

This is discussed in detail here and blogged about here and there is a bug report about it here .

The short version is: This is broken for nested fragements and you have to write your own workaround.

My suggestion would be to in your child fragment call:

getParentFragment().startActivityForResult(....)

and in your parent Fragment override onActivityResult and replay the call to your child fragments:

...
for (Fragment child : getChildFragmentManager().getFragments()) {
   child.onActivityResult(requestCode, resultCode, data);
}
...

Give it a try, When you call startActivityForResult(), onActivityResult() of the Activity is first called then onActivityResult() of its fragment is called but this call is not given to the nested fragment. So in onActivityResult() of your fragment you will have to get the current loaded fragment somehow, typecast it if needed and then call a method written inside it to which you pass whatever you get OnActivityResult().

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

  // notifying nested fragments (support library bug fix)
  final FragmentManager childFragmentManager = getChildFragmentManager();

  if (childFragmentManager != null) {
    final List < Fragment > nestedFragments = childFragmentManager.getFragments();

    if (nestedFragments == null || nestedFragments.size() == 0) return;

    for (Fragment childFragment: nestedFragments) {
      if (childFragment != null && !childFragment.isDetached() && !childFragment.isRemoving()) {
        childFragment.onActivityResult(requestCode, resultCode, data);
      }
    }
  }
}

Code in your fragment's onActivityResult() would look something like, Try to get the fragment from fragmentManager or with the help of your viewPagerAdapter Also try to call startActivityForResult as,

fragment.getParentFragment().startActivityForResult();

instead of

fragment.startActivityForResult();

Put this in your outer fragment to access the current loaded fragment,

MyFragment myFragment = (MyFragment)pagerAdapter.getCurrentFragment();
myFragment.myMethod();

And the below code in the adapter which will return the current fragment loaded, remember below is just for you to understand, use it in your code accordingly

Fragment fragment;

@Override
public Fragment getItem(int index) {
    fragment = new FragFilter();
    return fragment;
}

public Fragment getCurrentFragment() {
    return this.fragment;
}

Remove

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

in your activity and first fragment and maintain this in your nested fragment

and Even if not worked pass your activity instance while intializing fragment as

fragment = new ProfileSettingFragment(activity);

and create a constructor in fragment what your using with activity instance then you can call onActivityResult in main activity and can get data form that activity as you are passing activity reference while initializing your fragment.

You can create an interface which have a method will return a string and by implementing that in your activity you can receive the data through over where your activity reference available.

For some reason when you startActivityForResult from

android.support.v4.app.Fragment

wont work, it will go to your Activities onActivityResult. If you use

android.app.Fragment

it will work and return to your onActivityResult in Fragment.

Although i didn't test your code. I am writing this answer on my behalf.

getActivity.startActivityForResult(...)

should call Activity onActivityResult.

getParentFragment().onActivityResult(...)

should call onActivityResult in your parent fragment.

And

this.onActivityResult(...)

should should call your current fragment onActivityResult() method.

you can try these keyword as mentioned here. In case you still face problem let me know i'll a code sample on GIT

尝试这个:

getContext().getApplicationContext.startActivityforResult();

override onActivityResult in your SabaKuchHomeActivity use

public void dispatchTakePictureIntent() {
        final int TAKE_PHOTO_RESULT_CODE = 2345;
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent
                .resolveActivity(getActivity().getPackageManager()) != null)
            if (getParentFragment() != null)
                getParentFragment().startActivityForResult(takePictureIntent, TAKE_PHOTO_RESULT_CODE);
            else
                startActivityForResult(takePictureIntent, TAKE_PHOTO_RESULT_CODE);
    }

    public void dispatchChoosePictureIntent() {
        final int CHOOSE_PHOTO_RESULT_CODE = 1234;
        Intent intent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");
        if (getParentFragment() != null)
            getParentFragment().startActivityForResult(Intent.createChooser(intent, "Choose Picture"),
                    CHOOSE_PHOTO_RESULT_CODE);
        else
            startActivityForResult(Intent.createChooser(intent, "Choose Picture"),
                    CHOOSE_PHOTO_RESULT_CODE);
    }

Use getParentFragment() if you are using custom fragment or/and viewpager, otherwise igonre/remove getParentFragment()

Simple solution just call the startActivityForResult(/* … */) only and onActivityResult(/* … */) in your fragment will be called. I usually use this.

we can also implement onActivityResult() in your Fragment as well.

so dear for your code just remove getActivity. from getActivity.startActivityForResult(...) then it will calls onActivityResult() of your fragment. for more information see this link . enjoy your code:)

It became a longer code ,i will just do a brief walkthrough -(since its a bounty) and that's all. here is the xml i used. the rest java

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/rumorsapp.ghaweek"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="rumorsapp.ghaweek.MainActivity" >

<android.support.design.widget.TabLayout
    android:id="@+id/tablayou"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:background="#ff9900"
    android:minHeight="50dp"
    app:tabIndicatorColor="#f09"
    app:tabMode="scrollable"
    app:tabPadding="10dp"
    app:tabSelectedTextColor="#004"
    app:tabTextColor="#fff" >
</android.support.design.widget.TabLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_marginTop="2dp"
    android:layout_below="@+id/tablayou"
    android:layout_height="match_parent"/>
</RelativeLayout>

All i did to make it work was create an interface called ActivityResHan which simply had a method called initiate(String fragmentTag); ( my names are poor -i know ) the logic was to have my direct Fragment -( fragment containing the viewpager or the Child that fornicated and has kids ) implement this ActivityResHan interface

class ViewPagerFragment extends Fragment implements ActivityResHan{

which was to going to call the startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); to retrieve a Contact from the content provider.

@Override
    public void initiate(String fragmentTag) {
        calleer = fragmentTag; //this calleer saves the tag
        Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
        pickContactIntent.setType(Phone.CONTENT_TYPE);
        startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
    }

This direct-Fragment 's onActivityResult checks if calleer is empty -( i hope you have already met calleer ) if its not then it calls the onActivityResult for his/her children, and it recognises its children by Tag , through FragmentManager.findFragmentByTag(); that's where calleer comes in

and now Every Child of the direct-Fragment , when it needs to start an activity for result just finds the direct-Fragment by Tag -( viewpageframent ) and then cast that Fragment to ActivityResHan and calls initiate(fragmentTag);

((ActivityResHan)getActivity().getSupportFragmentManager().
                            findFragmentByTag("viewpageframent")).initiate(getTag());

The rest of the codes makes it all happen .

import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.design.widget.TabLayout.OnTabSelectedListener;
import android.support.design.widget.TabLayout.Tab;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

/*
 *  FOr simplicity i added compacted classes, but the idea is, it is suppose
 *  to work even if you have separate clases. you may even reslove to getting
 *  rid of the interface, and using request code, as the tag. so you can 
 *  identify them there.
 */

//i am in my separate class
interface ActivityResHan{

    void initiate(String fragmentTag);
}
//i am in my separate class
public class MainActivity extends AppCompatActivity {

String ANDROID_PAGER_TAG_REFERER = "android:switcher:2131296359:";
ViewPager mViewPager;
TabLayout tabl;
FrameLayout fl;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    fl = new FrameLayout(this);
    fl.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
            LayoutParams.MATCH_PARENT));
    fl.setId(2);
    setContentView(fl);
    getSupportFragmentManager().beginTransaction().
    add(2,new ViewPagerFragment(), "viewpageframent").commit();

}

//i am in my separate class
private class ViewPagerFragment extends Fragment implements ActivityResHan{
    static final int PICK_CONTACT_REQUEST = 1; 
    String calleer = "";

    @Override
    @Nullable
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.activity_main, null);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onViewCreated(view, savedInstanceState);
        tabl = (TabLayout) view.findViewById(R.id.tablayou);
        mViewPager = (ViewPager) view.findViewById(R.id.pager);
        tabl.setTabsFromPagerAdapter(new FragmentPAdapt());
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabl));

        tabl.setOnTabSelectedListener(new OnTabSelectedListener() {

            @Override
            public void onTabUnselected(Tab arg0) {

            }

            @Override
            public void onTabSelected(Tab arg0) {
                mViewPager.setCurrentItem(arg0.getPosition());
            }

            @Override
            public void onTabReselected(Tab arg0) {

            }
        });
    }

    @Override
    public void initiate(String fragmentTag) {
        calleer = fragmentTag;
        Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
        pickContactIntent.setType(Phone.CONTENT_TYPE);
        startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode,
            Intent data) {
        if(!calleer.isEmpty()){
            Fragment fg =getSupportFragmentManager().findFragmentByTag(calleer);
            fg.onActivityResult(requestCode, resultCode, data);
            calleer = "";
        }else{
            //run my own shit
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

}
//i am in my separate class
private class FragmentPAdapt extends FragmentPagerAdapter{

    private class Thefrag extends Fragment{
        TextView t;
        public Thefrag() {
            super();
        }
        @Override
        @Nullable
        public View onCreateView(LayoutInflater inflater,
                @Nullable ViewGroup container,
                @Nullable Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            LinearLayout v = new LinearLayout(MainActivity.this);
            v.setBackgroundColor(Color.WHITE);
            t = new TextView(MainActivity.this);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, 
                    LinearLayout.LayoutParams.MATCH_PARENT);
            lp.gravity = Gravity.CENTER_VERTICAL|Gravity.FILL_VERTICAL;
            t.setLayoutParams(lp);
            t.setText("         This is frag " +getTag().subSequence(
                    getTag().length()-1,
                    getTag().length()));
            t.setTextSize(15f);
            v.setClickable(true);
            v.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View arg0) {
                    ((ActivityResHan)getActivity().getSupportFragmentManager().
                            findFragmentByTag("viewpageframent")).initiate(getTag());
                }
            });
            v.addView(t);
            return v;
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode,
                Intent data) {
            // TODO Auto-generated method stub
            t.setText("               Contact uri is = " + data.getDataString());
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    public FragmentPAdapt() {
        super(getSupportFragmentManager());
        mViewPager.setAdapter(this);
    }

    @Override
    public Fragment getItem(int arg0) {
        Fragment f = getSupportFragmentManager().findFragmentByTag(
                ANDROID_PAGER_TAG_REFERER + String.valueOf(arg0));
        if(f == null){
            return new Thefrag();
        }
        return f;
    }

    @Override
    public int getCount() {         
        return 10;
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return "FRAGMENT "+String.valueOf(position);
    }
 }

}

Hope it helps.

In Kotlin

In Activity :-

private var fragment: Fragment? = null

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.fragment_activity)

    fragment = Fragment()

 }

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    fragment?.onActivityResult(requestCode, resultCode, data)
}

In Fragment :- 

button.setOnClickListener {

activity?.startActivityForResult(Intent(parentActivity,
                SecondActivity::class.java), REQUEST_CODE)

}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    val string = data?.getStringExtra("SELECTED_NAME")
    Log.e("Name", "$string")
}

In SecondActivity :- 

override fun onOptionsItemSelected(item: MenuItem): Boolean {

    when (item.itemId) {
        android.R.id.home -> finish()

        R.id.action_filter_apply -> {
            val intent = Intent()
            intent.putExtra("SELECTED_NAME", "Android")
            setResult(Activity.RESULT_OK, intent)
            finish()
        }
    }

    return super.onOptionsItemSelected(item)
}
 

In your fragment override this method

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
}

and store the activity variable as a member of your class. This way you will always get the right activity, provided by the system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM