Before I start, yes I have read countless related questions. I still can't seem to track down the issue.
I have a SherlockFragmentActivity:
package com.kicklighterdesignstudio.floridaday;
import android.os.Bundle;
import android.support.v4.app.Fragment;
public class FragmentActivity extends BaseActivity {
public static final String TAG = "FragmentActivity";
public static final int SCHEDULE_FRAGMENT = 0;
public static final int MAP_FRAGMENT = 1;
public static final int FOOD_FRAGMENT = 2;
public static final int TWITTER_FRAGMENT = 3;
public static final int HASHTAG_FRAGMENT = 4;
private Fragment mContent;
public FragmentActivity() {
super(R.string.main_activity_title);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_frame);
switchContent(SCHEDULE_FRAGMENT);
setBehindContentView(R.layout.menu_frame);
}
public void switchContent(int id) {
getFragment(id);
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, mContent)
.commit();
getSlidingMenu().showContent();
}
private void getFragment(int id) {
switch (id) {
case 0:
mContent = new ScheduleFragment();
break;
case 1:
mContent = new FoodFragment();
break;
case 2:
mContent = new MapFragment();
break;
case 3:
mContent = new TwitterFragment();
break;
case 4:
mContent = new HashtagFragment();
break;
}
}
}
It extends BaseActivity:
package com.kicklighterdesignstudio.floridaday;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import com.actionbarsherlock.view.MenuItem;
import com.slidingmenu.lib.SlidingMenu;
import com.slidingmenu.lib.app.SlidingFragmentActivity;
public class BaseActivity extends SlidingFragmentActivity {
// private int mTitleRes;
protected ListFragment mFrag;
public BaseActivity(int titleRes) {
// mTitleRes = titleRes;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setTitle(mTitleRes);
setTitle("");
// set the Behind View
setBehindContentView(R.layout.menu_frame);
if (savedInstanceState == null) {
FragmentTransaction t = this.getSupportFragmentManager().beginTransaction();
mFrag = new MenuFragment();
t.replace(R.id.menu_frame, mFrag);
t.commit();
} else {
mFrag = (ListFragment) this.getSupportFragmentManager().findFragmentById(
R.id.menu_frame);
}
// customize the SlidingMenu
SlidingMenu sm = getSlidingMenu();
sm.setShadowWidthRes(R.dimen.shadow_width);
sm.setShadowDrawable(R.drawable.shadow);
sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
sm.setFadeDegree(0.35f);
sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
sm.setBehindScrollScale(0.0f);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
toggle();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
Right now, I'm only concerned with ScheduleFragment:
package com.kicklighterdesignstudio.floridaday;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.actionbarsherlock.app.SherlockFragment;
public class ScheduleFragment extends SherlockFragment implements OnItemClickListener {
public static final String TAG = "ScheduleFragment";
private ArrayList<ScheduleItem> schedule;
private FloridaDayApplication app;
public ScheduleFragment() {
// setRetainInstance(true);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
app = (FloridaDayApplication) activity.getApplication();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.schedule_fragment, container, false);
}
#Override
public void onStart() {
super.onStart();
getSherlockActivity().getSupportActionBar().setTitle(R.string.schedule_fragment);
schedule = app.getSchedule();
ListView scheduleListView = (ListView) getActivity().findViewById(R.id.schedule_list);
ScheduleItemAdapter adapter = new ScheduleItemAdapter(getActivity(), schedule);
scheduleListView.setAdapter(adapter);
scheduleListView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> a, View v, int id, long position) {
Fragment newFragment = new ScheduleItemFragment(id);
FragmentTransaction transaction = getSherlockActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content_frame, newFragment).addToBackStack(null).commit();
}
}
ScheduleFragment displays a list of schedule items. When clicked, a new fragment is displayed (ScheduleItemFragment) to show details of the item and a map to its location:
package com.kicklighterdesignstudio.floridaday;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.MarkerOptions;
#SuppressLint("ValidFragment")
public class ScheduleItemFragment extends SherlockFragment {
public static final String TAG = "ScheduleItemFragment";
private int scheduleItemId;
private FloridaDayApplication app;
private ScheduleItem scheduleItem;
private MapView mapView;
private GoogleMap map;
public ScheduleItemFragment(int id) {
scheduleItemId = id;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
app = (FloridaDayApplication) activity.getApplication();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.schedule_item_fragment, container, false);
setHasOptionsMenu(true);
// Initialize MapView
mapView = (MapView) v.findViewById(R.id.map_view);
mapView.onCreate(savedInstanceState);
return v;
}
#Override
public void onStart() {
super.onStart();
scheduleItem = app.getSchedule().get(scheduleItemId);
getSherlockActivity().getSupportActionBar().setTitle(scheduleItem.getTitle());
// Map Stuff
map = mapView.getMap();
if (map != null) {
map.getUiSettings();
map.setMyLocationEnabled(true);
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
// Add marker to the map
MarkerOptions options = new MarkerOptions().position(scheduleItem.getLocation().getPosition()).title(
scheduleItem.getLocation().getTitle());
map.addMarker(options);
// Adjust Camera Programmatically
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
scheduleItem.getLocation().getPosition(), 14);
map.animateCamera(cameraUpdate);
} else {
Log.i(TAG, "Map is null");
}
// Other Views
TextView title = (TextView) getSherlockActivity().findViewById(R.id.title);
TextView time = (TextView) getSherlockActivity().findViewById(R.id.time);
TextView description = (TextView) getSherlockActivity().findViewById(R.id.description);
title.setText(scheduleItem.getTitle());
time.setText(scheduleItem.getDateTimeString());
description.setText(scheduleItem.getDescription());
}
// TODO: Make this work
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getFragmentManager().popBackStack();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public void onDestroy() {
mapView.onDestroy();
super.onDestroy();
}
#Override
public void onLowMemory() {
mapView.onLowMemory();
super.onLowMemory();
}
#Override
public void onPause() {
mapView.onPause();
super.onPause();
}
#Override
public void onResume() {
mapView.onResume();
super.onResume();
}
#Override
public void onSaveInstanceState(Bundle outState) {
mapView.onSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}
}
Thanks to BaseActivity, the icon in my ActionBar is clickable. It toggles the Sliding Menu. When viewing a ScheduleItemFragment, I would like the icon to return to the previous item in the backstack (which you can see I'm trying to do.) No matter what I try, the icon always toggles the Sliding Menu. Any thoughts on how to guarantee my Fragment gains control of the ActionBar menu clicks?
you need to call setHasOptionsMenu(true); in onCreate, not onCreateView
also I'm interested what happens when you debug, does onOptionsItemSelected still get called?
edit: add the following to your fragment
#Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
edit1:
there may be a better way to do this but I'm not exactly sure how your fragments are setup out, create a public field in baseActivity public bool isItemFragmentOnTop
now onOptionsItemSelected in the case of the home button getting press do this
if (isItemFragmentOnTop){
getFragmentManager().popBackStack();
isItemFragmentOnTop = false;
} else {
toggle();
}
return true;
then in your fragment you can call ((BaseActivity)getActivity).isItemFragmentOnTop = true; to make the home button pop the back stack, you would want to do this when you display your fragment onItemClick in your list view.
Related
I am attaching a fragment from a fragment that is attached to an activity and then inside the fragment i have set my custom toolbar with set setDisplayHomeUpEnabled to true. when am attaching the fragment i have set the Main activity toolbar to be hidden, the only problem is that it is not being unhidden when am returning to the parent fragment from the child fragment
package manu.apps.cartv6.Activities;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import manu.apps.cartv6.Classes.CartCounterConverter;
import manu.apps.cartv6.Classes.Config;
import manu.apps.cartv6.Classes.Product;
import manu.apps.cartv6.Classes.UserSessionManager;
import manu.apps.cartv6.Fragments.UserProfileFragment;
import manu.apps.cartv6.Fragments.ViewProductsFragment;
import manu.apps.cartv6.Interfaces.AddRemoveCallbacks;
import manu.apps.cartv6.R;
import manu.apps.cartv6.Tests.CartFragment;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, NavigationView.OnNavigationItemSelectedListener, AddRemoveCallbacks {
/** Lists*/
public static List<Product> cartList = new ArrayList<>();
/** Variables*/
// Counter for Cart
public static int cart_count = 0;
// Get Id for users
String getId;
// Time Interval for back button press
private static final int TIME_INTERVAL = 2000; // # milliseconds, desired time passed between two back presses.
// How long the back button has been pressed
private long backPressed;
//Getting Class Info
private static final String TAG = MainActivity.class.getSimpleName();
/** Views*/
// Toolbars
Toolbar toolbar;
// TextViews
TextView navHeaderUsername;
// ImageViews
ImageView navHeaderProfileImage;
/** Session Managing*/
UserSessionManager userSessionManager;
/** Navigation Drawer*/
//Declaring ActionBarDrawerToggle
private ActionBarDrawerToggle actionBarDrawerToggle;
//Declaring Navigation View
NavigationView navigationView;
//Declaring Drawer Layout
DrawerLayout drawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Creating a Session Manager for the Users
userSessionManager = new UserSessionManager(this);
userSessionManager.checkUserLogin();
//Finding Drawer Layout
drawerLayout = findViewById(R.id.drawer_layout);
//Finding Navigation View
navigationView = findViewById(R.id.navigation_view);
//Finding Toolbar
toolbar = findViewById(R.id.main_tool_bar);
//Toolbar Workings
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Home");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Setting View Products Fragment
Fragment fragment = new ViewProductsFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,fragment).commit();
//Setting ActionBarDrawerToggle to Open and Close
actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,R.string.open,R.string.close);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
// Setting Navigation Item Selected Listener for Items in Navigation View
navigationView.setNavigationItemSelectedListener(this);
/**
* app:headerLayout="#layout/layout_nav_header"
*
* Remove the above line in NavigationView because we are inflating programmatically
*
* */
View navView = navigationView.inflateHeaderView(R.layout.layout_nav_header);
//Finding Views in Navigation Header which is inside Navigation View
navHeaderUsername = navView.findViewById(R.id.nav_header_username);
navHeaderProfileImage = navView.findViewById(R.id.nav_header_profile_image);
// Parsing Username and Email
HashMap<String, String> user = userSessionManager.getUserDetails();
getId = user.get(userSessionManager.ID);
}
// Fetch User Details
private void fetchUserDetails(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
//progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.FETCH_USER_DETAILS,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
Log.i(TAG, response.toString());
try {
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
JSONArray jsonArray = jsonObject.getJSONArray("fetch");
if (success.equals("1")) {
for (int i = 0; i < jsonArray.length();i++) {
JSONObject object = jsonArray.getJSONObject(i);
String username = object.getString("username").trim();
String email = object.getString("email").trim();
// Set Details for the Navigation Header
navHeaderUsername.setText(username);
//etProfileUsername.setText(username);
//etProfileEmail.setText(email);
}
}
} catch (JSONException e) {
e.printStackTrace();
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "JSON Error fetching Details", Toast.LENGTH_SHORT).show();
Snackbar.make(getWindow().getDecorView().getRootView(),e.toString(),Snackbar.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Volley Error fetching Details", Toast.LENGTH_SHORT).show();
Snackbar.make(getWindow().getDecorView().getRootView(),error.toString(),Snackbar.LENGTH_LONG).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String > params = new HashMap<>();
params.put("id", getId);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
public static String numberFormatter(double d) {
DecimalFormat decimalFormat = new DecimalFormat("#,###.##");
return decimalFormat.format(d);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.user_toolbar_menu_items, menu);
MenuItem cartItem = menu.findItem(R.id.cart_action);
cartItem.setIcon(CartCounterConverter.convertLayoutToImage(MainActivity.this,cart_count,R.drawable.view_cart_icon));
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Check if Action Bar Drawer Toggle has been selected
if(actionBarDrawerToggle.onOptionsItemSelected(item)){
return true;
}
switch (item.getItemId()) {
case R.id.cart_action:
//startActivity(new Intent(MainActivity.this,CartActivity.class));
Fragment fragment = new CartFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,fragment).commit();
getSupportActionBar().hide();
break;
case R.id.logout_action:
userSessionManager.logOutUser();
finish();
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
/*switch (item.getItemId()) {
case R.id.action_category_one:
Toast.makeText(this, "Under Development", Toast.LENGTH_SHORT).show();
break;
case R.id.action_profile:
fragment = new UserProfileFragment();
break;
}*/
int id = item.getItemId();
if (id == R.id.action_view_products) {
fragment = new ViewProductsFragment();
}
// else if (id == R.id.action_receipts) {
// }
else if (id == R.id.action_profile) {
//startActivity(new Intent(MainActivity.this,UserProfileActivity.class));
fragment = new UserProfileFragment();
}
if (fragment !=null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
//R.id." " will be found in content_main.xml from the Frame Layout
ft.replace(R.id.frame_layout,fragment);
ft.commit();
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onClick(View v) {
}
// When back button is pressed method
#Override
public void onBackPressed() {
//Check if navigation drawer is opened or closed
if (drawerLayout.isDrawerOpen(GravityCompat.START)){
drawerLayout.closeDrawer(GravityCompat.START);
}else {
if (backPressed + TIME_INTERVAL > System.currentTimeMillis()) {
super.onBackPressed();
return;
} else {
Toast.makeText(getBaseContext(), "Press back button again to exit", Toast.LENGTH_SHORT).show();
}
backPressed = System.currentTimeMillis();
}
}
#Override
protected void onResume() {
super.onResume();
fetchUserDetails();
}
// Remember to implement AddRemoveCallback Interface
#Override
public void onAddProduct() {
cart_count++;
invalidateOptionsMenu();
}
// Remember to implement AddRemoveCallback Interface
#Override
public void onRemoveProduct() {
cart_count--;
invalidateOptionsMenu();
}
}
My child fragment
package manu.apps.cartv6.Tests;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import manu.apps.cartv6.Activities.MainActivity;
import manu.apps.cartv6.Fragments.ViewProductsFragment;
import manu.apps.cartv6.R;
/**
* A simple {#link Fragment} subclass.
*/
public class CartFragment extends Fragment {
Toolbar fragmentCartToolbar;
public CartFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//((MainActivity) getActivity()).getSupportActionBar().hide();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_cart, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fragmentCartToolbar = view.findViewById(R.id.fragment_cart_tool_bar);
((MainActivity) getActivity()).setSupportActionBar(fragmentCartToolbar);
((MainActivity) getActivity()).getSupportActionBar().setTitle("Blank Fragment");
((MainActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
((MainActivity) getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);
final Toolbar bar = (Toolbar) getActivity().findViewById(R.id.main_tool_bar);
fragmentCartToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity) getActivity()).setSupportActionBar(bar);
//((MainActivity) getActivity()).getSupportActionBar().show();
Fragment fragment = new ViewProductsFragment();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,fragment).commit();
}
});
}
}
The problem is that the moment i add setNavigationOnClickListener the Main Activity toolbar doesn't show again when i remove it, it shows perfectly
#Override
public void onResume() {
super.onResume();
((MainActivity)getActivity()).getSupportActionBar().hide();
((MainActivity) getActivity()).setSupportActionBar(fragmentCartToolbar);
((MainActivity) getActivity()).getSupportActionBar().setTitle("Blank Fragment");
((MainActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//((MainActivity) getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);
fragmentCartToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment = new ViewProductsFragment();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,fragment).commit();
}
});
}
Please try to add below in your parent fragment's onResume(), I guess it's ViewProductsFragment from the provided code.
This will allow you to hide the action bar from the fragment itself rather than the activity.
#Override
public void onResume() {
super.onResume();
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
}
i am looking for a second opinion. I have a class that extends the Fragment class and contains a ViewPager and MaterialTabs. I need to find a workaround on a problem and I would like to remove tabs from ViewPager and add just one (fragment too) and so on.
For instance, i start with two tabs and on an action i want to remove those tabs and add a new one and on a different action to re-add those two tabs.
Is this plain stupid or it has a shot? Thank you.
Below is my class that i will work on:
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.app.ActivityCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import it.neokree.materialtabs.MaterialTab;
import it.neokree.materialtabs.MaterialTabHost;
import it.neokree.materialtabs.MaterialTabListener;
/**
*
*/
public class PuzzlesTabActivity extends Fragment implements MaterialTabListener {
public static int NUM_TABS = 2;
public static boolean currentlyRunning;
private MaterialTabHost tabHost;
private ViewPager pager;
private PuzzlesTabActivity.ViewPagerAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(layout.puzzle_tab_layout, container, false);
if (Utils.isNetworkAvailable(this.getActivity())) {
this.tabHost = (MaterialTabHost) rootView.findViewById(id.myTabHost);
this.pager = (ViewPager) rootView.findViewById(id.myPager);
try {
this.pager.setPadding(0, 5, 0, 0);
// init view pager
this.adapter = new PuzzlesTabActivity.ViewPagerAdapter(this.getActivity().getFragmentManager());
this.pager.setAdapter(this.adapter);
this.pager.setOnPageChangeListener(new SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// when user do a swipe the selected tab change
PuzzlesTabActivity.this.tabHost.setSelectedNavigationItem(position);
}
});
this.pager.setCurrentItem(0);
// add tabs
for (int i = 0; i < this.adapter.getCount(); i++) {
this.tabHost.addTab(this.tabHost.newTab().setText(this.adapter.getPageTitle(i)).setTabListener(this));
}
} catch (Exception e) {
Log.e(Constants.TAG, e.getMessage());
}
} else {
ActivityCompat.startActivity(this.getActivity(), new Intent(this.getActivity(), MainActivity.class), null);
}
return rootView;
}
#Override
public void onTabSelected(MaterialTab tab) {
this.pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(MaterialTab tab) {
}
#Override
public void onTabUnselected(MaterialTab tab) {
}
private class ViewPagerAdapter extends FragmentStatePagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
public Fragment getItem(int num) {
switch (num) {
case 0:
PuzzlesFragment aFragment = new PuzzlesFragment();
return aFragment;
case 1:
FavFragment nFragment = new FavFragment();
return nFragment;
default:
return new PuzzlesFragment();
}
}
#Override
public int getCount() {
return PuzzlesTabActivity.NUM_TABS;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return PuzzlesTabActivity.this.getResources().getString(string.new_puzzles);
case 1:
return PuzzlesTabActivity.this.getResources().getString(string.fav_puzzles);
default:
return PuzzlesTabActivity.this.getResources().getString(string.new_puzzles);
}
}
}
public void onPause() {
super.onPause();
SharedPreferences prefs = this.getActivity().getSharedPreferences(Utils.PREFS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("lastActivity", this.getClass().getName());
editor.commit();
}
#Override
public void onStart() {
super.onStart();
PuzzlesTabActivity.currentlyRunning = true;
}
#Override
public void onStop() {
PuzzlesTabActivity.currentlyRunning = false;
super.onStop();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
}
Yes, this is fine. ViewPager already does something like this in a normal use case. It works by creating the fragment to the left, the current fragment, and the fragment to the right, as you swipe (so only three exist at a time).
As for adding and removing the tabs, that is fine to do as well. Just make sure to handle swapping for the new tab's fragment in the ViewPager.
My application has 2 tab and works like a charm.
But today I tried to expand my tabbar and I added a third tab.
When I tap the third tab it destroys the first tab fragment and it calls onDestroyView method in first tab fragment.
When I tap the second tab it doesn't call the onDestroyView.
Why does the third tab destroy the first tab?
I don't want it to destroy my first view.
How can I solve this problem?
My custom FragmentAdapter class
package com.esmobileinc.vetmapp;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.ViewGroup;
public class SectionsPagerAdapter extends FragmentPagerAdapter {
Context mContext;
private Fragment mCurrentFragment;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
switch (position){
case 0:
return new HaritaFragment();
case 1:
return new ListeFragment();
case 2:
return new ListeFragment();
}
return null;
}
public Fragment getCurrentFragment() {
return mCurrentFragment;
}
//...
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (getCurrentFragment() != object) {
mCurrentFragment = ((Fragment) object);
}
super.setPrimaryItem(container, position, object);
}
#Override
public int getCount() {
return 3;
}
/*#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return mContext.getString(R.string.title_section1).toUpperCase(l);
case 1:
return mContext.getString(R.string.title_section2).toUpperCase(l);
}
return null;
}*/
public int getIcon(int position){
switch (position){
case 0:
return R.drawable.harita_tab_icon;
case 1:
return R.drawable.liste_tab_icon;
case 2:
return R.drawable.harita_tab_icon;
}
return R.drawable.harita_tab_icon;
}
}
This is my Main Activity.
package com.esmobileinc.vetmapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.instabug.library.Instabug;
import com.instabug.wrapper.support.activity.InstabugActionBarActivity;
public class MainActivity extends InstabugActionBarActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
FragmentManager manager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getSupportFragmentManager();
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.nav_logo);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setTitle("");
mSectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
//.setText(mSectionsPagerAdapter.getPageTitle(i))
.setIcon(mSectionsPagerAdapter.getIcon(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_mail) {
Instabug.getInstance().setCommentFieldHint(getString(R.string.veterinerbildir_comment));
Instabug.getInstance().enableEmailField(true,true);
Instabug.getInstance().setCommentRequired(true);
Instabug.getInstance().invokeFeedbackProcess(Instabug.INSTABUG_FEEDBACK_FEEDBACK);
return true;
}
else if (id == R.id.action_about){
Intent intent = new Intent(this,InfoActivity.class);
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
}
There is my first tab fragment.
package com.esmobileinc.vetmapp;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.instabug.library.Instabug;
import com.parse.FindCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HaritaFragment extends Fragment implements LocationListener {
private static GoogleMap mGoogleMap;
public static HashMap<Marker, Markers> mMarkersHashMap = new HashMap<Marker, Markers>();
private ArrayList<Markers> mMyMarkersArray = new ArrayList<Markers>();
private Map<Marker, Markers> allMarkersMap = new HashMap<Marker, Markers>();
private Location userLocation;
private LatLng latLng;
private Double lat;
private Double lng;
private static View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
return inflater.inflate(R.layout.fragment_harita, container, false);
}
public void onViewCreated(View view, Bundle savedInstanceState){
setupMap();
//showGPSDisableAlert();
}
#Override
public void onResume() {
super.onResume();
googleAnalyticsSendScreen();
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity().getBaseContext());
if (status != ConnectionResult.SUCCESS) { // Google Play Services are not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, getActivity(), requestCode);
dialog.show();
} else { // Google Play Services are available
getAllDataFromParse();
}
}
public void onDestroyView()
{
super.onDestroyView();
Fragment fragment = (getChildFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
private void showGPSDisableAlert(){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.location_error_title);
builder.setMessage(R.string.location_error_message);
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
private void getLocations(){
mGoogleMap.getUiSettings().setMapToolbarEnabled(false);
userLocation = mGoogleMap.getMyLocation();
if (userLocation != null) {
onLocationChanged(userLocation);
latLng = new LatLng(lat,lng);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
}
else {
showGPSDisableAlert();
latLng = new LatLng(39.19820535, 34.89257812);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 5));
}
}
private void getAllDataFromParse(){
if (mMyMarkersArray.isEmpty()){
if (isInternetAvailable()){
unPinAllParseData();
getOnlineDataFromParse();
}
else{
getOfflineDataFromParse();
}
}
}
private void unPinAllParseData(){
ParseQuery<ParseObject> query = ParseQuery.getQuery("Veterinerler");
query.setLimit(1000);
ParseObject.unpinAllInBackground();
}
private void getOnlineDataFromParse(){
ParseQuery<ParseObject> query = ParseQuery.getQuery("Veterinerler");
query.setLimit(1000);
query.whereEqualTo("isMember", "YES");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> vetList, ParseException e) {
if (e == null) {
for(int i=0; i< vetList.size(); i++){
mMyMarkersArray.add(new Markers(
vetList.get(i).getString("adi"),
vetList.get(i).getString("adres"),
vetList.get(i).getString("telefon"),
vetList.get(i).getString("web"),
vetList.get(i).getString("face"),
vetList.get(i).getString("geceAcik"),
vetList.get(i).getDouble("latitude"),
vetList.get(i).getDouble("longitude")));
}
getLocations();
plotMarkers(mMyMarkersArray);
ParseObject.pinAllInBackground(vetList);
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.parse_online_query_error_title));
builder.setMessage(getString(R.string.parse_online_query_error_message));
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
}
private void getOfflineDataFromParse(){
ParseQuery<ParseObject> query = ParseQuery.getQuery("Veterinerler");
query.setLimit(1000);
query.whereEqualTo("isMember", "YES");
query.fromLocalDatastore();
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> vetList, ParseException e) {
if (e == null) {
getLocations();
for(int i=0; i< vetList.size(); i++){
mMyMarkersArray.add(new Markers(
vetList.get(i).getString("adi"),
vetList.get(i).getString("adres"),
vetList.get(i).getString("telefon"),
vetList.get(i).getString("web"),
vetList.get(i).getString("face"),
vetList.get(i).getString("geceAcik"),
vetList.get(i).getDouble("latitude"),
vetList.get(i).getDouble("longitude")));
}
plotMarkers(mMyMarkersArray);
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.parse_offline_query_error_title));
builder.setMessage(getString(R.string.parse_offline_query_error_title));
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
}
private void googleAnalyticsSendScreen() {
Tracker t = ((GlobalState) getActivity().getApplication()).getTracker(
GlobalState.TrackerName.APP_TRACKER);
t.setScreenName("Harita Ekranı");
t.send(new HitBuilders.AppViewBuilder().build());
}
private void plotMarkers(ArrayList<Markers> markers){
if(markers.size() > 0)
{
for (Markers myMarker : markers)
{
// Create user marker with custom icon and other options
MarkerOptions markerOption = new MarkerOptions().position(new LatLng(myMarker.getmLatitude(), myMarker.getmLongtitude()));
if (myMarker.getmGeceAcik().equalsIgnoreCase("YES")){
markerOption.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
}
else if (myMarker.getmGeceAcik().equalsIgnoreCase("Cep")){
markerOption.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
}
else if (myMarker.getmGeceAcik().equalsIgnoreCase("Barinak")){
markerOption.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_VIOLET));
}
final Marker currentMarker = mGoogleMap.addMarker(markerOption);
mMarkersHashMap.put(currentMarker, myMarker);
allMarkersMap.put(currentMarker, myMarker);
mGoogleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
Markers selectedMarkerInfo = allMarkersMap.get(marker);
View v = View.inflate(getActivity().getBaseContext(),R.layout.info_window,null);
TextView tvAdi = (TextView) v.findViewById(R.id.tv_adi);
TextView tvAdres = (TextView) v.findViewById(R.id.tv_adres);
ImageView img = (ImageView) v.findViewById(R.id.img_icon);
tvAdi.setText(selectedMarkerInfo.getmAdi());
tvAdres.setText(selectedMarkerInfo.getmAdres());
tvAdi.setSelected(true);
if (selectedMarkerInfo.mGeceAcik.equalsIgnoreCase("Barinak")){
img.setImageResource(R.drawable.belediye);
}
else if (selectedMarkerInfo.mGeceAcik.equalsIgnoreCase("YES")){
img.setImageResource(R.drawable.gece_acik);
}
else if (selectedMarkerInfo.mGeceAcik.equalsIgnoreCase("Cep")){
img.setImageResource(R.drawable.acil);
}
else{
img.setImageResource(R.drawable.normal);
}
return v;
}
#Override
public View getInfoContents(Marker marker) {
return null;
}
});
}
}
}
private void setupMap(){
mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
mGoogleMap.setMyLocationEnabled(true);
latLng = new LatLng(39.19820535, 34.89257812);
//latLng = new LatLng(41.048846, 29.027924);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 5));
//OnClick Info Window Listener...
mGoogleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
Markers selectedMarkerInfo = allMarkersMap.get(marker);
//GOOGLE ANALYTICS EVENT SENDER
String secilenVeteriner = selectedMarkerInfo.getmAdi();
Tracker t = ((GlobalState) getActivity().getApplication()).getTracker(
GlobalState.TrackerName.APP_TRACKER);
t.send(new HitBuilders.EventBuilder()
.setCategory(secilenVeteriner)
.setAction("Harita ekranın'dan seçilme sayınız")
.setLabel("Harita")
.build());
Intent intent = new Intent(getActivity(), DetailActivity.class);
intent.putExtra("adi", selectedMarkerInfo.getmAdi());
intent.putExtra("adres", selectedMarkerInfo.getmAdres());
intent.putExtra("web", selectedMarkerInfo.getmWeb());
intent.putExtra("face", selectedMarkerInfo.getmFace());
intent.putExtra("tel", selectedMarkerInfo.getmTelefon());
intent.putExtra("lat", selectedMarkerInfo.getmLatitude().toString());
intent.putExtra("lng", selectedMarkerInfo.getmLongtitude().toString());
intent.putExtra("gece", selectedMarkerInfo.getmGeceAcik());
startActivity(intent);
}
});
}
private boolean isInternetAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
#Override
public void onLocationChanged(Location location) {
lat = (location.getLatitude());
lng = (location.getLongitude());
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_mail) {
Instabug.getInstance().setCommentFieldHint(getString(R.string.veterinerbildir_comment));
Instabug.getInstance().enableEmailField(true,true);
Instabug.getInstance().setCommentRequired(true);
Instabug.getInstance().invokeFeedbackProcess(Instabug.INSTABUG_FEEDBACK_FEEDBACK);
return true;
}
if (id == R.id.map_standart){
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
if (id == R.id.map_hibrit){
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
if (id == R.id.map_uydu){
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
return super.onOptionsItemSelected(item);
}
}
There is my second tab fragment class, third tab fragment is same.
package com.esmobileinc.vetmapp;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.parse.FindCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
public class ListeFragment extends ListFragment {
private View mView;
private ArrayList<String> illerArray = new ArrayList<String>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_liste, container, false);
return mView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getAllDataFromParse();
}
#Override
public void onResume() {
super.onResume();
googleAnalyticsSendScreen();
}
private void getAllDataFromParse(){
if (illerArray.isEmpty()){
if (isInternetAvailable()){
getOnlineDataFromParse();
}
else{
getOfflineDataFromParse();
}
}
}
private boolean isInternetAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) this.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private void getOnlineDataFromParse(){
ParseQuery<ParseObject> query = ParseQuery.getQuery("Veterinerler");
query.setLimit(1000);
query.whereEqualTo("isMember", "YES");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> vetList, ParseException e) {
if (e == null) {
for(int i=0; i< vetList.size(); i++){
illerArray.add(vetList.get(i).getString("il"));
}
illerArray = new ArrayList<String>(new LinkedHashSet<String>(illerArray));
Collections.sort(illerArray, new orderComparator());
showListView();
registerCallBack();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.parse_online_query_error_title));
builder.setMessage(getString(R.string.parse_online_query_error_message));
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
}
private void getOfflineDataFromParse(){
ParseQuery<ParseObject> query = ParseQuery.getQuery("Veterinerler");
query.fromLocalDatastore();
query.setLimit(1000);
query.whereEqualTo("isMember", "YES");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> vetList, ParseException e) {
if (e == null) {
for(int i=0; i< vetList.size(); i++){
illerArray.add(vetList.get(i).getString("il"));
}
illerArray = new ArrayList<String>(new LinkedHashSet<String>(illerArray));
Collections.sort(illerArray, new orderComparator());
showListView();
registerCallBack();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.parse_online_query_error_title));
builder.setMessage(getString(R.string.parse_online_query_error_message));
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
}
private void showListView() {
ArrayAdapter<String> adapter = new myListAdapter();
ListView listView = (ListView) getActivity().findViewById(android.R.id.list);
listView.setAdapter(adapter);
}
private void registerCallBack() {
ListView listView = (ListView) getActivity().findViewById(android.R.id.list);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String secilenIl = illerArray.get(position);
//GOOGLE EVENT SEND
Tracker t = ((GlobalState) getActivity().getApplication()).getTracker(
GlobalState.TrackerName.APP_TRACKER);
t.send(new HitBuilders.EventBuilder()
.setCategory("İller Listesi")
.setAction("Seçilen il")
.setLabel(secilenIl)
.build());
//INTENTING DETAIL VIEW CONTROLLER !!!!
Intent intent = new Intent(getActivity(),IlcelerActivity.class);
intent.putExtra("secilenIl",secilenIl);
startActivity(intent);
}
});
}
private class myListAdapter extends ArrayAdapter<String>{
public myListAdapter(){
super(getActivity(), R.layout.ilce_view, illerArray);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if (itemView == null){
itemView = getActivity().getLayoutInflater().inflate(R.layout.ilce_view, parent, false);
}
String il = illerArray.get(position);
TextView ilce = (TextView) itemView.findViewById(android.R.id.text1);
ilce.setText(il);
return itemView;
}
}
public class orderComparator implements Comparator<String> {
#Override
public int compare(String il1, String il2) {
Collator collator = Collator.getInstance(Locale.getDefault());
//veya Collator trCollator = Collator.getInstance(new Locale("tr", "TR"));
return collator.compare(il1, il2);
}
}
}
With these code my application calls the HaritaFrament(first tab) onDestroyView method when I tap the third tab.
But it doesn't call the onDestroyView when I tap the second tap.
I don't want to destroy my HaritaFragment.
Please help me solve this problem.
What you're looking for is ViewPager#setOffscreenPageLimit.
This is by default 1, which means the ViewPager will only retain 1 fragment before and 1 fragment after the current position. If you have 3 fragments and you don't want any of them to be destroyed by the ViewPager, you can just set it to 2.
mViewPager.setOffscreenPageLimit(2);
I encounter a weird problem while using the support library.
I want to make a dynamic navigation tabs with fragments switching on the 2.3.3 platform, just like what API Demo did .
everything goes fine on 2.3.3 platform, but when I took a look at the same activity on the 4.3 platform, I found that something quite weird.
the SupportFragmentManagement cannot detach the fragment, seems like the tab selecting callback didn't execute correctly;
following pictures show how my demo go
and here's my code:
package net.zengweizhi.android.gettingstarted.lesson05.test;
import net.zengweizhi.android.gettingstarted.R;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
// using the api from support library
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener;
import android.support.v7.app.ActionBarActivity;
public class NavigationTabsWithFragmentsV9 extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_navigation_tabs, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.actionButton_addTab:
addTab();
break;
case R.id.actionButton_removeTab:
removeTab();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
private int mTabSeq = 0;
private void addTab(){
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mTabSeq++;
Tab tab = getSupportActionBar().newTab();
tab.setText("TAB " + mTabSeq);
tab.setTabListener(new MyTabListener(this));
getSupportActionBar().addTab(tab);
}
private void removeTab(){
Tab tab = getSupportActionBar().getSelectedTab();
getSupportActionBar().removeTab(tab);
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tab.getText().toString());
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
if( getSupportActionBar().getTabCount() == 0 ){
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
}
}
private static final class MyTabListener implements TabListener {
private NavigationTabsWithFragmentsV9 mActivity;
public MyTabListener(NavigationTabsWithFragmentsV9 activity /*,Fragment fragment*/){
mActivity = activity;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// Do nothing
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object obj = tab.getTag();
if( null == obj ){
Bundle args = new Bundle();
args.putString(SimpleFragment.EXTRA_OUTPUT_MESSAGE, tab.getText().toString());
Fragment fragment = Fragment.instantiate(mActivity, SimpleFragment.class.getName(), args);
ft.add(android.R.id.content, fragment, tab.getText().toString());
tab.setTag(obj = fragment);
}
ft.attach((Fragment)obj);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if( null != mActivity.getSupportFragmentManager().findFragmentByTag(tab.getText().toString()) ){
ft.detach((Fragment)tab.getTag());
}
}
}
public static final class SimpleFragment extends Fragment {
public static final String EXTRA_OUTPUT_MESSAGE = "output_message";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_simple, container, false);
String outputMesasge = null;
if( null != getArguments() ){
outputMesasge = getArguments().getString(EXTRA_OUTPUT_MESSAGE);
}
if( null == outputMesasge || 0 == outputMesasge.trim().length() ){
outputMesasge = getString(R.string.demo_text);
}
TextView textView = (TextView) fragmentView.findViewById(R.id.textView_simpleFragmentOutput);
textView.setText(outputMesasge);
return fragmentView;
}
}
}
But when I change all thesupport api to the regular api(default platform api), everything goes fine on 4.3 platform(but this one doesn't compatible with 2.3.3 platform);
here's the code(nothing difference except the ActionBar and Fragment API)
package net.zengweizhi.android.gettingstarted.lesson05.test;
import net.zengweizhi.android.gettingstarted.R;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
// use the api from default platform(only in v11 and later)
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.Fragment;
import android.app.FragmentTransaction;
#SuppressLint("NewApi")
public class NavigationTabsWithFragmentsV14 extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_navigation_tabs, menu);
return super.onCreateOptionsMenu(menu);
}
private int mTabSeq = 0;
private void addTab(){
getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mTabSeq++;
Tab tab = getActionBar().newTab();
tab.setText("TAB " + mTabSeq);
tab.setTabListener(new MyTabListener(this));
getActionBar().addTab(tab);
}
private void removeTab(){
Tab tab = getActionBar().getSelectedTab();
getActionBar().removeTab(tab);
Fragment fragment = getFragmentManager().findFragmentByTag(tab.getText().toString());
getFragmentManager().beginTransaction().remove(fragment).commit();
if( getActionBar().getTabCount() == 0 ){
getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.actionButton_addTab:
addTab();
break;
case R.id.actionButton_removeTab:
removeTab();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
private static final class MyTabListener implements TabListener {
private NavigationTabsWithFragmentsV14 mActivity;
public MyTabListener(NavigationTabsWithFragmentsV14 activity /*,Fragment fragment*/){
mActivity = activity;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// Do nothing
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object obj = tab.getTag();
if( null == obj ){ // initialize fragment to tab
Bundle args = new Bundle();
args.putString(SimpleFragment.EXTRA_OUTPUT_MESSAGE, tab.getText().toString());
Fragment fragment = Fragment.instantiate(mActivity, SimpleFragment.class.getName(), args);
ft.add(android.R.id.content, fragment, tab.getText().toString());
tab.setTag(obj = fragment);
}
ft.attach((Fragment)obj);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if( null != mActivity.getFragmentManager().findFragmentByTag(tab.getText().toString()) ){
ft.detach((Fragment)tab.getTag());
}
}
}
public static final class SimpleFragment extends Fragment {
public static final String EXTRA_OUTPUT_MESSAGE = "output_message";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_simple, container, false);
String outputMesasge = null;
if( null != getArguments() ){
outputMesasge = getArguments().getString(EXTRA_OUTPUT_MESSAGE);
}
if( null == outputMesasge || 0 == outputMesasge.trim().length() ){
outputMesasge = getString(R.string.demo_text);
}
TextView textView = (TextView) fragmentView.findViewById(R.id.textView_simpleFragmentOutput);
textView.setText(outputMesasge);
return fragmentView;
}
}
}
I can make a compatible version by using (values-v14/classes.xml) and following code
try {
Class<?> clazz = Class.forName(getString(R.string.class_navigationTabsAndFragmentsActivity));
startActivity(clazz);
} catch (ClassNotFoundException ex) {
showTextByToast(ex.getMessage());
}
but I still want to know what's going on in the support library version, can anyone help me to figure out this problem?
Google releases Nexus 5 and a new support library (v19), this version fixed this bug
I have two fragments, lets call them Fragment A and Fragment B, which are a part of a NavigationDrawer (this is the activity they a bound to). In Fragment A I have a button. When this button is pressed, I would like another item added to the ListView in Fragment B.
What is the best way to do this? Use Intents, SavedPreferences, making something public(?) or something else?
EDIT 5: 20/7/13 This is with srains latest code
This is the NavigationDrawer that I use to start the fragments:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Navigation_Drawer extends FragmentActivity {
public DrawerLayout mDrawerLayout; // Creates a DrawerLayout called_.
public ListView mDrawerList;
public ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mNoterActivities; // This creates a string array called _.
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
// Just setting up the navigation drawer
} // End of onCreate
// Removed the menu
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
selectItem(position);
}
}
private void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
if (position == 0) {
Fragment qnfragment = new QuickNoteFragment();
((FragmentBase) qnfragment).setContext(this);
Bundle args = new Bundle(); // Creates a bundle called args
args.putInt(QuickNoteFragment.ARG_nOTERACTIVITY_NUMBER, position);
qnfragment.setArguments(args);
fragmentManager.beginTransaction()
.replace(R.id.content_frame, qnfragment).commit();
} else if (position == 3) {
Fragment pendViewPager = new PendViewPager(); // This is a ViewPager that includes HistoryFragment
((FragmentBase) pendViewPager).setContext(this);
Bundle args = new Bundle();
pendViewPager.setArguments(args);
fragmentManager.beginTransaction()
.replace(R.id.content_frame, pendViewPager).commit();
}
// Update title etc
}
#Override
protected void onPostCreate(Bundle savedInstanceState) { // Used for the NavDrawer toggle
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) { // Used for the NavDrawer toggle
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggles
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
This is QuickNoteFragment:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class QuickNoteFragment extends FragmentBase implements OnClickListener {
public static final String ARG_nOTERACTIVITY_NUMBER = "noter_activity";
Button b_create;
// removed other defining stuff
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.quicknote, container, false);
int i = getArguments().getInt(ARG_nOTERACTIVITY_NUMBER);
String noter_activity = getResources().getStringArray(
R.array.noter_array)[i];
FragmentManager fm = getFragmentManager();
setRetainInstance(true);
b_create = (Button) rootView.findViewById(R.id.qn_b_create);
// Removed other stuff
getActivity().setTitle(noter_activity);
return rootView;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.qn_b_create:
String data = "String data";
DataModel.getInstance().addItem(data);
break;
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
}
}
public interface OnItemAddedHandler { // Srains code
public void onItemAdded(Object data);
}
}
This is HistoryFragment (Remember it is part of a ViewPager):
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.RiThBo.noter.QuickNoteFragment.OnItemAddedHandler;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class HistoryFragment extends FragmentBase implements OnItemAddedHandler {
ListView lv;
List<Map<String, String>> planetsList = new ArrayList<Map<String, String>>();
SimpleAdapter simpleAdpt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.history, container, false);
initList();
ListView lv = (ListView) view.findViewById(R.id.listView);
simpleAdpt = new SimpleAdapter(getActivity(), planetsList,
android.R.layout.simple_list_item_1, new String[] { "planet" },
new int[] { android.R.id.text1 });
lv.setAdapter(simpleAdpt);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parentAdapter, View view,
int position, long id) {
// We know the View is a TextView so we can cast it
TextView clickedView = (TextView) view;
Toast.makeText(
getActivity(),
"Item with id [" + id + "] - Position [" + position
+ "] - Planet [" + clickedView.getText() + "]",
Toast.LENGTH_SHORT).show();
}
});
registerForContextMenu(lv);
return view;
}
private void initList() {
// We populate the planets
planetsList.add(createPlanet("planet", "Mercury"));
planetsList.add(createPlanet("planet", "Venus"));
planetsList.add(createPlanet("planet", "Mars"));
planetsList.add(createPlanet("planet", "Jupiter"));
planetsList.add(createPlanet("planet", "Saturn"));
planetsList.add(createPlanet("planet", "Uranus"));
planetsList.add(createPlanet("planet", "Neptune"));
}
private HashMap<String, String> createPlanet(String key, String name) {
HashMap<String, String> planet = new HashMap<String, String>();
planet.put(key, name);
return planet;
}
// We want to create a context Menu when the user long click on an item
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;
// We know that each row in the adapter is a Map
HashMap map = (HashMap) simpleAdpt.getItem(aInfo.position);
menu.setHeaderTitle("Options for " + map.get("planet"));
menu.add(1, 1, 1, "Details");
menu.add(1, 2, 2, "Delete");
}
#Override
public void onItemAdded(Object data) {
// to add item
String string = String.valueOf(data);
Toast.makeText(getContext(), "Data: " + string, Toast.LENGTH_SHORT).show();
planetsList.add(createPlanet("planet", string));
}
#Override
public void onStart() {
super.onStart();
DataModel.getInstance().setOnItemAddedHandler(this);
}
}
This is FragmentBase:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
public class FragmentBase extends Fragment {
private FragmentActivity mActivity; // I changed it to FragmentActivity because Activity was not working, and my `NavDrawer` is a FragmentActivity.
public void setContext(FragmentActivity activity) {
mActivity = mActivity;
}
public FragmentActivity getContext() {
return mActivity;
}
}
This is DataModel:
import android.util.Log;
import com.xxx.xxx.QuickNoteFragment.OnItemAddedHandler;
public class DataModel {
private static DataModel instance;
private static OnItemAddedHandler mOnItemAddHandler;
public static DataModel getInstance() {
if (null == instance) {
instance = new DataModel();
}
return instance;
}
public void setOnItemAddedHandler(OnItemAddedHandler handler) {
mOnItemAddHandler = handler;
}
public void addItem(Object data) {
if (null != mOnItemAddHandler)
mOnItemAddHandler.onItemAdded(data);
else {
Log.i("is context null?", "yes!");
}
}
}
Thank you
I suggest you to use interface and MVC, that will make your code much more maintainable.
First you need an interface:
public interface OnItemAddedHandler {
public void onItemAdded(Object data);
}
Then, you will need a data model:
public class DataModel {
private static DataModel instance;
private static OnItemAddedHandler mOnItemAddHandler;
public static DataModel getInstance() {
if (null == instance) {
instance = new DataModel();
}
return instance;
}
public void setOnItemAddedHandler(OnItemAddedHandler handler) {
mOnItemAddHandler = handler;
}
public void addItem(Object data) {
if (null != mOnItemAddHandler)
mOnItemAddHandler.onItemAdded(data);
}
}
When you click the button, you can add data into the datamodel:
Object data = null;
DataModel.getInstance().addItem(data);
Then, the FragmentB implements the interface OnItemAddedHandler to add item
public class FragmentB implements OnItemAddedHandler {
#Override
public void onItemAdded(Object data) {
// to add item
}
}
also, When the FragmentB start, you should register itself to DataModel:
public class FragmentB implements OnItemAddedHandler {
#Override
public void onItemAdded(Object data) {
// to add item
}
#Override
protected void onStart() {
super.onStart();
DataModel.getInstance().setOnItemAddedHandler(this);
}
}
You also can add DataModel.getInstance().setOnItemAddedHandler(this); to the onCreate method of FragmentB
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DataModel.getInstance().setOnItemAddedHandler(this);
// do other things
}
update
you can send string simply:
String data = "some string";
DataModel.getInstance().addItem(data);
then on FragementB
public class FragmentB implements OnItemAddedHandler {
#Override
public void onItemAdded(Object data) {
// get what you send into method DataModel.getInstance().addItem(data);
String string = String.valueOf(data);
}
}
update
OK. You have add DataModel.getInstance().setOnItemAddedHandler(this) in onCreateView method, so there is no need to add it in onStart() method. You can remove the whole onStart method.
onStart will be called on the fragment start, we do not need to call it in onCreateView. And on onItemAdded will be call when call the method DataModel.getInstance().addItem(data), we do not need to call it in onCreateView neither.
so, you can remove the code below from onCreateView method:
DataModel.getInstance().setOnItemAddedHandler(this);
// remove the methods below
// onItemAdded(getView());
// onStart();
You have another fragment where there is a button, you can add the codes below in the clickhandler function:
String data = "some string";
DataModel.getInstance().addItem(data);
update3
I think the HistoryFragment has been detached after you when to QuickNoteFragment
You can add code to HistoryFragment to check:
#Override
public void onDetach() {
super.onDetach();
Log.i("test", String.format("onDetach! %s", getActivity() == null));
}
update4
I think HistoryFragment and QuickNoteFragment should has an parent class, named FragmentBase:
public class FragmentBase extends Fragment {
private Activity mActivity;
public void setContext(Activity activity) {
mActivity = mActivity;
}
public Activity getContext() {
return mActivity;
}
}
HistoryFragment and QuickNoteFragment extends FragmentBase. Then when you switch between them, you can call setContext to set a Activity, like:
private void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
if (position == 0) {
Fragment qnfragment = new QuickNoteFragment();
qnfragment.setContext(this);
// ...
} else if (position == 1) {
Fragment pagerFragment = new RemViewPager();
pagerFragment.setContext(this);
// ...
}
}
now, we can get a non-null activity in HistoryFragment by calling getContext, so we can change onItemAdded method to:
#Override
public void onItemAdded(Object data) {
// to add item
String string = String.valueOf(data);
Toast.makeText(getContext(), "Data: " + string, Toast.LENGTH_SHORT).show();
planetsList.add(createPlanet("planet", string));
}
I hope this would work.
Some good design principals:
An activity can know everything pubic about any Fragment it contains.
A Fragment should not know anything about the specific Activities that contain it.
A Fragment should NEVER know about other fragments that may or may not be contained in the Parent activity.
A suggested approach (informal design pattern) based on these principles.
Each fragment should declare an interface to be implemented by its parent activity:
public class MyFragment extends Fragment
{
public interface Parent
{
void onMyFragmentSomeAction();
}
private Parent mParent;
public onAttach(Activity activity)
{
mParent = (Parent) activity;
}
// This would actually be in a listener. Simplifying to save typing.
void onSomeButtonClick(View button)
{
mParent.onMyFragmentSomeAction();
}
}
And the activity should implement the appropriate interfaces for all of its contained fragments.
public class MyActivity extends Activity
implements MyFragment.Parent,
YourFragment.Parent,
HisFragment.Parent
{
[usual Activity code]
void onMyFragmentSomeAction()
{
if yourFragment is showing
{
yourFragment.reactToSomeAction();
}
if hisFragment is showing
{
hisFragment.observeThatSomeActionHappened();
}
[etc]
}
The broadcast approach is good, too, but it's pretty heavyweight and it requires the target Fragment to know what broadcasts will be sent by the source Fragment.
Use Broadcast. Send a boradcast from A, and B will receive and handle it.
Add a public method to B, for example, public void addListItem(), which will add data to listview in B. Fragment A try to find the instance of Fragment B using FragmentMananger.findFragmentByTag() and invoke this method.