Bottom menu bar goes blank by clicking second time on menu options - android

I have a problem with my Bottom bar in android. when i click on the bottom menu options it goes blank. Please help me out to fine what is the basic problem. Where is am I wrong.
It shows no error or exception in logcat.
Here is my code
public class BottomBarActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottom_bar);
final BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
// Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.action_library:
FragmentLibrary fragmentLibrary = new FragmentLibrary();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout1, fragmentLibrary);
fragmentTransaction.commit();
Toast.makeText(BottomBarActivity.this, "Library", Toast.LENGTH_SHORT).show();
break;
case R.id.action_notification:
//002
Fragment selectedFragmentNotification = FragmentNotification.newInstance();
FragmentTransaction fragmentTransactionNotification = getSupportFragmentManager().beginTransaction();
fragmentTransactionNotification.replace(R.id.frame_layout1, selectedFragmentNotification);
fragmentTransactionNotification.commit();
Toast.makeText(BottomBarActivity.this, "Notifications", Toast.LENGTH_SHORT).show();
break;
case R.id.action_more:
Fragment selectedFragmentMore = FragmentMore.newInstance();
FragmentTransaction fragmentTransactionMore = getSupportFragmentManager().beginTransaction();
fragmentTransactionMore.replace(R.id.frame_layout1, selectedFragmentMore);
fragmentTransactionMore.commit();
Toast.makeText(BottomBarActivity.this, "More", Toast.LENGTH_SHORT).show();
break;
case R.id.action_discovered:
Fragment selectedFragmentMain = FragmentMain.newInstance();
FragmentTransaction fragmentTransactionMain = getSupportFragmentManager().beginTransaction();
fragmentTransactionMain.replace(R.id.frame_layout1, selectedFragmentMain);
fragmentTransactionMain.commit();
Toast.makeText(BottomBarActivity.this, "Discover", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
});
//Manually displaying the first fragment
Fragment selectedFragment = FragmentMain.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout1, selectedFragment);
fragmentTransaction.commit();
}
}
Here is the Fragment Class Code.
This fragment is called when I click one of the menu item.
public class FragmentLibrary extends Fragment {
private static final String ARG_POSITION = "position";
private int position;
private PagerSlidingTabStrip tabs_L;
private ViewPager pager_L;
public FragmentLibrary() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_library, container, false);
pager_L = (ViewPager) view.findViewById(R.id.pagerL);
pager_L.setAdapter(new MyAdapterLibrary(getFragmentManager()));
tabs_L = (PagerSlidingTabStrip) view.findViewById(R.id.tabsL);
tabs_L.setViewPager(pager_L);
return view;
}
// ADAPTER CLASS
public class MyAdapterLibrary extends FragmentPagerAdapter {
private String[] titles = {
getString(R.string.tab_title_current_reading),
getString(R.string.tab_title_reading_lists),
getString(R.string.tab_title_history)
};
public MyAdapterLibrary(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragmentCurrentReading.newInstance(position);
case 1:
return FragmentReadingLists.newInstance(position);
case 2:
return FragmentHistory.newInstance(position);
}
return null;
}
#Override
public int getCount() {
return titles.length;
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
}

Related

setDisplayHomeAsUpEnabled(true) opens Options Menu

I have a fragment MyProfile (consists info about a logged user) which I want to be used by fragments Team (consists info about all team members). When I use MyProfile for Team fragment, I need up button. I read documentation guide, tried all from up navigation inside fragment and stopped on this example. The problem is instead of going back to the previous fragment in my case it just opens the options menu.
MainActivity
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
int id = item.getItemId();
if (id == R.id.nav_team) {
fragmentTransaction.replace(R.id.container, new TeamFragment())
.addToBackStack(null)
.commit();
}
TeamFragment
public class TeamFragment extends Fragment {
private String LOG_TAG = getClass().getSimpleName();
private ListView teamList;
private android.support.v4.app.FragmentManager fragmentManager;
public TeamFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragmentManager = getFragmentManager();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
((MainActivity) getActivity()).setActionBarTitle("Team");
View rootView = inflater.inflate(R.layout.fragment_announcement, container, false);
final SwipeRefreshLayout swipeToUpdate = rootView.findViewById(R.id.swiperefresh);
teamList = rootView.findViewById(R.id.announcements_list);
getTeamFromAPI(Contract.TEAM);
teamList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ImageView avatar = view.findViewById(R.id.team_img);
TextView fullname = view.findViewById(R.id.team_fullname);
TextView jobtitle = view.findViewById(R.id.team_jobtitle);
TextView email = view.findViewById(R.id.team_email);
avatar.buildDrawingCache();
Bitmap bitmap = avatar.getDrawingCache();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] bAvatar = baos.toByteArray();
//when team member i replace here current fragment with profile fragment
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment fragment = ProfileFragment.newInstance(String.valueOf(fullname.getText()),
String.valueOf(jobtitle.getText()),
String.valueOf(email.getText()), bAvatar);
fragmentTransaction.replace(R.id.container, fragment, "MEMBER_PROFILE")
.addToBackStack(null)
.commit();
}
});
return rootView;
}
private void getTeamFromAPI(String url) {
//fetch team members from database
}
}
Place where I try return back to TeamFragment
ProfileFragment
public class ProfileFragment extends Fragment{
private String LOG_TAG = getClass().getSimpleName();
private String mFullname;
private String mTitle;
private String mEmail;
private byte[] mAvatar;
private android.support.v4.app.FragmentManager fragmentManager;
private ActionBar actionBar;
private View rootView;
public ProfileFragment() {
// Required empty public constructor
}
public static ProfileFragment newInstance(String name, String title, String email, byte[] avatar) {
Bundle bundle = new Bundle();
bundle.putString("fullname", name);
bundle.putString("title", title);
bundle.putString("email",email);
bundle.putByteArray("avatar", avatar);
ProfileFragment fragment = new ProfileFragment();
fragment.setArguments(bundle);
return fragment;
}
private void readBundle(Bundle bundle) {
if (bundle != null) {
this.mFullname = bundle.getString("fullname");
this.mTitle = bundle.getString("title");
this.mEmail = bundle.getString("email");
this.mAvatar = bundle.getByteArray("avatar");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragmentManager = getFragmentManager();
// Sets "up navigation" for both phone/tablet configurations
actionBar = ((MainActivity)getActivity()).getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_announcement, container, false);
ListView listView = rootView.findViewById(R.id.announcements_list);
SwipeRefreshLayout swipe = rootView.findViewById(R.id.swiperefresh);
swipe.setEnabled(false);
readBundle(getArguments());
ArrayList<ProfileObject> list = new ArrayList<>();
list.add(new ProfileObject(mFullname, mTitle,mEmail,mAvatar));
ProfileAdapter adapter = new ProfileAdapter(getContext(), list);
listView.setAdapter(adapter);
return rootView;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Log.e(LOG_TAG+"/onOptionsItemSelected","Pressed: "+item.getItemId());
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ProfileFragment member_profile = (ProfileFragment)fragmentManager.findFragmentByTag("MEMBER_PROFILE");
fragmentTransaction.remove(member_profile).commit();
fragmentManager.popBackStack();
actionBar.setDisplayHomeAsUpEnabled(false);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
But as I already said it only the opens options menu. Did I make a somewhere conceptual mistake?
UPDATE: Problem inside onOptionsItemSelected. If add
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Log.e(LOG_TAG+"/onOptionsItemSelected","Pressed: "+item.getItemId());
return true;
default:
return super.onOptionsItemSelected(item);
}
}
and click on back arrow nothing will be in Logcat.
As per your code you have handled onOptionsItemSelected() for R.id.home but I see you are using ActionBar back button which is provided by Android UI itself
actionBar = ((MainActivity)getActivity()).getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
In this case Home Button is referenced as android.R.id.home and NOT R.id.home
This is the reason you are not getting any update in Logcat too (as you mentioned in comments).
Update your switch case as below and replace R.id.home with android.R.id.home
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: // <- Update this
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ProfileFragment member_profile = (ProfileFragment)fragmentManager.findFragmentByTag("MEMBER_PROFILE");
fragmentTransaction.remove(member_profile).commit();
fragmentManager.popBackStack();
actionBar.setDisplayHomeAsUpEnabled(false);
return true;
default:
return super.onOptionsItemSelected(item);
}

how to handle multiple fragments onbackpressed

The Main Activity having bottom navigation and contains 5 fragments in it. Each fragments having multiple fragment inside. how to handle the onbackpressed in it.
Homepage.java
public class Homepage extends AppCompatActivity {
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.home:
selectedFragment = Fragment_home.newInstance();
break;
case R.id.eventsfeed:
selectedFragment = Fragment_eventsfeed.newInstance();
break;
case R.id.events:
selectedFragment = Fragment_events.newInstance();
break;
case R.id.messages:
selectedFragment = Fragment_messages.newInstance();
break;
case R.id.settings:
selectedFragment = Fragment_settings.newInstance();
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content, selectedFragment);
transaction.commit();
return true;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.homepage);
Fragment fragmentnewview = new Fragment_home();
FragmentManager frMan = getSupportFragmentManager();
FragmentTransaction frTr = frMan.beginTransaction();
frTr.add(R.id.content,fragmentnewview);
frTr.commit();
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
BottomNavigationViewHelper.disableShiftMode(navigation);
}}
Fragment_home.java
public class Fragment_home extends Fragment {
public static Fragment_home newInstance(){
Fragment_home fragment=new Fragment_home();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view=inflater.inflate(R.layout.fragment_home, container, false);
CardView card=(CardView)view.findViewById(R.id.next_page_home_card);
card.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
view.setVisibility(View.GONE);
Fragment fragmentnewview = new Event_details();
FragmentManager frMan = getActivity().getSupportFragmentManager();
FragmentTransaction frTr = frMan.beginTransaction();
frTr.add(R.id.content,fragmentnewview);
frTr.commit();
}
});
return view;
}
}
Inside that Fragment_home.java i have a card view when it clicked it goes to next fragment Event_Details.java
Event_Details.java
public class Event_details extends Fragment {
Button add_comments;
ImageButton back;
public static Event_details newInstance(){
Event_details fragment=new Event_details();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view=inflater.inflate(R.layout.event_details, container, false);
add_comments=(Button)view.findViewById(R.id.add_comment);
back=(ImageButton)view.findViewById(R.id.back);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
view.setVisibility(View.GONE);
Fragment fragmentnewview = new Fragment_home();
FragmentManager frMan = getActivity().getSupportFragmentManager();
FragmentTransaction frTr = frMan.beginTransaction();
frTr.add(R.id.content,fragmentnewview);
frTr.commit();
}
});
add_comments.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
view.setVisibility(View.GONE);
Fragment fragmentnewview = new Comments();
FragmentManager frMan = getActivity().getSupportFragmentManager();
FragmentTransaction frTr = frMan.beginTransaction();
frTr.add(R.id.content,fragmentnewview);
frTr.commit();
}
});
return view;
}
}
i have a button in Event_Details.java when clicked that it calls another fragment Comments.java
Comments.java
public class Comments extends Fragment {
ImageButton back;
public static Comments newInstance(){
Comments fragment=new Comments();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view=inflater.inflate(R.layout.add_your_comments, container, false);
back=(ImageButton)view.findViewById(R.id.back);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
view.setVisibility(View.GONE);
Fragment fragmentnewview = new Event_details();
FragmentManager frMan = getActivity().getSupportFragmentManager();
FragmentTransaction frTr = frMan.beginTransaction();
frTr.add(R.id.content,fragmentnewview);
frTr.commit();
}
});
return view;
}
}
back.setOnClickListener is the image button to go back but i can't implement in the hardware back button.
You need to #Override your activity onBackPressed() method !!!
There are many good information and answers about your question ! if you want to become good programmer you need good research skills!!! :))
Try to research and solve the problem yourself . Write some code, and after all of it if you still can't resolve your problem i'll give you code for copy and paste :)
When you load a fragment, use addToBackStack(null) on the FragmentTransaction. If you do that, the back button will reverse the transaction.
#Override onBackPressed()
method as #L.Petrosyan told,
insideonBackPressed()get the current position of your viewpager usingviewPager.getCurrentItem();
it will return you anint` value. use that value to manage your code.

Android - TabLayout - Navigation with RecyclerView Items

I have a Tabbed Activity with 3 Tabs. On each Tab are RecyclerViews with some list items. If you click on an item a new fragment should open and there should appear a Back-Button in the toolbar. My current screen looks like this:
And now I will show you my code. At first MainActivity.java with the TabLayout:
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Pflege");
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
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.tab_icon_pflege);
tabLayout.getTabAt(1).setIcon(R.drawable.tab_icon_dokumentation);
tabLayout.getTabAt(2).setIcon(R.drawable.tab_icon_probleme);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
switch(tab.getPosition()) {
case 0:
mViewPager.setCurrentItem(0);
toolbar.setTitle("Pflege");
break;
case 1:
mViewPager.setCurrentItem(1);
toolbar.setTitle("Daten");
break;
case 2:
mViewPager.setCurrentItem(2);
toolbar.setTitle("Probleme");
break;
default:
mViewPager.setCurrentItem(tab.getPosition());
toolbar.setTitle("Pflege");
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
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:
Tab1Pflege tab1 = new Tab1Pflege();
return tab1;
case 1:
Tab2Dokumentation tab2 = new Tab2Dokumentation();
return tab2;
case 2:
Tab3Probleme tab3 = new Tab3Probleme();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Pflege";
case 1:
return "Daten";
case 2:
return "Probleme";
}
return null;
}
}
}
Here is the Fragment for the first tab with the RecyclerView:
public class Tab1Pflege extends Fragment {
private RecyclerView recyclerView;
private RecyclerView.Adapter rvAdapter;
private RecyclerView.LayoutManager rvLayoutManager;
private ArrayList<String> listItems;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1_pflege, container, false);
listItems = new ArrayList<>();
listItems.add("Test1");
listItems.add("Test2");
listItems.add("Test3");
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
rvLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(rvLayoutManager);
rvAdapter = new RvAdapter(listItems);
recyclerView.setAdapter(rvAdapter);
return rootView;
}
}
And here is my RecyclerView Adapter:
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.MyViewHolder> {
ArrayList<String> listItems;
public RvAdapter (ArrayList<String> listItems){
this.listItems = listItems;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item_layout, null);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.itemTitle.setText(listItems.get(position));
holder.itemImage.setImageResource(R.drawable.ic_keyboard_arrow_right);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(listItems.get(position));
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView itemTitle;
ImageView itemImage;
public MyViewHolder(View itemView){
super(itemView);
itemTitle = (TextView) itemView.findViewById(R.id.itemTitle);
itemImage = (ImageView) itemView.findViewById(R.id.itemImage);
}
}
}
In this class is an onClickListener for clicking on a list item. And there I want to open a new fragment for example for Test1. On top of that there should appear a Back-Button in the toolbar to navigate back to the Tab1 Overview with the RecyclerView. But I have no idea how to do that. Can someone help me with it?
In onClick, you can do something like this (to load another fragment)
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
Fragment fragment = // TODO: initialise your fragment 'fragment'
mFragments.push(fragment);
// Animation, if need it
// trans.setCustomAnimations(R.anim.right_in, R.anim.left_out,
// R.anim.right_out, R.anim.left_in);
// _container is the id of 'fragment' container in the your xml
trans.replace(R.id._container, fragment);
// variable to identify this fragment, and title of the page as well
String name = // TODO: initialise
trans.addToBackStack(name);
trans.commit();
getSupportActionBar().setTitle(name);
and in onCreate of your activity, setup listener for back stack changes.
FragmentManager manager = getSupportFragmentManager();
manager.addOnBackStackChangedListener(mBackStackListener);
and you can change back icon in
private OnBackStackChangedListener mBackStackListener = new OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
FragmentManager manager = getSupportFragmentManager();
int count = manager.getBackStackEntryCount();
if(count > 0) {
// TODO: Show back icon
} else {
// TODO: Other icon
}
}
};

Show a detail fragment when clicking an item in a ListFragment in Android Studio

My app has a tab bar that should be visible at all times. The first tab contains a ListFragment. When I click on an item within, it loads a new activity that creates a detail fragment displaying the contents of the object in the list. I would like to display this content without having to start a new activity because it also destroys the tab bar!
Any help would be greatly appreciated!
To illustrate, here are some screenshots and code:
This is the code for the FragmentActivity that creates the tabs:
public class MainFragmentActivity extends FragmentActivity
implements ActionBar.TabListener {
SectionsPagerAdapter sectionsPagerAdapter = null;
ViewPager viewPager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
sectionsPagerAdapter =
new SectionsPagerAdapter
(
getSupportFragmentManager());
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(sectionsPagerAdapter);
viewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
}); // End of sectionPageAdapter.
Tab browseTab = actionBar.newTab();
browseTab.setIcon(R.drawable.search);
browseTab.setTabListener(this);
actionBar.addTab(browseTab);
Tab myStuffTab = actionBar.newTab();
myStuffTab.setIcon(R.drawable.my_stuff);
myStuffTab.setTabListener(this);
actionBar.addTab(myStuffTab);
Tab profileTab = actionBar.newTab();
profileTab.setIcon(R.drawable.profile);
profileTab.setTabListener(this);
actionBar.addTab(profileTab);
Tab settingsTab = actionBar.newTab();
settingsTab.setIcon(R.drawable.settings);
settingsTab.setTabListener(this);
actionBar.addTab(settingsTab);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment browseFragment = new BrowseFragment();
Bundle browseArgs = new Bundle();
browseArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
browseFragment.setArguments(browseArgs);
return browseFragment;
case 1:
Fragment myStuffFragment = new MyStuffFragment();
Bundle myStuffArgs = new Bundle();
myStuffArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
myStuffFragment.setArguments(myStuffArgs);
return myStuffFragment;
case 2:
Fragment profileFragment = new ProfileFragment();
Bundle profileArgs = new Bundle();
profileArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
profileFragment.setArguments(profileArgs);
return profileFragment;
case 3:
Fragment settingsFragment = new SettingsFragment();
Bundle settingsArgs = new Bundle();
settingsArgs.putInt(BrowseFragment.sectionNumberKey, position + 1);
settingsFragment.setArguments(settingsArgs);
return settingsFragment;
}
return null;
}
// There are always 4 tabs
#Override
public int getCount() {
return 4;
}
// Return a CharSequence for the selected tab
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase();
case 1:
return getString(R.string.title_section2).toUpperCase();
case 2:
return getString(R.string.title_section3).toUpperCase();
case 3:
return getString(R.string.title_section4).toUpperCase();
}
return null;
}
}
} // End of class.
This is the code for the first tab:
public class BrowseFragment extends ListFragment {
public static String sectionNumberKey = "sec_num";
private String activityName = "Browse";
int currentPosition = 0;
List<Listing> listings = new ListingData().getListings();
public BrowseFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BrowseArrayAdapter adapter = new BrowseArrayAdapter(getActivity(),
R.layout.browselist_item,
listings);
setListAdapter(adapter);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_browse,
container, false);
TextView tv = (TextView) rootView.findViewById(R.id.section_label);
int intSectionNumber = getArguments().getInt(sectionNumberKey);
String numAsString = Integer.toString(intSectionNumber);
tv.setText(numAsString);
activityName += " " + numAsString;
return rootView;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
showDetails(position);
}
void showDetails(int index) {
currentPosition = index;
Intent intent = new Intent();
intent.setClass(getActivity(), BrowseDetailsActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
And here is the code for the Detail Activity:
public class BrowseDetailsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
BrowseDetailFragment details = new BrowseDetailFragment();
details.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
}
}
}
Basicly you just have to use the content of the onCreate method from your BrowseDetailActivity in the showDetails method of your BrowseFragment. In this way, you can drop your BrowseDetailsActivity.
BrowseFragment.java
void showDetails(int index) {
BrowseDetailFragment details = BrowseDetailFragment.newInstance(index);
getChildFragmentManager().beginTransaction().add(details).commit();
}
And use the static newInstance method inside your BrowseDetailFragment like so:
BrowseDetailFragment.java
public class BrowseDetailFragment extends Fragment {
private int position;
public static BrowseDetailFragment newInstance(int position) {
BrowseDetailFragment fragment = new BrowseDetailFragment();
fragment.position = position;
return fragment;
}
public BrowseDetailFragment() {
//Required empty constructor
}
//Lifecycle methods and logics
}
Make sure to provide some navigation option so users can return to your list.

Facebook like dynamic viewpager

I am trying to create facebook like viewpager (swipable tabs and proper backstack) I can create swipable tabs but cant handle the proper back navigation. Bellow is my code
public class MainActivity extends FragmentActivity {
private ViewPager mPager;
// private SlidePagerAdapter mPagerAdapter;
private MyPagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Instantiate a ViewPager and a PagerAdapter. */
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setOffscreenPageLimit(4);
}
#Override
public void onBackPressed() {
Fragment currentVisibleFragment = mPagerAdapter.getRegisteredFragment(mPager.getCurrentItem());
if (currentVisibleFragment != null && currentVisibleFragment.isVisible()) {
FragmentManager childFm = currentVisibleFragment.getChildFragmentManager();
System.out.println("============================================");
System.out.println("childFm.getBackStackEntryCount()=== " + childFm.getBackStackEntryCount());
System.out.println("============================================");
if (childFm.getBackStackEntryCount() > 0) {
childFm.popBackStack();
return;
}
}
super.onBackPressed();
}
}
Adapter of my class is as bellow
public class MyPagerAdapter extends SmartFragmentStatePagerAdapter {
private static int NUM_ITEMS = 3;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return new FragmentA();
case 1: // Fragment # 0 - This will show FirstFragment different title
return new FragmentB();
case 2: // Fragment # 1 - This will show SecondFragment
return new FragmentC();
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
here is the exteded adapter
public abstract class SmartFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
// Sparse array to keep track of registered fragments in memory
private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Register the fragment when the item is instantiated
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
// Unregister when the item is inactive
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
// Returns the fragment for the position (if instantiated)
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
and Fragments are as bellow
public class FragmentA extends Fragment {
public static final String TAG = "FragmentA";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.first_fragment, container, false);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getChildFragmentManager().beginTransaction();
/*
* IMPORTANT: We use the "root frame" defined in
* "root_fragment.xml" as the reference to replace fragment
*/
trans.replace(R.id.framelayout_infragment_one, new FragmentA1());
/*
* IMPORTANT: The following lines allow us to add the fragment
* to the stack and return to it later, by pressing back
*/
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
public class FragmentA1 extends Fragment {
public static final String TAG = "FragmentA1";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.first_fragment, container, false);
view.setBackgroundColor(Color.RED);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getChildFragmentManager().beginTransaction();
/*
* IMPORTANT: We use the "root frame" defined in
* "root_fragment.xml" as the reference to replace fragment
*/
trans.replace(R.id.framelayout_infragment_one, new FragmentA2());
/*
* IMPORTANT: The following lines allow us to add the fragment
* to the stack and return to it later, by pressing back
*/
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
//second inner fragment
public class FragmentA2 extends Fragment {
public static final String TAG = "FragmentA2";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.second_fragment, container, false);
view.setBackgroundColor(Color.GRAY);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(R.id.root_frame, new FragmentC());
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
When I am going to frament A2 expected behaviour when user press back is I want to go to Frament A1 but I am going to Frament A. Fragment B,B1,B2 are same as A A1 A2 resp...
Please help
I managed it by maintaining stacks by myself
public static HashMap<String, Stack<Fragment>> mStacks;
mStacks = new HashMap<String, Stack<Fragment>>();
mStacks.put("TAB1", new Stack<Fragment>());
mStacks.put("TAB2", new Stack<Fragment>());
mStacks.put("TAB3", new Stack<Fragment>());
mStacks.put("TAB4", new Stack<Fragment>());
//when starting new fragment add that to stack like this
public void pushFragments(Fragment fragment) {
setSelectedPageN(pager.getCurrentItem());
mStacks.get(ApplicationConstants.CURRENT_TAB).push(fragment);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (ApplicationConstants.CURRENT_TAB.equals("TAB1")) {
ft.replace(R.id.container_feed, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB2")) {
ft.replace(R.id.container_chart, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB3")) {
ft.replace(R.id.container_explore, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB4")) {
ft.replace(R.id.container_profile, fragment);
}
ft.commit();
}
//When you want to finish
public void popFragments() {
/*
* Select the second last fragment in current tab's stack.. which will
* be shown after the fragment transaction given below
*/
setSelectedPageN(pager.getCurrentItem());
Fragment fragment = mStacks.get(ApplicationConstants.CURRENT_TAB).elementAt(mStacks.get(ApplicationConstants.CURRENT_TAB).size() - 2);
if (fragment instanceof ProfileContainerFragment) {
fragment = new ProfileFragment();
} else if (fragment instanceof FeedNewUserGuideline && !isShowFeedTutorial) {
fragment = new FeedFragment();
}
/* pop current fragment from stack.. */
mStacks.get(ApplicationConstants.CURRENT_TAB).pop();
/*
* We have the target fragment in hand.. Just show it.. Show a standard
* navigation animation
*/
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);
if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_FEED)) {
ft.replace(R.id.container_feed, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_CHART)) {
ft.replace(R.id.container_chart, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_EXPLORE)) {
ft.replace(R.id.container_explore, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_PROFILE)) {
ft.replace(R.id.container_profile, fragment);
}
ft.commit();
}
//When user back press
#Override
public void onBackPressed() {
try {
if (((BaseFragment) mStacks.get(ApplicationConstants.CURRENT_TAB).lastElement()).onBackPressed() == false) {
switch (pager.getCurrentItem()) {
case KeyConstants.POSITION_ONE_FEED:
if (mStacks.get(ApplicationConstants.TAB_FEED).size() == 1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();
// super.onBackPressed(); // or call finish..
} else {
popFragments();
}
break;
case KeyConstants.POSITION_TWO_CHART:
if (mStacks.get(ApplicationConstants.TAB_CHART).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_ONE_FEED);
} else {
popFragments();
}
break;
case KeyConstants.POSITION_THREE_EXPLORE:
if (mStacks.get(ApplicationConstants.TAB_EXPLORE).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_TWO_CHART);
} else {
popFragments();
}
break;
case KeyConstants.POSITION_FOUR_PROFILE:
if (mStacks.get(ApplicationConstants.TAB_PROFILE).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_THREE_EXPLORE);
} else {
popFragments();
}
break;
default:
break;
}
} else {
// do nothing.. fragment already handled back button press.
}
} catch (Exception e) {
e.printStackTrace();
}
}

Categories

Resources