17

I have a Fragment called "MeinProfilFragment". And a MainActivity which handles the ActionBar-Tabs logic.

In the "MeinProfilFragment" i have put the logic for a "Login-Process".

After the user logged in successfully i want to display another layout.

How to do ? It is possbile to replace a Fragment within a Fragment ? Or do i have to call the MainActivity for UI-Updates ?

Here is the code of the "MainActivity":

public class MainActivity extends Activity {

public static int selectedTab;

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

    ActionBar actionBar = getActionBar();

    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);    
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowCustomEnabled(false);

    Tab meinProfil = actionBar.newTab().setText("Mein Profil");
    TabListener<MeinProfilFragment> tabListenerMeinProfil = new TabListener<MeinProfilFragment>(this,"Mein Profil",MeinProfilFragment.class);
    meinProfil.setTabListener(tabListenerMeinProfil);
    actionBar.addTab(meinProfil);

    Tab mitglieder = actionBar.newTab().setText("Mitglieder");
    TabListener<MitgliederFragment> tabListenerMitglieder = new TabListener<MitgliederFragment>(this,"Mitglieder",MitgliederFragment.class);
    mitglieder.setTabListener(tabListenerMitglieder);
    actionBar.addTab(mitglieder);

    Tab dinner = actionBar.newTab().setText("Dinner");
    TabListener<DinnerFragment> tabListenerDinner = new TabListener<DinnerFragment>(this,"Dinner",DinnerFragment.class);
    dinner.setTabListener(tabListenerDinner);
    actionBar.addTab(dinner);

    Tab community = actionBar.newTab().setText("Community");
    TabListener<CommunityFragment> tabListenerCommunity = new TabListener<CommunityFragment>(this,"Community",CommunityFragment.class);
    community.setTabListener(tabListenerCommunity);
    actionBar.addTab(community);

    if(savedInstanceState != null){
        actionBar.setSelectedNavigationItem(savedInstanceState.getInt("selectedTab"));
    }
}


private static class TabListener<T extends Fragment> implements ActionBar.TabListener
{
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    public TabListener(Activity activity,String tag,Class<T> clz) {
         mActivity = activity;
         mTag = tag;
         mClass = clz; 
    }
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        selectedTab = tab.getPosition();
        Fragment prevFragment;
        FragmentManager fm = mActivity.getFragmentManager();
        prevFragment = fm.findFragmentByTag(mTag); 
        if (prevFragment != null) { 
            mFragment = prevFragment; 
        }
        if(mFragment == null){
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment,mTag);
        }else{
            ft.attach(mFragment);
        }   
     }
    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        selectedTab = tab.getPosition();
        if(mFragment != null){
             ft.detach(mFragment);
        }else{
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment,mTag);
        }
    }
    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        selectedTab = tab.getPosition();
    }   
}
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("selectedTab", selectedTab);
}   

And here is the MeinProfilFragment:

public class MeinProfilFragment extends Fragment implements OnClickListener{

EditText LoginEmail;
EditText LoginPassw;
Button LoginButton;
public boolean loggedIn = false;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
    View view =  inflater.inflate(R.layout.mein_profil_fragment,container, false);
    LoginEmail = (EditText) view.findViewById(R.id.login_email_input);
    LoginPassw = (EditText) view.findViewById(R.id.login_passwort_input);
    LoginButton  = (Button) view.findViewById(R.id.login_submit);
    LoginButton.setOnClickListener(this);
    return view;
}

@Override
public void onClick(View arg0) {
    switch(arg0.getId())
    {
        case R.id.login_submit:
            // Get Input Values:
            String login_email = LoginEmail.getText().toString();
            String login_passw = LoginPassw.getText().toString();
            if(login_email.length()<6 || login_passw.length()<4){
                return;
            }   
            Log.i("TEST","onClick: E-Mail: "+login_email+" \n Passwort: "+login_passw);
            new Login().execute(login_email,login_passw);
        break;
    }
}

private class Login extends AsyncTask<String,Void,JSONObject>
{
    @Override
    protected JSONObject doInBackground(String... params) {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost("xxxx");
        try{
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("mitglied_email",params[0]));
            nameValuePairs.add(new BasicNameValuePair("mitglied_passwort",params[1]));
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            InputStream is = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
            String line = reader.readLine();
            JSONObject jsonData = new JSONObject(line);
            return jsonData;
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(JSONObject result) {
        super.onPostExecute(result);
        updateUi(result);
    }   
}

public void updateUi(JSONObject result)
{
    try {
        Log.i("TEST",result.getString("logged_in"));
        String loggedInFlag = result.getString("logged_in");
        if(loggedInFlag.equals("true")){
            // Richtige Angaben:
            Log.i("TEST","loggedInFlag EQ TRUE");
            loggedIn = true;

            // Here i want to replace this current fragment with another called e.g "ProfileFragment"

        }else{
            // Falsche Angaben:
            Log.i("TEST","loggedInFlag EQ FALSE");
            loggedIn = false;
        }

    } catch (JSONException e) {
        e.printStackTrace();
    }
}

In the updateUi() method i want to show/inflate another UI.

How to do ? Is there a way to "restart" the Fragment and then inflate another Fragment-Layout in the onCreateView().

Or it is possible to Replace the Fragment-Layout with another Fragment-Layout within the Fragment ?

Whats the best practice ?

JuJu
  • 307
  • 1
  • 3
  • 18

1 Answers1

19

you can replace fragment by using this

FragmentManager fragmentManager2 = getFragmentManager();
FragmentTransaction fragmentTransaction2 = fragmentManager2.beginTransaction();
DetailFragment fragment2 = new DetailFragment();
fragmentTransaction2.addToBackStack("xyz");
fragmentTransaction2.hide(MeinProfilFragment.this);
fragmentTransaction2.add(android.R.id.content, fragment2);
fragmentTransaction2.commit();
JuJu
  • 307
  • 1
  • 3
  • 18
Sanket Kachhela
  • 10,861
  • 8
  • 50
  • 75
  • 2
    You forgot to add the new fragment to the backstack after the replace, 'fragmentTransaction2.addToBackStack(null); – K Roobroeck Jan 17 '13 at 12:13
  • Hi, ok...i have added the code above to my updateUi() method.But what to put into fragmentTransaction2.replace(R.id.xxx, fragment2); ? R.id.fragmentid? I have not defined the Fragment in an xml file. – JuJu Jan 17 '13 at 12:20
  • @SanketKachhela that's true, I added it only for the sake of completion. – K Roobroeck Jan 17 '13 at 12:21
  • @JulianFürderer what you have define in XML? FrameLayout? – Sanket Kachhela Jan 17 '13 at 12:22
  • I tried to put the top-level "LinearLayout" to first param of replace()...that worked, but the old fragment doesnt disappear,- the text of the fragment2 becomes visible at the bottom. – JuJu Jan 17 '13 at 12:23
  • I dont know exactly what to put as first param in add(). What ID ? Should i add Fragment with IDS to an xml-file ? Actually i have the first param containing the top-level LinearLayout-ID of the current fragment – JuJu Jan 17 '13 at 12:31
  • MeinProfilFragment XML-Layout: xxxxx – JuJu Jan 17 '13 at 12:37
  • yes...that works,- the current fragment disappears, BUT the new layout of the fragment2 isnt shown, the screen is empty (except the tabs above). The fragment2 Layout contains a LinearLayout with a textview and a button. – JuJu Jan 17 '13 at 12:45
  • remove hide statement and see.. i am not sure about that. – Sanket Kachhela Jan 17 '13 at 12:49
  • By removing the hide(), the layout of fragment2 is show BUT below the layout of the current fragment ;-) – JuJu Jan 17 '13 at 12:51
  • i am using replace method instead of add method. add method was another option for me. replace is working for me – Sanket Kachhela Jan 17 '13 at 13:00
  • With replace its the same result as with removing hide():he layout of fragment2 is show BUT below the layout of the current fragment – JuJu Jan 17 '13 at 13:05
  • its working with: fragmentTransaction2.add(android.R.id.content, fragment2); – JuJu Jan 17 '13 at 13:09
  • The above code is written where ?? In fragment or activity ?? – Rahul Kumar Aug 16 '17 at 06:35
  • @RahulKumar I think it should be written in the host activity. Fragments should never communicate with other fragments directly. – winklerrr Sep 20 '17 at 14:43
  • @SanketKachhela: if android.R.id.content is in the MaiActivity xml, you can't access it from a fragment!!! – msc87 Oct 24 '18 at 09:59