I'd like to replace a fragment, when a menu button is clicked. The toast is displayed, but it seems like I have a problem with the FragmentTransaction, since it tells me it
Description Resource Path Location Type
Cannot instantiate the type FragmentTransaction ActivityAppLaunch.java /juraQuiz/src/com/pthuermer/juraquiz line 71 Java Problem
this is what I tried:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.actionbar_menu_info) {
Toast.makeText(getApplicationContext(), "Info", Toast.LENGTH_LONG).show();
FragmentTransaction ft = new FragmentTransaction();
Fragment fragment = new FragmentInfo();
ft.replace(R.id.container, fragment);
}
if (id == R.id.actionbar_menu_settings) {
Toast.makeText(getApplicationContext(), "Settigns", Toast.LENGTH_LONG).show();
}
return super.onOptionsItemSelected(item);
}
try FragmentManager
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = new FragmentInfo();
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
Related
Recently i'm working on my app to make it load faster and work better, i'm using navigation drawer in my MainActivity:
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camara) {
LoadJson asyncTask = (LoadJson) new LoadJson(new LoadJson.AsyncResponse() {
#Override
public void processFinish(JSONArray output) {
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
//Set the fragment initially
MainFragment fragment = new MainFragment(output);
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
// Handle the camera action
}
}).execute();
} else if (id == R.id.nav_gallery) {
//Set the fragment initially
GalleryFragment fragment = new GalleryFragment();
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else if (id == R.id.nav_search) {
//Set the fragment initially
FetchResualt fragment = new FetchResualt();
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
// Handle the camera action
} else if (id == R.id.nav_manage) {//
Bundle bundle = new Bundle();//
bundle.putInt("someStr",ID_OF_BEACH);//
//Set the fragment initially//
FragmentBeach fragment = new FragmentBeach();//
fragment.setArguments(bundle);//
FragmentTransaction fragmentTransaction =//
getSupportFragmentManager().beginTransaction();//
fragmentTransaction.replace(R.id.fragment_container, fragment);//
fragmentTransaction.commit();//
// Handle the camera action
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
As you can see if we push the first menu if (id == R.id.nav_camara) it will pass a JSONArray to a Fragment class and it take like 4-5 seconds to load. So if the user navigates between menus every time he goes to nav_camara it make the app a 4 second freeze to load and as you can see everytime we choose a menu item it will recreate a new copy of fragment, so even if I make: setRetainInstance(true); in my fragment class it wont work.
What solution you suggest to prevent the app to recreate a new fragment each time we choose a menu item?
You will need to keep a SparseArray<Fragment> to keep the instances in memory.
Follow these steps:
create a field in your Activity:
SparseArray<Fragment> myFragments;
initialise it in the onCreate() like:
myFragments = new SparseArray<Fragment>();
update your onNavigationItemSelected():
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camara) {
// get cached instance of the fragment
fragment = myFragments.get(INT_CONSTANT_FOR_CAM_FRAGMENT);
// if fragment doesn't exist in myFragments, create one and add to it
if (fragment == null) {
fragment = new MainFragment();
myFragments.put(INT_CONSTANT_FOR_CAM_FRAGMENT, fragment);
}
// now load the fragment
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
// do the rest with others as well.
}
move the AsyncTask thing inside your MainFragment's onActivityCreated() or a similar lifecycle method.
Above way will let you reuse the fragments and move the logic to their correct location (your Activity shouldn't know how MainFragment loads data to initiate itself, but of course you can still keep it there, though not recommended).
You can add a TAG while push a new fragment to the container. Then use FragmentManager#findFragmentByTag to find any fragment previously added with the same tag.
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
Fragment oldFragment = manager.findFragmentByTag(tag);
if (oldFragment != null)
transaction.replace(R.id.fragment_container, oldFragment, tag);
else
transaction.replace(R.id.fragment_container, newInstanceOfFragment, tag);
transaction.commit();
Declare them globally
GalleryFragment galleryFrag = new GalleryFragment();
FragmentTransaction ft;
FragmentManager fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
fm = getSupportFragmentManager();
...
}
then on your navigation selection
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_search) {
ft = fm.beginTransaction();
ft.replace(R.id.fragment_container, galleryFrag).commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
I have some problem with Fragment and addToBackStack. I am create some project using Activity, Fragment, ActionBar, navigation spinner. Activity (MainActivity) is parent with two fragment (BestFragment and CurrFragment). BestFragment using action bar with navigation spinner to call two data (Buy and Sell) and display in Listview (default load is Buy data). When listview (BestFragment) setonitemclicklistener then calling detail selected item and display to CurrFragment. I am using addToBackStack from BestFragment to CurrFragment. When i am choose Sell data from navigation spinner (BestFragment) and selected item in Listview, it will be send detail on CurrFragment. If i am press back button in action bar (CurrFragment), that's can be back to BestFragment but that's load default Buy data (not Sell data on previous BestFragment). Help me.
Main Activity
#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_settings:
return true;
case android.R.id.home:
getFragmentManager().popBackStack();
getActionBar().setTitle(mTitle);
//setTitle(navMenuTitles[1]);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
BestFragment
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int p,
long arg3) {
// TODO Auto-generated method stub
//ambil mata uang
String des = bestList.get(p).getMataUang();
//ambil kata terakhir textview
String a[] = textinfobest.getText().toString().split(" ");
String last_text = a[a.length-1];
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
CurrFragment llf = new CurrFragment();
Bundle bundle = new Bundle();
bundle.putString("tambah title", des +" "+last_text);
bundle.putString("pilih",des+last_text);
llf.setArguments(bundle);
ft.replace(R.id.frame_container, llf);
ft.addToBackStack(null);
ft.commit();
}
});
I have an activity and in that i have a textView,Framelayout(having fragments) and a button. while clicking on the button , i am changing the fragments in framelayout and text in textView (according to fragments). On pressing the back button of my phone i am somehow able to get previous fragment with onBackpressed function but not able to get the previous value on the textView. how to do it.
public class Quetionare extends AppCompatActivity {
Toolbar toolbar;
TextView tv;
Fragment fr;
Button next;
intro into;
SelectCar selectCar;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quetionare);
initToolbar();
next=(Button)findViewById(R.id.button2);
tv = (TextView)findViewById(R.id.textView5);
fr = new intro();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.container, fr);
fragmentTransaction.commit();
}
private void initToolbar()
{
toolbar = (Toolbar)findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
final ActionBar actionBar = getSupportActionBar();
if (actionBar != null)
{
actionBar.setDisplayHomeAsUpEnabled(true);
}
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
public void selectFrag(View view)
{
if(view==findViewById(R.id.button2))
{
fr = new SelectCar();
next.setVisibility(View.GONE);
tv.setText("Select Your car model and Plan");
}
else
{
fr = new Checkbox();
tv.setText("Make Your Plan");
}
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.container, fr);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
#Override
public void onBackPressed()
{
if(getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
if (fr == into)
{
next.setVisibility(View.VISIBLE);
}
else
{
next.setVisibility(View.GONE);
}
}
else
super.onBackPressed();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_quetionare, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
}
You will have to save the value in the TextView when transitioning to your second fragment to a field, and then call setText using that value when you are navigating back.
we need to use findfragmentbyid method. By using this i have achieved desired functionality. thanks
I have been searching for showing fragments but the problem still exists and I can't get it to work.
my problem is when ever I add repeat_entry to menu for showing another fragment, that fragment is not showing but when I click on action_settings the fragment for that one is showing.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.animator.fade_in,android.R.animator.fade_out);
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
selectTabToShow(String.valueOf(R.id.action_search));
CategorySettings fragemnt = (CategorySettings) getFragmentManager().findFragmentById(R.id.categorySettings);
fragemnt.refresCategoryList();
Fragment fragment = new CategorySettings();
ft.add(R.id.category_cont,fragment,"asdf");
ft.commit();
return true;
}else if(id == R.id.repeat_entry){
Toast.makeText(MainActivity.this,"ssdf sdf",Toast.LENGTH_SHORT).show();
Fragment fragment = new RepeatEntry();
ft.add(R.id.category_cont,fragment,"repeat tag");
ft.commit();
Toast.makeText(MainActivity.this,"ssdf sdf",Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
As of now this is my RepeatEntry fragments
public class RepeatEntry extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
View v = inflater.inflate(R.layout.repeat_entry,container,false);
return v;
}
}
Please help me guys I'm new to this.
Try to replace
ft.replace(R.id.category_cont,fragment,"repeat tag");
How can i translate fragment when i click back button?
#Override
public void onBackPressed()
{
FragmentTransaction ft;
ft = fm.beginTransaction();
ft.replace(R.id.fragment_content, new RMBTStartFragment());
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
Thank you.
put your code into
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
if (id == android.R.id.home) {
// your code
}
else if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
and put getSupportActionBar().setDisplayHomeAsUpEnabled(true); in your onCreate