In my App, I have two Fragments: FragmentA and FragmentB which are loaded from my MainActivity by the help of an SlidingMenu.
Thanks to Crashlytics I get notified when and where my app crashes. In this case, from time to time the DatabaseHandler in FragmentA is null (for some users), even though it has been initzialized.
This is my Code:
MainActivity
public class MainActivity extends AppCompatActivity implements MyFragment.OnListFragmentInteractionListener, AsyncResponse {
private FragmentA fragmentA = new FragmentA();
private DatabaseHandler databaseHandler = new DatabaseHandler(this);
private NavigationView navigationView;
private DrawerLayout drawer;
private Toolbar toolbar;
// index to identify current nav menu item
private static int navItemIndex = 0;
public static String CURRENT_TAG = MyConstants.TAG_FRAGMENT_A;
// toolbar titles respected to selected nav menu item
private String[] activityTitles;
// flag to load home fragment when user presses back key
private Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentA.setDatabaseHandler(this.databaseHandler);
// Init UI
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mHandler = new Handler();
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
fabSendButton = (FloatingActionButton) findViewById(R.id.fab);
// Navigation view header
navHeader = navigationView.getHeaderView(0);
// load toolbar titles from string resources
activityTitles = getResources().getStringArray(R.array.sliding_menu_item_activity_titles);
// initializing navigation menu
setUpNavigationView();
if (savedInstanceState == null) {
navItemIndex = 0;
CURRENT_TAG = MyConstants.TAG_FRAGMENT_A;
loadHomeFragment();
}
}
/***
* Returns respected fragment that user
* selected from navigation menu
*/
private void loadHomeFragment() {
// set toolbar title
setToolbarTitle();
// if user select the current navigation menu again, don't do anything
// just close the navigation drawer
if (getSupportFragmentManager().findFragmentByTag(CURRENT_TAG) != null) {
drawer.closeDrawers();
return;
}
// Sometimes, when fragment has huge data, screen seems hanging
// when switching between navigation menus
// So using runnable, the fragment is loaded with cross fade effect
// This effect can be seen in GMail app
Runnable mPendingRunnable = new Runnable() {
#Override
public void run() {
// update the activity_main_header_with_item content by replacing fragments
Fragment fragment = getFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
fragmentTransaction.commit();
}
};
// If mPendingRunnable is not null, then add to the message queue
if (mPendingRunnable != null) {
mHandler.post(mPendingRunnable);
}
//Closing drawer on item click
drawer.closeDrawers();
// refresh toolbar menu
invalidateOptionsMenu();
}
private Fragment getFragment() {
switch (navItemIndex) {
case 0:
return this.fragmentA;
case 1:
Fragment B fragmentB = new FragmentB();
fragmentB.setDatabaseHandler(this.databaseHandler);
return fragmentB;
default:
return this.fragmentA;
}
}
private void setToolbarTitle() {
getSupportActionBar().setTitle(activityTitles[navItemIndex]);
}
private void setUpNavigationView() {
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()) {
//Replacing the activity_main_header_with_item content with ContentFragment Which is our Inbox View;
case R.id.nav_A:
navItemIndex = 0;
CURRENT_TAG = MyConstants.TAG_FRAGMENT_A;
break;
case R.id.nav_B:
navItemIndex = 1;
CURRENT_TAG = MyConstants.TAG_FRAGMENT_B;
break;
default:
navItemIndex = 0;
}
loadHomeFragment();
return true;
}
});
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.openDrawer, R.string.closeDrawer) {
#Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawer.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessary or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main_header_with_item, menu);
return true;
}
}
FragmentA:
public class FragmentA extends MyFragment implements AsyncResponse {
private View view;
private RecyclerView recyclerView;
public FragmentA() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
List<Song> songsList = databaseHandler.getAllSongs();
view = inflater.inflate(R.layout.home_list, container, false);
// Set the adapter
Context context = view.getContext();
recyclerView = (RecyclerView) view.findViewById(R.id.listinclude);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), R.drawable.divider));
setVisibilities(songsList);
this.recyclerViewAdapter = new RecyclerViewAdapter(songsList, mListener, false, true);
recyclerView.setAdapter(this.recyclerViewAdapter);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
private void setVisibilities(List<Song> songsList) {
ViewFlipper viewFlipper = (ViewFlipper) view.findViewById(R.id.viewFlipper);
if (songsList.isEmpty() && viewFlipper.getDisplayedChild() == 0) {
viewFlipper.setDisplayedChild(1);
} else if (!songsList.isEmpty() && viewFlipper.getDisplayedChild() == 1) {
viewFlipper.setDisplayedChild(0);
}
}
#Override
public void processFinish(String output) {
// does something
}
}
MyFragment
public class MyFragment extends Fragment {
protected DatabaseHandler databaseHandler;
protected static final String ARG_COLUMN_COUNT = "column-count";
protected int mColumnCount = 1;
protected MyFragment.OnListFragmentInteractionListener mListener;
protected RecyclerViewAdapter recyclerViewAdapter;
public void setDatabaseHandler(DatabaseHandler databaseHandler) {
this.databaseHandler = databaseHandler;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Timber.i( "onCreate");
if (getArguments() != null) {
mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
}
}
#Override
public void onPause() {
Timber.i( "onPause");
super.onPause();
}
#Override
public void onAttach(Context context) {
Timber.i( "onAttach");
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (FragmentA.OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement OnListFragmentInteractionListener");
}
}
#Override
public void onDetach() {
Timber.i( "onDetach");
super.onDetach();
mListener = null;
}
public interface OnListFragmentInteractionListener {
// TODO: Update argument type and name
void onListFragmentInteraction(Song item);
}
}
DatabaseHandler:
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "appName";
// Songs table name
private static final String TABLE_SONGS = "songs";
#Override
public void onCreate(SQLiteDatabase db) {
// create Tables
}
// Upgrading database
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 1:
//upgrade logic from version 1 to 2
case 2:
//upgrade logic from version 2 to 3
case 3:
//upgrade logic from version 3 to 4
break;
default:
throw new IllegalStateException(
"onUpgrade() with unknown oldVersion " + oldVersion);
}
}
// Getting All Songs
public List<Song> getAllSongs() {
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_SONGS + " ORDER BY ID DESC";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
List<Song> songList = new ArrayList<>();
songList.addAll(getSongsFromCursor(cursor));
cursor.close();
// return title list
return songList;
}
}
Problem:
Fatal Exception: java.lang.RuntimeException
Unable to start activity ComponentInfo{com.myapp.myappname/com.myapp.myappname.ui.activity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.myapp.myappname.database.DatabaseHandler.getAllSongs()' on a null object reference
Details:
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myappname/com.myapp.myappname.ui.activity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.myapp.myappname.database.DatabaseHandler.getAllSongs()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2984)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.myapp.myappname.database.DatabaseHandler.getAllSongs()' on a null object reference
at com.myapp.myappname.ui.fragment.FragmentA.onCreateView(FragmentA.java:51)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2900)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:603)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at com.myapp.myappname.ui.activity.MainActivity.onStart(MainActivity.java:590)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1256)
at android.app.Activity.performStart(Activity.java:6972)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2937)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
try this one
databaseHandler=new DataBaseHandler(getActivity());
List<Song> songsList = databaseHandler.getAllSongs();
And add constructor in the DataBaseHandler class
public DataBaseHandler(Context context){
super(context, DB_NAME, null, 1);
}
try this on FragmentA.
databaseHandler=new DataBaseHandler(getContext());
you are taking context of mainActivity to initialize databaseHandler but using in fragment.
Found a solution based on Serg's answer:
FragmentA:
public class FragmentA extends MyFragment implements AsyncResponse {
private View view;
private RecyclerView recyclerView;
public FragmentA() {
}
public static FragmentA newInstance(DatabaseHandler DatabaseHandler) {
FragmentA fragment = new FragmentA();
Bundle bundle = new Bundle();
bundle.putSerializable(MyConstants.FRAGMENT_ARGUMENT_KEY, databaseHandler);
fragment.setArguments(bundle);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
databaseHandler = (DatabaseHandler) getArguments().getSerializable(MyConstants.FRAGMENT_ARGUMENT_KEY);
List<Song> songsList = databaseHandler.getAllSongs();
view = inflater.inflate(R.layout.home_list, container, false);
// Set the adapter
Context context = view.getContext();
recyclerView = (RecyclerView) view.findViewById(R.id.listinclude);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), R.drawable.divider));
setVisibilities(songsList);
this.recyclerViewAdapter = new RecyclerViewAdapter(songsList, mListener, false, true);
recyclerView.setAdapter(this.recyclerViewAdapter);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
private void setVisibilities(List<Song> songsList) {
ViewFlipper viewFlipper = (ViewFlipper) view.findViewById(R.id.viewFlipper);
if (songsList.isEmpty() && viewFlipper.getDisplayedChild() == 0) {
viewFlipper.setDisplayedChild(1);
} else if (!songsList.isEmpty() && viewFlipper.getDisplayedChild() == 1) {
viewFlipper.setDisplayedChild(0);
}
}
#Override
public void processFinish(String output) {
// does something
}
}
MainActivity:
fragmentA = FragmentA.newInstance(this.databaseHandler);
Related
I have a SwitchTabActivty with 4 items. In my case, I use the second item to get some data from the web through a recyclerview. The problem is that when I press the fourth item (it contains a button that's starting an activity) and I go back to my second tab , my recycler view is multiplied with the same data again.
Switchtabactivity :
public class SwitchTabActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private boolean pressToExit = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_switch_tab);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.weather_tab);
tabLayout.getTabAt(1).setIcon(R.drawable.events);
tabLayout.getTabAt(2).setIcon(R.drawable.details_tab);
tabLayout.getTabAt(3).setIcon(R.drawable.settings_tab);
setColorTab(tabLayout);
}
private void setColorTab(TabLayout tab) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
tab.setTabTextColors(getResources().getColorStateList(R.color.tab_colors, null));
} else {
tab.setTabTextColors(getResources().getColorStateList(R.color.tab_colors));
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onBackPressed() {
if (!pressToExit) {
Toast.makeText(this, "Press back again to exit.", Toast.LENGTH_SHORT).show();
pressToExit = true;
} else {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
#Override
public void onResume() {
super.onResume();
pressToExit = false;
}
#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_switch_tab, 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);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return WeatherFragment.newInstance(position);
case 1:
return EventFragment.newInstance(position);
case 2:
return OwnEventFragment.newInstance(position);
case 3:
return SettingsFragment.newInstance(position);
}
return null;
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Weather";
case 1:
return "Events";
case 2:
return "My Events";
case 3:
return "Settings";
}
return null;
}
}
EventFragment :
public class EventFragment extends Fragment implements EventResponse {
private String latitude, longitude;
private static final String ARG_SECTION_NUMBER = "section_number";
private RecyclerView eventList;
private EventAdapter adapter;
private TextView ifNullEvents;
private final ArrayList<EventData> eventsData = new ArrayList<>();
private UserDataBase db;
private List<String> latLonList;
private ProgressBar progressBar;
public EventFragment() {
}
public static EventFragment newInstance(int sectionNumber) {
EventFragment fragment = new EventFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.event_fragment, container, false);
initView(rootView);
db = new UserDataBase(getContext());
checkLocationChanged();
latLonList = db.getLatLon();
latitude = latLonList.get(0);
longitude = latLonList.get(1);
String EVENT_BRITE_URL_PARSE = "MY_URL";
String EVENT_BRITE_TOKEN = "MY_TOKEN";
new EventBriteApi(this, getContext()).execute(EVENT_BRITE_URL_PARSE + EVENT_BRITE_TOKEN);
setupRecyclerView();
setLocationMessage();
return rootView;
}
private void initView(View view) {
eventList = (RecyclerView) view.findViewById(R.id.event_recycler_view);
ifNullEvents = (TextView) view.findViewById(R.id.text_null_location);
progressBar = (ProgressBar) view.findViewById(R.id.progress_bar_event);
}
private void checkLocationChanged() {
if (WePrefs.isLocationChanged) {
eventsData.clear();
ifNullEvents.setText(getResources().getString(R.string.waiting_for_data));
ifNullEvents.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
WePrefs.setIsLocationChanged(false);
} else {
progressBar.setVisibility(View.GONE);
ifNullEvents.setVisibility(View.GONE);
}
if (WePrefs.isNullEventLocation) {
ifNullEvents.setText(getResources().getString(R.string.no_events_found));
ifNullEvents.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.INVISIBLE);
WePrefs.setIsNullEventLocation(false);
}
}
private void setupRecyclerView() {
eventList.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
eventList.setLayoutManager(linearLayoutManager);
adapter = new EventAdapter(getActivity(), eventsData);
adapter.setHasStableIds(true);
eventList.setAdapter(adapter);
}
#Override
public void onResume() {
checkLocationChanged();
setLocationMessage();
super.onResume();
}
private void setLocationMessage() {
if (eventsData.isEmpty()) {
ifNullEvents.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
} else {
ifNullEvents.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
}
progressBar.setVisibility(View.GONE);
}
#Override
public void getArray(ArrayList<EventData> data) {
eventsData.clear();
eventsData.addAll(new ArrayList<>(new LinkedHashSet<>(data)));
}
}
Adapter :
ublic class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventHolder> {
ArrayList<EventData> data;
Context context;
public EventAdapter(Context context, ArrayList<EventData> events) {
this.context = context;
data = events;
}
#Override
public EventHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RelativeLayout layout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.single_event_view, parent, false);
return new EventAdapter.EventHolder(layout);
}
#Override
public void onBindViewHolder(EventHolder holder, int position) {
holder.eventName.setText(data.get(position).getEventName());
if (data.get(position).getEventImageUrl() != null) {
Picasso.with(context).load(data.get(position).getEventImageUrl()).into(holder.eventPic);
} else {
holder.eventPic.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.no_image));
}
}
#Override
public int getItemCount() {
return data.size();
}
public class EventHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView eventName;
ImageView eventPic;
RelativeLayout layout;
public EventHolder(View itemView) {
super(itemView);
eventName = (TextView) itemView.findViewById(R.id.event_name);
eventPic = (ImageView) itemView.findViewById(R.id.event_image);
layout = (RelativeLayout) itemView.findViewById(R.id.event_layout);
layout.setOnClickListener(this);
}
#Override
public void onClick(View view) {
//context.startActivity(new Intent(context, WebViewActivity.class));
}
}
}
Those are some of my java classes that I use for this kind of thing.
Anyway, another problem is that, when I change the location ( to receive my events) I must go to another tab and after that to come back to see my events list ( I think it needs to recreate the view ) so , because of that I called onResume, but it does not help.
I have an activity that hosts a TabLayout with 3 tabs. I am trying to load a recyclerview based on dynamic data in Firebase and the recyclerview simply is not populating any views. I am not sure if it has to do with the FragmentSectionPager adapter or what, but I am having no luck loading the actual RecyclerView.
Activity:
public class HomeActivity extends AppCompatActivity implements TrendingFragment.FragmentListener,FollowingFragment.OnFragmentInteractionListener, LiveFragment.OnFragmentInteractionListener {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private Toolbar toolbar;
private boolean isOpen;
private ProgressBar mProgressBar;
private TextView mProgressText;
private TabLayout mTabLayout;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
toolbar = (Toolbar) findViewById(R.id.action_tool_bar);
toolbar.setTitleTextColor(ContextCompat.getColor(getApplicationContext(), R.color.white));
setSupportActionBar(toolbar);
setTitle(R.string.app_name);
Window window = getWindow();
final android.support.v7.app.ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mProgressBar = (ProgressBar) findViewById(R.id.pbHeaderProgress);
mProgressText = (TextView) findViewById(R.id.progress_text);
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
mViewPager = (ViewPager) findViewById(R.id.tab_swipe_container);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
toolbar, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
isOpen = false;
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
isOpen = true;
}
};
mDrawerLayout.addDrawerListener(mDrawerToggle);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
ArrayList<String> drawerTitleArray = new ArrayList<>();
drawerTitleArray.add(0, "TEST");
drawerTitleArray.add(1, "TEST 1");
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, drawerTitleArray));
mViewPager.setAdapter(new SectionPagerAdapter(getSupportFragmentManager()));
mTabLayout.setupWithViewPager(mViewPager);
Bundle extras = getIntent().getExtras();
int position = 0;
if(extras != null) {
position = extras.getInt("viewpager_position");
}
mViewPager.setCurrentItem(position);
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
return mDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onFragmentLoaded() {
mProgressBar.setVisibility(View.INVISIBLE);
mProgressText.setVisibility(View.INVISIBLE);
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public class SectionPagerAdapter extends FragmentStatePagerAdapter {
public SectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new TrendingFragment();
case 1:
return new FollowingFragment();
case 2:
return new LiveFragment();
default:
return new TrendingFragment();
}
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getResources().getString(R.string.trending_text);
case 1:
return getResources().getString(R.string.following_text);
case 2:
return getResources().getString(R.string.new_text);
default:
return getResources().getString(R.string.trending_text);
}
}
}
}
Fragment Containing RecyclerView:
public class LiveFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private RecyclerView mRecyclerview;
private DatabaseReference mBaseRef;
private DatabaseReference mPollsRef;
private LinearLayoutManager mLayoutManager;
private FirebaseRecyclerAdapter <Poll, PollHolder> mFireAdapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public LiveFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment LiveFragment.
*/
// TODO: Rename and change types and number of parameters
public static LiveFragment newInstance(String param1, String param2) {
LiveFragment fragment = new LiveFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBaseRef = FirebaseDatabase.getInstance().getReference();
mPollsRef = mBaseRef.child("Polls");
mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(Poll.class, R.layout.latest_item, PollHolder.class, mPollsRef) {
#Override
protected void populateViewHolder(PollHolder viewHolder, Poll model, int position) {
viewHolder.mPollQuestion.setText(model.getQuestion());
Picasso.with(getActivity().getApplicationContext())
.load(model.getImage_URL())
.fit()
.into(viewHolder.mPollImage);
Log.v("QUESTION", model.getQuestion());
Log.v("IMAGE", model.getImage_URL());
}
};
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View v = inflater.inflate(R.layout.fragment_new, container, false);
Log.v("TAG", "ON CREATE CALLED FROM NEW");
mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerview = (RecyclerView) v.findViewById(R.id.new_RecyclerView);
if (mRecyclerview != null){
mRecyclerview.setHasFixedSize(true);
}
mRecyclerview.setLayoutManager(mLayoutManager);
Log.v("TAG", "ON START CALLED FROM NEW");
mRecyclerview.setAdapter(mFireAdapter);
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
if (mFireAdapter != null){
mFireAdapter.cleanup();
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public static class PollHolder extends RecyclerView.ViewHolder {
TextView mPollQuestion;
ImageView mPollImage;
public PollHolder(View itemView) {
super(itemView);
mPollQuestion = (TextView) itemView.findViewById(R.id.latest_item_question);
mPollImage = (ImageView) itemView.findViewById(R.id.pollThumbNailImage);
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
How to create nested fragments and implement FragmentInteractionListener of child fragment in parent fragment NOT in MainActivity
I'm developing an android app that contains a fragment in main layout. Let's call this 'parentFragment'.
I also have another fragment within parentFragment. Let's call this fragment 'childFragment'.
This childFragment, have few methods that need to be implemented in the parentFragment, NOT in MainActivity.
This is where I am struggling to achieve. Firstly, is it possible for a Fragment to implement another Fragment's methods? If yes please advise on how to achieve this.
I have created interface for the child fragments to be implemented by ParentFragment.
Here is my MainActivity Class:
public class MainActivity extends AppCompatActivity {
private NavigationView navigationView;
private DrawerLayout drawer;
private View navHeader;
// and the rest of my variables and setup...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
// Navigation view header
navHeader = navigationView.getHeaderView(0);
// load nav menu header data
loadNavHeader();
// initializing navigation menu
setUpNavigationView();
// Load fragments here. In my case HomeFragment
loadHomeFragment();
}
/***
* Returns respected fragment that user
* selected from navigation menu
*/
private void loadHomeFragment() {
// selecting appropriate nav menu item
selectNavMenu();
// set toolbar title
setToolbarTitle();
// load the HomeFragment
Fragment fragment = getHomeFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
fragmentTransaction.commitAllowingStateLoss();
//Closing drawer on item click
drawer.closeDrawers();
}
private Fragment getHomeFragment() {
switch (navItemIndex) {
case 0:
// home
HomeFragment fragment = new HomeFragment();
return fragment;
case 1:
// add player
AddPlayerFragment addPlayerFragment = new AddPlayerFragment();
return addPlayerFragment;
case 2:
// settings
SettingsFragment settingsFragment = new SettingsFragment();
return settingsFragment;
case 3:
// help
HelpFragment helpFragment = new HelpFragment();
return helpFragment;
case 4:
// about us
AboutUsFragment aboutUsFragment = new AboutUsFragment();
return aboutUsFragment;
default:
return new HomeFragment();
}
}
// and the rest of my logic for navigations, action bar and so on.
// ....
}
HomeFragment is my parent fragment
public class HomeFragment extends Fragment implements PlayerProfileFragment.OnFragmentInteractionListener {
// players list
private List<Player> playersList;
public HomeFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
// load data here
playersList = PlayerDao.getInstance(this.getContext()).getAllPlayers();
ViewPager pager = (ViewPager) getView().findViewById(R.id.viewPager);
pager.setAdapter(new MyPagerAdapter(getFragmentManager()));
return rootView;
}
#Override
public void showMoreData(int playerId) {
AlertDialog.Builder builder1 = new AlertDialog.Builder(this.getContext());
builder1.setMessage(" showMoreData id = " + playerId);
builder1.setCancelable(true);
AlertDialog alert12 = builder1.create();
alert12.show();
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
if (fm.getFragments() != null) {
fm.getFragments().clear();
}
}
#Override
public Fragment getItem(int pos) {
Player player = playersList.get(pos);
return PlayerProfileFragment.newInstance(player.getId(), player.getName(), player.getAge(), player.getImagePath());
}
#Override
public int getCount() {
return playersList.size();
}
}
}
PlayerProfileFragment.java is my child fragment.
public class PlayerProfileFragment extends Fragment {
private OnFragmentInteractionListener mListener;
// the fragment initialization parameters
private static final String ARG_PLAYER_NAME = "playerNameParam";
private static final String ARG_PLAYER_AGE = "playerAgeParam";
private static final String ARG_PLAYER_ID = "playerIdParam";
private static final String ARG_PLAYER_IMAGE_PATH = "playerImagePathParam";
private String playerNameParam;
private String playerAgeParam;
private int playerIdParam;
private String playerImagePathParam;
public PlayerProfileFragment() {
// Required empty public constructor
}
public static PlayerProfileFragment newInstance(int param1, String param2, int param3, String param4) {
PlayerProfileFragment fragment = new PlayerProfileFragment();
Bundle args = new Bundle();
args.putInt(ARG_PLAYER_ID, param1);
args.putString(ARG_PLAYER_NAME, param2);
args.putString(ARG_PLAYER_AGE, String.valueOf(param3));
args.putString(ARG_PLAYER_IMAGE_PATH, param4);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
playerNameParam = args.getString(ARG_PLAYER_NAME);
playerAgeParam = args.getString(ARG_PLAYER_AGE);
playerIdParam = args.getInt(ARG_PLAYER_ID);
playerImagePathParam = args.getString(ARG_PLAYER_IMAGE_PATH);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_player_profile, container, false);
TextView tvName = (TextView) v.findViewById(R.id.fragment_player_profile_name);
tvName.setText(playerNameParam);
TextView tvAge = (TextView) v.findViewById(R.id.fragment_player_profile_age);
tvAge.setText(playerAgeParam + " " + getString(R.string.athlete_info_banner_age_years_label));
Button showMoreButton = (Button) v.findViewById(R.id.fragment_player_profile_show_more_button);
showMoreButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onButtonShowMorePressed(playerIdParam);
}
});
return v;
}
public void onButtonShowMorePressed(int playerId) {
if (mListener != null) {
mListener.showMoreData(playerId);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
*/
public interface OnFragmentInteractionListener {
void uploadPlayerData(int playerId);
void editPlayer(int playerId);
void showMoreData(int playerId);
}
}
Please notice that HomeFragment (Parent fragment) does not have onAttach(). Only PlayerProfileFragment has onattach() method. Do I need onAttach() for both fragments?
I finally got it working. Below is what I had to do:
HomeActivity class
public class MainActivity extends AppCompatActivity {
private NavigationView navigationView;
private DrawerLayout drawer;
private View navHeader;
// and the rest of my variables and setup...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
// Navigation view header
// load nav menu header data
loadNavHeader();
// initializing navigation menu
setUpNavigationView();
// Load fragments here. In my case HomeFragment
loadHomeFragment();
}
/***
* Load navigation menu header information
* like background image, profile image
* name, website, notifications action view (dot)
*/
private void loadNavHeader() {
// some logic here
}
/***
* Returns respected fragment that user
* selected from navigation menu
*/
private void loadHomeFragment() {
// selecting appropriate nav menu item
selectNavMenu();
// set toolbar title
setToolbarTitle();
Fragment fragment = getHomeFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
fragmentTransaction.commitAllowingStateLoss();
//Closing drawer on item click
drawer.closeDrawers();
}
private Fragment getHomeFragment() {
switch (navItemIndex) {
case 0:
// home
HomeFragment fragment = new HomeFragment();
return fragment;
case 1:
// add player
AddPlayerFragment addPlayerFragment = new AddPlayerFragment();
return addPlayerFragment;
case 2:
// settings
SettingsFragment settingsFragment = new SettingsFragment();
return settingsFragment;
case 3:
// help
HelpFragment helpFragment = new HelpFragment();
return helpFragment;
case 4:
// about us
AboutUsFragment aboutUsFragment = new AboutUsFragment();
return aboutUsFragment;
default:
return new HomeFragment();
}
}
// and the rest of my logic for navigations, action bar and so on.
// ....
}
HomeFragment is my parent fragment, please note that it implements OnFragmentInteractionListener also using childFragmentManager when creating my pagerView.
pager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
public class HomeFragment extends Fragment implements PlayerProfileFragment.OnFragmentInteractionListener {
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
private PlayerProfileFragment.OnFragmentInteractionListener mListener;
public static final String ARG_ITEM_ID = "item_id";
// players list
private List<Player> playersList;
public HomeFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setupView();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mListener = (PlayerProfileFragment.OnFragmentInteractionListener) getParentFragment();
}
private void setupView(){
// load data here
playersList = PlayerDao.getInstance(this.getContext()).getAllPlayers();
ViewPager pager = (ViewPager) getView().findViewById(R.id.viewPager);
// using childFragmentManager was part of my solution
pager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
}
#Override
public void showMoreData(int playerId) {
AlertDialog.Builder builder1 = new AlertDialog.Builder(this.getContext());
builder1.setMessage(" showMoreData id = " + playerId);
builder1.setCancelable(true);
AlertDialog alert12 = builder1.create();
alert12.show();
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
if (fm.getFragments() != null) {
fm.getFragments().clear();
}
}
#Override
public Fragment getItem(int pos) {
Player player = playersList.get(pos);
return PlayerProfileFragment.newInstance(player.getId(), player.getName(), player.getAge(), player.getImagePath());
}
#Override
public int getCount() {
return playersList.size();
}
}
}
PlayerProfileFragment class is my child fragment. Please note that, This is also part of my solution. Use getParentFragment() to initialise mListener
mListener = (PlayerProfileFragment.OnFragmentInteractionListener) getParentFragment();
public class PlayerProfileFragment extends Fragment {
private OnFragmentInteractionListener mListener;
// the fragment initialization parameters
private static final String ARG_PLAYER_NAME = "playerNameParam";
private static final String ARG_PLAYER_AGE = "playerAgeParam";
private static final String ARG_PLAYER_ID = "playerIdParam";
private static final String ARG_PLAYER_IMAGE_PATH = "playerImagePathParam";
private String playerNameParam;
private String playerAgeParam;
private int playerIdParam;
private String playerImagePathParam;
public PlayerProfileFragment() {
// Required empty public constructor
}
public static PlayerProfileFragment newInstance(int param1, String param2, int param3, String param4) {
PlayerProfileFragment fragment = new PlayerProfileFragment();
Bundle args = new Bundle();
args.putInt(ARG_PLAYER_ID, param1);
args.putString(ARG_PLAYER_NAME, param2);
args.putString(ARG_PLAYER_AGE, String.valueOf(param3));
args.putString(ARG_PLAYER_IMAGE_PATH, param4);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
playerNameParam = args.getString(ARG_PLAYER_NAME);
playerAgeParam = args.getString(ARG_PLAYER_AGE);
playerIdParam = args.getInt(ARG_PLAYER_ID);
playerImagePathParam = args.getString(ARG_PLAYER_IMAGE_PATH);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// This is also part of my solution: getParentFragment() -- very important
mListener = (PlayerProfileFragment.OnFragmentInteractionListener) getParentFragment();
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_player_profile, container, false);
TextView tvName = (TextView) v.findViewById(R.id.fragment_player_profile_name);
tvName.setText(playerNameParam);
TextView tvAge = (TextView) v.findViewById(R.id.fragment_player_profile_age);
tvAge.setText(playerAgeParam + " " + getString(R.string.athlete_info_banner_age_years_label));
Button showMoreButton = (Button) v.findViewById(R.id.fragment_player_profile_show_more_button);
showMoreButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onButtonShowMorePressed(playerIdParam);
}
});
return v;
}
public void onButtonShowMorePressed(int playerId) {
if (mListener != null) {
mListener.showMoreData(playerId);
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
*/
public interface OnFragmentInteractionListener {
void showMoreData(int playerId);
}
}
I hope it helps you guys. Let me know if you have any question.
Actually, i created a navigation drawer that has three items and on clicking on every item it goes to its fragment that displays certain type of products , so i have an Activity with three fragments for each type of them.
If i would like to add another product type i will have to create its fragment.
So ,My question is , are there any methods that can only make one fragment and every time an item is clicked only the data inside the fragment to be changed/replaced and not to replace the whole fragment itself with another ?
Edited my main activity:
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
DrawerLayout drawerLayout;
RecyclerView recyclerView;
String navTitles[];
private NavigationView navigationView;
TypedArray navIcons;
RecyclerViewAdapter recyclerViewAdapter;
ActionBarDrawerToggle drawerToggle;
Fragment[] fFragments = new Fragment[3];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Let's first set up toolbar
setupToolbar();
//Initialize Views
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
drawerLayout = (DrawerLayout) findViewById(R.id.drawerMainActivity);
//Setup Titles and Icons of Navigation Drawer
navTitles = getResources().getStringArray(R.array.navDrawerItems);
navIcons = getResources().obtainTypedArray(R.array.navDrawerIcons);
recyclerViewAdapter = new RecyclerViewAdapter(navTitles, navIcons, this);
recyclerView.setAdapter(recyclerViewAdapter);
recyclerViewAdapter.setClickedListener(new RecyclerViewAdapter.ClickListerner() {
#Override
public void onItemlistener(int index) {
updateUIWithIndex(index);
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//Finally setup ActionBarDrawerToggle
setupDrawerToggle();
//Add the Very First Fragment to the Container
updateUIWithIndex(1);
}
// on click update fragment
private void updateUIWithIndex(int index) {
drawerLayout.closeDrawers();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment fFragment = null;
if (fFragments[index - 1] == null) {
switch (index) {
case 1:
fFragment = new FirstFragment();
break;
case 2:
fFragment = new SecondFragment();
break;
case 3:
fFragment = new ThirdFragment();
break;
}
fFragments[index - 1] = fFragment;
} else {
fFragment = fFragments[index - 1];
}
fragmentTransaction.replace(R.id.containerView, fFragment);
fragmentTransaction.commit();
}
void setupToolbar() {
toolbar = (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
void setupDrawerToggle() {
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.app_name, R.string.app_name);
//This is necessary to change the icon of the Drawer Toggle upon state change.
drawerToggle.syncState();
}
}
My Fragment :
public class FirstFragment extends Fragment implements ClickListner {
private final String LOG_TAG = FirstFragment.class.getSimpleName();
private DisplayAdapter recyclerViewAdapter;
private RecyclerView recyclView;
private ArrayList<Products> pProduct = null;
private List<Products> prods = null;
ProductDbHelper pDB;
ProgressDialog mJsonDialog;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.all_products, container, false);
pDB = new ProductDbHelper(getActivity());
mJsonDialog = new ProgressDialog(getActivity());
mJsonDialog.setIndeterminate(true);
if (pDB.isDataAvailable() == 0) {
mJsonDialog.setMessage("Parsing JSON feed...");
mJsonDialog.show();
getFeed();
} else {
new FetchDatabaseTask().execute();
}
return myView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclView = (RecyclerView) view.findViewById(R.id.RecycleList);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclView.setLayoutManager(layoutManager);
recyclerViewAdapter = new DisplayAdapter(getActivity(), new ArrayList<Products>());
recyclView.setAdapter(recyclerViewAdapter);
recyclerViewAdapter.setClickListener(this);
}
#Override
public void itemClicked(View view, Parcelable product) {
Intent intent = new Intent(getActivity(), DetailActivity.class);
intent.putExtra("P", product);
startActivity(intent);
}
public void getFeed() {
RestInterface interfaces = Client.getClient().create(RestInterface.class);
Call<List<Products>> call = interfaces.getProductsReport();
call.enqueue(new Callback<List<Products>>() {
#Override
public void onResponse(Call<List<Products>> call, Response<List<Products>> response) {
prods = response.body();
for (int i = 0; i < prods.size(); i++) {
pDB.addShop(prods.get(i));
}
new FetchDatabaseTask().execute();
if (mJsonDialog.isShowing())
mJsonDialog.dismiss();
}
#Override
public void onFailure(Call<List<Products>> call, Throwable t) {
Log.e(LOG_TAG, "FFFF" + t.toString());
}
});
}
public class FetchDatabaseTask extends AsyncTask<Void, Void, List<Products>> {
protected void onPreExecute() {
mJsonDialog.setMessage("Reading from internal storage...");
mJsonDialog.show();
}
#Override
protected List<Products> doInBackground(Void... voids) {
// get all the shop's products
List<Products> lProduct = pDB.getAllShops();
// in the second fragment , sort the products' price in ascending order
List<Products> lProduct = pDB.sortShopsAscend();
// in the third fragment sort the products descendingly
List<Products> lProduct = pDB.sortShopsDescend();
return lProduct;
}
protected void onPostExecute(List<Products> shops) {
super.onPostExecute(shops);
if (shops != null) {
if (recyclerViewAdapter != null) {
recyclerViewAdapter.setData(shops);
} else {
pProduct = new ArrayList<>();
pProduct.addAll(shops);
}
}
if (mJsonDialog.isShowing())
mJsonDialog.dismiss();
}
}
}
Make those changes in the MainActivity class :
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
DrawerLayout drawerLayout;
RecyclerView recyclerView;
String navTitles[];
private NavigationView navigationView;
TypedArray navIcons;
RecyclerViewAdapter recyclerViewAdapter;
ActionBarDrawerToggle drawerToggle;<
//If you want to use the first fragment only
FirstFragment fragment = null;
.
.
.
recyclerViewAdapter.setClickedListener(new RecyclerViewAdapter.ClickListerner() {
#Override
public void onItemlistener(int index) {
//Call this method to close the drawer layout or you can simply call the close method here
updateUIWithIndex(index);
//Do something depending on the index
if(index == 0){
//Call getFeed() for example
fragment.getFeed();
}
else if(index == 1){
//call another method
}
}
});
.
.
.
// on click update fragment
//I don't know if you still need the index in this method
private void updateUIWithIndex(int index) {
//Close the drawer Layout anyway
drawerLayout.closeDrawers();
if (fragment == null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
//Create an instance of the FirstFragment
fragment = new FirstFragment();
fragmentTransaction.replace(R.id.containerView, fragment);
fragmentTransaction.commit();
}
}
You can simply pass variable to Fragment method.
Completely updated post
In your case:
set fragment as field in your MainActivity
private FirstFragment firstFragment;
Run this fragment in your OnCreate method in MainActivity
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
firstFragment = null;
firstFragment = new FirstFragment();
fragmentTransaction.replace(R.id.containerView, firstFragment );
fragmentTransaction.commit();
Then replace updateUIWithIndex method to fragment method, so you have:
recyclerViewAdapter.setClickedListener(new RecyclerViewAdapter.ClickListerner() {
#Override
public void onItemlistener(int index) {
firstFragment.getFeed(index)
}
});
Pass index to getFeed:
public void getFeed(int index) {
final int currentIndex = index;
RestInterface interfaces = Client.getClient().create(RestInterface.class);
Call<List<Products>> call = interfaces.getProductsReport();
call.enqueue(new Callback<List<Products>>() {
#Override
public void onResponse(Call<List<Products>> call, Response<List<Products>> response) {
prods = response.body();
for (int i = 0; i < prods.size(); i++) {
pDB.addShop(prods.get(i));
}
new FetchDatabaseTask(currentIndex ).execute();
if (mJsonDialog.isShowing())
mJsonDialog.dismiss();
}
#Override
public void onFailure(Call<List<Products>> call, Throwable t) {
Log.e(LOG_TAG, "FFFF" + t.toString());
}
});
Add constructor to FetchDatabaseTask class
public class FetchDatabaseTask extends AsyncTask<Void, Void, List<Products>> {
private int currentIndex = 0;
FetchDatabaseTask(int index) {
currentIndex = index;
}
//ur others methods here
}
And then you can do as you need in onPreExecute,doInBackground and onPostExecute methods like this:
protected void onPostExecute(List<Products> shops) {
super.onPostExecute(shops);
switch (currentIndex) {
case 0:
if (shops != null) {
if (recyclerViewAdapter != null) {
recyclerViewAdapter.setData(shops);
} else {
pProduct = new ArrayList<>();
pProduct.addAll(shops);
}
}
if (mJsonDialog.isShowing())
mJsonDialog.dismiss();
break;
case 1:
//ur SecondFragment code
break;
case 2:
//ur ThirdFragment code
break;
}
}
So you can use only one fragment for every type of product or whatever you want.
I have 3 fragments in a ViewPager Activity. All 3 fragments have input fields. Here I am trying to pass first two fragments data to third fragment. I read few posts here and most of them suggested to use interfaces(i.e. to pass data through parent activity)
I have also gone through this link
http://developer.android.com/training/basics/fragments/communicating.html
Interface: using interfaces is good approach when we are sending data through some user event. Here I am trying to send data without any user event. Hence I thought of onPause() since onPause() is always called. But ViewPager functions differently. When a fragment is loaded,the adjacent fragments are also loaded. I would be successful to pass data between 1st fragment to 3rd fragment. But 2nd fragment's onPause() wont be called unless I am navigating to some fragment that is not adjacent to it(which in my case is not there)
Setter/Getters:I have read in few posts people saying not to use setter/getters(I still havent understood the reason yet) Are getters and setters poor design? Contradictory advice seen
Bundle: I havent considered this yet. Since I am again confused here how would I pass data using bundle.(inside which method should I send data? and how?)
Sorry if my question sounds dumb.I am trying to understand fragments and i would like to know best way to pass data between fragments in viewpager.
Thank You in advance.
TabPAgerAdapter -- >
package com.jbandroid.model;
import com.jbandroid.fragment.LocationInfoFragment;
import com.jbandroid.fragment.PersonalInfoFragment;
import com.jbandroid.fragment.PostInfoFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm){
super(fm);
}
#Override
public Fragment getItem(int index) {
switch(index) {
case 0 : //PostInfoFragment
return new PostInfoFragment();
case 1 : //LocationInfoFragment
return new LocationInfoFragment();
case 2 : //PersonalInfoFragment
return new PersonalInfoFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
ViewPagerActivity -- >
package com.jbandroid;
public class SubmitPostActivity extends FragmentActivity implements ActionBar.TabListener,PostInfoFragment.setPostInfo,LocationInfoFragment.setLocationInfo{
private ViewPager viewpager;
private ActionBar actionBar;
private TabsPagerAdapter mAdapter;
FragmentManager manager;
PersonalInfoFragment frag;
List<String> location;
/*private MenuItem myActionMenuItem;
private Button myActionButton;*/
//Tab titles
private String[] tabs = {"Post Info" , "Location Info" , "Personal Info" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_submit_post);
viewpager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
manager = getSupportFragmentManager();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
//viewpager.setOffscreenPageLimit(2);
viewpager.setAdapter(mAdapter);
//actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (String tab : tabs){
actionBar.addTab(actionBar.newTab().setText(tab).setTabListener(this));
}
if(savedInstanceState != null){
actionBar.setSelectedNavigationItem( savedInstanceState.getInt("tab",0));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewpager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewpager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void pass_location_details(List<String> location) {
frag = (PersonalInfoFragment) manager.findFragmentByTag("android:switcher:" + viewpager.getId() + ":" + 2);
frag.get_post_location_details(location);
Log.d("submitarea", location.get(0));
}
#Override
public void pass_post_details(List<String> post_details,ArrayList<CustomGallery> selected) {
frag = (PersonalInfoFragment) manager.findFragmentByTag("android:switcher:" + viewpager.getId() + ":" + 2);
frag.get_post_details(post_details,selected);
Log.d("submitpostinfo","hello"+ post_details.get(5));
}
}
1st Fragment(Here I am trying to pass data using interface in onPause()-->
package com.jbandroid.fragment;
public class PostInfoFragment extends Fragment {
private MenuItem myActionMenuItem;
private Button myActionButton;
private ActionBar actionBar;
private String post_title, post_desc,post_status;
private EditText submit_post_title, submit_post_desc;
private Resources res;
setPostInfo info;
List<String> post_details;
//RelativeLayout rel_submit_post_start_date,rel_submit_post_end_date;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_post_info,
container, false);
/*if(!imageLoader.isInited()){*/
initImageLoader();
/*}*/
//handler = new Handler();
submit_post_title = (EditText) rootView
.findViewById(R.id.submit_post_title);
submit_post_desc = (EditText) rootView
.findViewById(R.id.submit_post_description);
actionBar = getActivity().getActionBar();
setHasOptionsMenu(true);
post_details = new ArrayList<String>();
res = getResources();
setListeners();
Log.d("postinfo_oncreate view", "postinfo_oncreate view");
return rootView;
}
//interface to pass data to activity and then to PersonalInfoFragment
public interface setPostInfo {
//public void pass_post_details(List<String> post_details);
public void pass_post_details(List<String> post_details,ArrayList<CustomGallery> selected);
}
//making sure if the parent activity has implemented interface
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
info = (setPostInfo) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ "must implemet setPostInfo");
}
Log.d("postinfo_onattach", "postinfo_onattach");
}
//passing form inputs to personalinfofragments
#Override
public void onPause() {
super.onPause();
// setFormInputs();
passFormInputs(); ---> passing in onPause() This executes successfully
Log.d("postinfo_onPAuse", "postinfo_onPause");
}
//method to pass data to personalinfofragment
private void passFormInputs() {
try {
post_title = submit_post_title.getText().toString();
post_desc = submit_post_desc.getText().toString();
post_status = "1";
if(post_title != null && post_title.length() > 0
&& post_desc != null && post_desc.length() > 0
&& post_status != null && post_status.length() > 0
){
post_details.add(post_title);
post_details.add(post_desc);
post_details.add(post_status);
info.pass_post_details(post_details,dataT); -->here I am passing values via
}else{ activity to 3rd fragment
Log.d("post_info", "values are null");
}
} catch (Exception e) {
e.printStackTrace();
}
}
//setting next button on actionbar
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Inflate the menu items for use in the action bar
inflater.inflate(R.menu.mymenu, menu);
// Here we get the action view we defined
myActionMenuItem = menu.findItem(R.id.my_action);
View actionView = myActionMenuItem.getActionView();
// We then get the button view that is part of the action view
if (actionView != null) {
myActionButton = (Button) actionView.findViewById(R.id.action_btn);
myActionButton.setText(R.string.txt_next);
if (myActionButton != null) {
// We set a listener that will be called when the return/enter
// key is pressed
myActionButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
actionBar.setSelectedNavigationItem(1);
}
});
}
}
}
}
2nd Fragment-->
package com.jbandroid.fragment;
public class LocationInfoFragment extends Fragment implements OnClickListener {
private MenuItem myActionMenuItem;
private Button myActionButton;
private ActionBar actionBar;
Dialog dialog;
private EditText submit_post_exact_location;
private TextView selected_country, selected_city,
submit_post_exact_time;
String country, city, exact_location, exact_time;
setLocationInfo info;
List<String> location;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_location_info,
container, false);
actionBar = getActivity().getActionBar();
setHasOptionsMenu(true);
submit_post_exact_location = (EditText) rootView
.findViewById(R.id.submit_post_exact_location);
submit_post_exact_time = (TextView) rootView
.findViewById(R.id.submit_post_exact_time);
selected_country = (TextView) rootView
.findViewById(R.id.selected_country);
selected_city = (TextView) rootView.findViewById(R.id.selected_city);
location = new ArrayList<String>();
setListeners();
return rootView;
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Inflate the menu items for use in the action bar
inflater.inflate(R.menu.mymenu, menu);
// Here we get the action view we defined
myActionMenuItem = menu.findItem(R.id.my_action);
View actionView = myActionMenuItem.getActionView();
// We then get the button view that is part of the action view
if (actionView != null) {
myActionButton = (Button) actionView.findViewById(R.id.action_btn);
myActionButton.setText(R.string.txt_next);
if (myActionButton != null) {
// We set a listener that will be called when the return/enter
// key is pressed
myActionButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
actionBar.setSelectedNavigationItem(2);
}
});
}
}
}
public interface setLocationInfo {
public void pass_location_details(List<String> location);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
info = (setLocationInfo) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ "must implement setLocationInfo");
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//setLocationDetails();
}
#Override
public void onPause() {
super.onPause();
setLocationDetails(); ----> doesnt executes since onPause isnt called when I navigate to 3rd fragment as it is an adjacent fragment of this fragment
// Log.d("location : onPause", area);
}
private void setLocationDetails() {
try {
exact_location = submit_post_exact_location.getText().toString();
exact_time = submit_post_exact_time.getText().toString();
country = selected_country.getText().toString();
city = selected_city.getText().toString();
if (country != null && country.length() > 0
&& !country.equalsIgnoreCase("select") && city != null
&& city.length() > 0 && !city.equalsIgnoreCase("select")
&& exact_location != null && exact_location.length() > 0
&& exact_time != null && exact_time.length() > 0) {
location.add(country);
location.add(city);
location.add(exact_location);
location.add(exact_time);
info.pass_location_details(location);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
In my 3rd Fragment I am trying to get this values
public class PersonalInfoFragment extends Fragment {
List<String> post_details;
List<String> location;
Button submit;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_personal_info,
container, false);
submit = (Button)rootView.findViewById(R.id.submitBtn);
submit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//performing operations with the values obtained
setPostItems();
insertintodb();
}
});
return rootView;
}
public void get_post_details(List<String> post_details,
ArrayList<CustomGallery> selected) { -->receiving values from
this.post_details = post_details; 1st fragment
this.selected = selected;
Log.d("personalfrag(postinfo)", "hello" + post_details.get(5));
}
//receiving values from 2nd fragment
public void get_post_location_details(List<String> location) {
this.location = location;
Log.d("personalfrag(locationinfo)", "hello" + location.get(0));
}
}
Okay, I Had same issue to pass data(not just string) between two tabs in a ViewPager. So here is what i did.
I Use interfaces to communicate between the different components.
The data passes this way:
Tab 1 -> Activity -> VewPageAdapter -> Tab 2
In Tab 1
create an interface.
OnCartsDataListener mOncarOnCartsDataListener;
public interface OnCartsDataListener {
public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mOncarOnCartsDataListener = (OnCartsDataListener)activity;
}catch (ClassCastException e){
}
}
// now call mOncarOnCartsDataListener.onCartsDataReceived(data) when you have the data
In Activity
Implement the interface and override the method
ViewPagerAdapter adapter;
adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs);
#Override
public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
Log.d(TAG, "data received to Activity... send to view pager");
adapter.onCartsDataReceived(cartsViewModels);
}
3.IN ViewPagerAdapter
Also implements the interface and override the method
#Override
public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
Log.d(TAG, "data received to view pager... sending to tab 2");
if(tab2!=null){
tab2.onCartsDataReceived(cartsViewModels);
}else{
Log.d(TAG, "tab2 is null");
}
}
Finally tab 2
Also implements the interface and override the method
#Override
public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
Log.d(TAG, "Finally ! received data to tab 2");
if(cartsViewModels!=null){
for(CartsViewModel cart : cartsViewModels){
Log.d(TAG,"got it :"+cart.getCartName());
}
}
}
Since AndroidX, you can create a ViewModel and share data between Activity and all fragments within ViewPager
Read here how to
Can you do something like this? First create any data structure like Arraylist in your main activity. Then send a reference of that data model to your fragments. Now update that data when, on change your text fields. By doing this all the fragment can see updated values. So fragments can update this data itself and we don't need to send that data since it is already shared. I'll explain this using your example. Try to improve this. You can maintain fragment specific data model then each fragment can access data with the knowledge of that data owner.
TabsPagerAdapter.java
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm,SubmitPostActivity activity){
super(fm);
}
#Override
public Fragment getItem(int index) {
switch(index) {
case 0 : //PostInfoFragment
return new PostInfoFragment(0,activity);
case 1 : //LocationInfoFragment
return new LocationInfoFragment(1,activity);
case 2 : //PersonalInfoFragment
return new PersonalInfoFragment(2,activity);
}
return null;
}
#Override
public int getCount() {
return 3;
}
}
ViewPagerActivity -- >
package com.jbandroid;
public class SubmitPostActivity extends FragmentActivity implements ActionBar.TabListener,LocationInfoFragment.setLocationInfo{
private ViewPager viewpager;
private ActionBar actionBar;
private TabsPagerAdapter mAdapter;
FragmentManager manager;
PersonalInfoFragment frag;
List<String> location;
/*private MenuItem myActionMenuItem;
private Button myActionButton;*/
//Tab titles
private String[] tabs = {"Post Info" , "Location Info" , "Personal Info" };
public List<String> dataModel = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_submit_post);
viewpager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
manager = getSupportFragmentManager();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(),this);
//viewpager.setOffscreenPageLimit(2);
viewpager.setAdapter(mAdapter);
//actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (String tab : tabs){
actionBar.addTab(actionBar.newTab().setText(tab).setTabListener(this));
}
if(savedInstanceState != null){
actionBar.setSelectedNavigationItem( savedInstanceState.getInt("tab",0));
}
}
}
1st Fragment =>
public class PostInfoFragment extends Fragment {
private MenuItem myActionMenuItem;
private Button myActionButton;
private ActionBar actionBar;
private String post_title, post_desc,post_status;
private EditText submit_post_title, submit_post_desc;
private int position;
private Resources res;
SubmitPostActivity callingActivity;
List<String> post_details;
public PostInfoFragment(int position,SubmitPostActivity callingActivity )
{
this.callingActivity = callingActivity;
this.position = position;
}
//RelativeLayout rel_submit_post_start_date,rel_submit_post_end_date;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_post_info,
container, false);
/*if(!imageLoader.isInited()){*/
initImageLoader();
/*}*/
//handler = new Handler();
submit_post_title = (EditText) rootView
.findViewById(R.id.submit_post_title);
submit_post_desc = (EditText) rootView
.findViewById(R.id.submit_post_description);
actionBar = getActivity().getActionBar();
setHasOptionsMenu(true);
post_details = new ArrayList<String>();
res = getResources();
setListeners();
Log.d("postinfo_oncreate view", "postinfo_oncreate view");
//this is editText onchange listner do the same for submit_post_desc as well
submit_post_title.addTextChangedListener( new TextWatcher()
{
#Override
public void onTextChanged( CharSequence s, int start, int before, int count )
{
}
#Override
public void beforeTextChanged( CharSequence s, int start, int count, int after )
{
}
#Override
public void afterTextChanged( Editable s )
{
if( callingActivity != null )
{
//use this.position in order to update relevant data
List<String> post_details = callingActivity.dataModel;
if( post_details == null )
{
post_details = new ArrayList<String>();
}
post_details.add(s.toString());
}
}
} );
return rootView;
}
//making sure if the parent activity has implemented interface
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
callingActivity = (SubmitPostActivity) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ "must implemet setPostInfo");
}
Log.d("postinfo_onattach", "postinfo_onattach");
}
}
Please not that this may not compile as it is. Try to get the concept.