Fragments and getFragmentManager and version compatibility - java

I am fairly new to coding and have looked everywhere but may not be looking correctly. I am having a problem with the placeholders. Not sure to have the support or not for the fragment manager being it is v7 support
Error:(21, 32) error: no suitable method found for add(int,ListFragment)
method FragmentTransaction.add(Fragment,String) is not applicable
(argument mismatch; int cannot be converted to Fragment)
method FragmentTransaction.add(int,Fragment) is not applicable
(argument mismatch; ListFragment cannot be converted to Fragment)
Here is my code
package chris.smellslikebacon;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements ListFragment.OnRecipeSelectedInterface {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListFragment savedFragment = (ListFragment) getSupportFragmentManager().findFragmentById(R.id.placeholders);
if(savedFragment == null) {
ListFragment fragment = new ListFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.placeholders, fragment);
fragmentTransaction.commit();
}
}
#Override
public void onListRecipeSelected(int index) {
Toast.makeText(MainActivity.this, Recipes.names[index], Toast.LENGTH_SHORT).show(); }
}

I think you should use getSupportFragmentManager instead for support:
FragmentManager fragmentManager = getSupportFragmentManager();
Hope this helps.

Related

FragmentTransaction add method is accepting the wrong parameter

Hey guys I was learning how to create an Android apps and today I am trying to make Fragment. So the method add has several type of parameter input (cause Android studio shows me 3 different parameter input), like (Fragment, String) (Int, Fragment) and (Int, Fragment, String). What I want to do is to use the first type of parameter, but somehow AndroidStudio keeps on detecting my code as (Int, Fragment).
This is the screenshot
I have looked up in the other stackoverflow forum and I have make sure that I use
import android.support.v4.app.FragmentTransaction;
Here is my code btw:
package listview.bookapp.activities;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import listview.bookapp.R;
public class ProfileMainActivity extends FragmentActivity {
Button profileMain;
Button profileEdit;
FrameLayout frameLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile_main);
profileMain = findViewById(R.id.profile_main);
profileEdit = findViewById(R.id.profile_edit);
frameLayout = findViewById(R.id.frameForFragment);
profileMain.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
ProfileMainFragment profileMainFrag = new ProfileMainFragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.frameForFragment, profileMainFrag);
ft.commit();
}
});
profileEdit.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
ProfileEditFragment profileEditFrag = new ProfileEditFragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.frameForFragment, profileEditFrag);
ft.commit();
}
});
}
}
Wonder if I missed something or this is just a bug from AndroidStudio (I am using Android Studio 3.2.1).
Cheers!

Error:(31, 40) error: incompatible types: android.support.v4.app.Fragment cannot be converted to android.app.Fragment

I have a problem in this code and I don't know which one I should use android.support.v4.app.Fragment or android.app.Fragment;
public class MainActivity extends AppCompatActivity {
private SharedPreferences pref;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pref = getPreferences(0);
initFragment();
}
private void initFragment(){
android.support.v4.app.Fragment fragment;
if(pref.getBoolean(Constants.IS_LOGGED_IN,false)){
fragment = new ProfileFragment();
}else {
fragment = new LoginFragment();
}
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_frame,fragment);
ft.commit();
}
}
Do not mismatch android.support.v4.app.Fragment with android.app.Fragment, use anyone of them in the whole app.
private void initFragment(){
android.support.v4.app.Fragment fragment;
if(pref.getBoolean(Constants.IS_LOGGED_IN,false)){
fragment = new ProfileFragment();
}else {
fragment = new LoginFragment();
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_frame,fragment);
ft.commit();
}
OR
private void initFragment(){
android.app.Fragment fragment;
if(pref.getBoolean(Constants.IS_LOGGED_IN,false)){
fragment = new ProfileFragment();
}else {
fragment = new LoginFragment();
}
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_frame,fragment);
ft.commit();
}
So if you are using support libraries then use getSupportFragmentManager() and it's supported other methods which are related to support library or else for android app fragment usage don't use support library function. It will create issues with 'Type mismatch'.
And this is highly recommended.
Support library imports for fragment trasaction:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
Android library imports for fragment transactions:
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;

How to call dialogfragment from another fragment?

I'm really new in android development, hope you guys can help me in my problem. I had already search for any solution but none of it works.
I have 6 fragments for scrollable tabs, then each tabs has ADD TO CART buttons, if I click that button a fragment dialog should appear. In my case, there is this error.
Error:(37, 13) error: no suitable method found for show(android.support.v4.app.FragmentManager,String)
method DialogFragment.show(android.app.FragmentManager,String) is not applicable
(argument mismatch; android.support.v4.app.FragmentManager cannot be converted to android.app.FragmentManager)
method DialogFragment.show(FragmentTransaction,String) is not applicable
(argument mismatch; android.support.v4.app.FragmentManager cannot be converted to FragmentTransaction)
Heres my code by the way for the fragment to call the DialogFragment.
package info.androidhive.materialtabs.fragments;
import android.app.DialogFragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import info.androidhive.materialtabs.R;
public class OneFragment extends Fragment{
public OneFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_one, container, false);
}
public void toDiagCartFragment(View v){
FragmentManager manager = getFragmentManager();
CartFragment cart = new CartFragment();
cart.show(manager, "My Cart");
}
}
This the code for DialogFragment to be called by OneFragment
package info.androidhive.materialtabs.fragments;
import android.app.DialogFragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import info.androidhive.materialtabs.R;
public class CartFragment extends DialogFragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_cart2, null);
}
}
Seems like the error is in the OneFragment.java
Heres my output by the way.
_I really appreciate for any answers, just please be nice to me
.I really don't know how to do it . :(
.Thanks :)
your error says your answer clearly.
type mismatch
your dialogFragment has android.app.FragmentManager and you are calling android.support.v4.app.FragmentManager. you should use getSupportFragmentManger() insted of getFragmentManager();
first of all replace your cartFragment import to this,
import android.support.v4.app.DialogFragment;
and create this method.
public static CartFragment newInstance() {
CartFragment dialog = new CartFragment ();
return dialog;
}
and in your one_fragment use like this.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
CartFragment newFragment = CartFragment .newInstance();
newFragment.show(ft, "My Cart");
your OneFragment belongs to support library fragment while CartFragment doesn't. you need to either modify CartFragment to support library or OneFragment to default Fragment. and modifying CartFragment to support library fragment will be better as support library has more functionality.
There is a version mismatch. Instead of using getFragmentManager(), use getSupportFragmentManager() as you are using the support library version of Fragments.
Replace
FragmentManager manager = getFragmentManager();
with
FragmentManager manager = getSupportFragmentManager();

getSupportFragmentManager(); instance

I am using 3 classes to reuse how the fragments should be placed in the screen. The First class is generic abstract class that are used to add the fragment to the transaction. The other two classes are extending the abstract class with an implementation for the fragment.
The First Class:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
public abstract class SingleFragmentActivity extends FragmentActivity {
protected abstract Fragment createFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
}
}
}
2nd Class
import android.support.v4.app.Fragment;
public class CrimeActivity extends SingleFragmentActivity {
#Override
protected Fragment createFragment() {
return new CrimeFragment();
}
}
3rd Class
import android.support.v4.app.Fragment;
public class CrimeListActivity extends SingleFragmentActivity{
#Override
protected Fragment createFragment() {
return new CrimeListFragment();
}
}
With the above, does i am using the same reference of getSupportFragmentManager(); that was already defined in the abstract generic class, or each one of the 2nd and 3rd Class get their own references. How Java really works here?
Am I using the same reference of getSupportFragmentManager();?
Yes, that is how class inheritance works in Java. FragmentActivity#getSupportFragmentManager() is the same method in all your classes.

Pop fragment from backstack

I am trying to create an activity which holds two fragments. One fragment is displayed when the activity starts and the other one is displayed when the user press a button in the toolbar.
In the second fragment I want to add back navigation and when the user press the back button the second fragment should close and the first one should appear.
But I am getting some errors and I couldn't fix them.
MainActivity.java
package com.geapps.notapp.activities;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import com.geapps.notapp.R;
import com.geapps.notapp.fragments.MainFragment;
import com.geapps.notapp.fragments.NewNoteFragment;
public class MainActivity extends ActionBarActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null)
{
loadFragment(new MainFragment(), "Main");
}
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
toolbar.setTitle("Toolbar");
toolbar.inflateMenu(R.menu.main);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener()
{
#Override
public boolean onMenuItemClick(MenuItem menuItem)
{
switch (menuItem.getItemId())
{
case R.id.action_new:
loadFragment(new NewNoteFragment(), "New Note");
break;
}
return false;
}
});
}
public void loadFragment(Fragment fragment, String tag)
{
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.main_container, fragment, tag);
fragmentTransaction.addToBackStack(tag);
fragmentTransaction.commit();
}
}
MainFragment.java
package com.geapps.notapp.fragments;
import java.util.ArrayList;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import com.geapps.notapp.R;
import com.geapps.notapp.adapters.NotesListAdapter;
import com.geapps.notapp.models.Note;
public class MainFragment extends Fragment
{
private View view;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_main, container, false);
loadNotes();
return view;
}
private void loadNotes()
{
ListView notesList = (ListView)view.findViewById(R.id.notes_list);
ArrayList<Note> notes = new ArrayList<Note>();
notes.add(new Note("Sunday homework", "1. Do math homework and then sleep"));
notes.add(new Note("Job details", "Programming job especially iOS and Android development"));
notes.add(new Note("Journal Part 1", "What am I going to do now? I have no way to run .. :("));
NotesListAdapter notesListAdapter = new NotesListAdapter(this.getActivity(), notes);
notesList.setAdapter(notesListAdapter);
}
}
NewNoteFragment.java
package com.geapps.notapp.fragments;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.geapps.notapp.R;
public class NewNoteFragment extends Fragment
{
private View view;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_new_note, container, false);
Toolbar toolbar = (Toolbar)getActivity().findViewById(R.id.toolbar);
toolbar.getMenu().findItem(R.id.action_new).setVisible(false);
toolbar.setNavigationIcon(R.drawable.ic_action_back);
toolbar.setNavigationOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.popBackStack("Main", FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
});
return view;
}
}
And here are the errors:
PathClassLoader(BaseDexClassLoader).findClass(String) line: 61
PathClassLoader(ClassLoader).loadClass(String, boolean) line: 501
PathClassLoader(ClassLoader).loadClass(String) line: 461
BackStackRecord.getEnterTransition(Fragment, boolean) line: 1056
BackStackRecord.configureTransitions(int, BackStackRecord$TransitionState, boolean, SparseArray, SparseArray) line: 1138
BackStackRecord.beginTransition(SparseArray, SparseArray, boolean) line: 1029
BackStackRecord.popFromBackStack(boolean, BackStackRecord$TransitionState, SparseArray, SparseArray) line: 883
FragmentManagerImpl.popBackStackState(Handler, String, int, int) line: 1593
FragmentManagerImpl$3.run() line: 509
FragmentManagerImpl.execPendingActions() line: 1489
FragmentManagerImpl$1.run() line: 454
Handler.handleCallback(Message) line: 615
FragmentActivity$1(Handler).dispatchMessage(Message) line: 92
Looper.loop() line: 137
ActivityThread.main(String[]) line: 4921
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 511
ZygoteInit$MethodAndArgsCaller.run() line: 1038
ZygoteInit.main(String[]) line: 805
NativeStart.main(String[]) line: not available [native method]
Try using this
getActivity().getSupportFragmentManager().popBackStack();
Instead of making it custom, let the system handle itself. Make following changes and give it a try:
public void loadFragment(Fragment fragment, String tag)
{
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.main_container, fragment, tag);
// fragmentTransaction.addToBackStack(tag);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
and
toolbar.setNavigationOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
// fragmentManager.popBackStack("Main", FragmentManager.POP_BACK_STACK_INCLUSIVE);
// fragmentManager.popBackStack();
getActivity().onBackPressed();
}
});
Although very late but for an easy approach try this:
When you add your first fragment into your activity call addToBackStack(null) before you commit.This will allow users from second fragment to return the first Fragment by back button.
getFragmentManager().beginTransaction().replace(R.id.main_container, fragment).addToBackStack(null).commit();
Now Add this in your second fragment's on click method to remove second fragment and return to first fragment.
getActivity().getFragmentManager().beginTransaction().remove(this).commit();
//now recreating main activity to return to first fragment
getActivity().recreate();
Alternate and better aproach is using interface see android docs here
Try this anyone of this three methods
1.#
getActivity().getSupportFragmentManager().popBackStack();
2.#
getActivity().getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
3.#
getActivity().getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

Categories