I am using the library com.roughike:bottom-bar:1.2.1 to make an Android app using bottom tabs. The problem is that in his github, there is no actual example on how tabs work with fragments. I have tried to work my way around it but to no success. Here is the code below.
public class MainActivity extends AppCompatActivity {
private CoordinatorLayout coordinatorLayout;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.three_buttons_activity);
BottomBar bottomBar = BottomBar.attach(this, savedInstanceState);
bottomBar.setItemsFromMenu(R.menu.three_buttons_menu, new OnMenuTabSelectedListener() {
#Override
public void onMenuItemSelected(int itemId) {
switch (itemId) {
case R.id.recent_item:
//Snackbar.make(coordinatorLayout, "Recent Item Selected", Snackbar.LENGTH_LONG).show();
break;
case R.id.favorite_item:
//Snackbar.make(coordinatorLayout, "Favorite Item Selected", Snackbar.LENGTH_LONG).show();
break;
case R.id.location_item:
//Snackbar.make(coordinatorLayout, "Location Item Selected", Snackbar.LENGTH_LONG).show();
break;
}
}
});
bottomBar.setActiveTabColor("#FFFFFF");
}
}
I wanted to have for example if I choose "recent item" it will go to recent item tab and do whatever on that tab but it doesn't happen to me.
If any of you have a good suggestion and example on how to do it right, I will really appreciate it..
Thanks
I used this bottom bar over a year ago. this is how i added the fragments.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_three_buttons);
// ************* Setting Up The Bottom Bar ************ //
BottomBar bottomBar = BottomBar.attach(this, savedInstanceState);
bottomBar.noTabletGoodness();
// *********** Adding Item Fragments to the bottom Bar ************ //
bottomBar.setFragmentItems(getSupportFragmentManager(), R.id.fragmentContainer,
new BottomBarFragment(ProfileFragment.newInstance("Content For Profile"), R.drawable.ic_profile, "Profile"),
new BottomBarFragment(MessagesFragment.newInstance(), R.drawable.ic_chat, "Messages"));
// bottomBar.setActiveTabColor("#009688");
bottomBar.setActiveTabColor(getResources().getColor(R.color.blue));
}
And one of the Fragment Class:
public class ProfileFragment extends Fragment {
public static ProfileFragment newInstance(String text) {
Bundle args = new Bundle();
args.putString(STARTING_TEXT, text);
ProfileFragment homeFragment = new ProfileFragment();
homeFragment.setArguments(args);
return homeFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout_profile_fragment, container, false);
// do your stuff
return rootView;
}
Related
I have already add an bottom navigation bar into my project with 3 fragments (Home_fragment, Wallet_fragment,Account_fragment). I have added login button in Account_fragment. Now i want that When ever i click on login button login_fragment(afterlogin_fragment) open with bottom navigation bar.
I have attaching a link to video showing my problem. link -- https://cloud.degoo.com/share/o41Axz4FYFHBx7
and here is codes ---
mainActivity ---
BottomNavigationView bottomNavigationView = findViewById(R.id.main_nav);
bottomNavigationView.setOnNavigationItemSelectedListener(navListener);
getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_layout, new HomeFragment()).commit();
}
BottomNavigationView.OnNavigationItemSelectedListener navListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment selecrFlag = null;
switch (menuItem.getItemId())
{
case R.id.nav_home:
selecrFlag = new HomeFragment();
break;
case R.id.nav_wallet:
selecrFlag = new WalletFragment();
break;
case R.id.nav_Account:
selecrFlag = new AccountFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_layout, selecrFlag).commit();
return true;
}
};
};
Account_fragment ---
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_account, container, false);
EmailID = v.findViewById(R.id.editTextEmail);
Passwd = v.findViewById(R.id.editPassword);
SignUpBt = v.findViewById(R.id.signbutton);
LoginBt = v.findViewById(R.id.loginbutton);
LoginBt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(AccountFragment.this.getContext(),AfterLogin.class));
}
});
afterlogin Fragment --
package com.thechamp.earnbyads;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class AfterLogin extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_after_login);
}
}
Look like you are confused. the way that you move to another Screen is not Fragment. It is Activity.
There are many ways to deal with this.
you can change your AfterLogin to Fragment.
or implement the AfterLogin Activity as what you implement in your Current Activity that has those 3 Fragments.
I've been developing an android app which I included the default Navigation-Drawer from Android Studio and so on. In my home fragment, I've implemented CarViews, and then set those cardview(s) OnClickListener to replace the fragment with traditional procedure.
After the fragment replacement and new page comes, I wanted to change the Actionbar title.
So in the onCreateView(...) method, I tried,
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("B");
It worked. But after pressing the hardware back button to go back to the stacked fragment, the title remains changed & it doesn't change to "Home" again. I've tried other ways. Here's my following codes. Thanks in advance.
public class HomeFragment extends Fragment implements View.OnClickListener {
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity())).getSupportActionBar()).setTitle("Home");
CardView cardView1 = root.findViewById(R.id.doctor_on);
CardView cardView2 = root.findViewById(R.id.ambulance_e);
CardView cardView3 = root.findViewById(R.id.maintainance_s);
cardView1.setOnClickListener(this);
cardView2.setOnClickListener(this);
cardView3.setOnClickListener(this);
return root;
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.doctor_on:
FragmentTransaction fragmentTransaction = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment1 = new doctors();
fragmentTransaction.replace(R.id.container1, fragment1).addToBackStack(getString(R.string.menu_home)).commit();
return;
case R.id.ambulance_e:
//Put Actions
FragmentTransaction fragmentTransaction2 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment2 = new ambulance();
fragmentTransaction2.replace(R.id.container1, fragment2).addToBackStack(getString(R.string.menu_home)).commit();
return;
case R.id.maintainance_s:
//Put Actions
FragmentTransaction fragmentTransaction3 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment3 = new maintanance();
fragmentTransaction3.replace(R.id.container1, fragment3).addToBackStack(getString(R.string.menu_home)).commit();
return;
}
}
#Override
public void onResume() {
super.onResume();
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Home");
}
}
To the next fragment(where I change the titlebar and pressed back button):
public class doctors extend Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("B");
View root = inflater.inflate(R.layout.fragment_doctors, container, false);
return root;
}
}
And in the doctors Fragment... Should fix the title error.
#Override
public void onDestroyView() {
super.onDestroyView();
Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity()))
.getSupportActionBar())
.setTitle(getString(R.string.your_title_here));
}
You have to override the method onBackPressed() and write the code:
#Override
public View onBackPressed(){
//Here goes the code that head back to your main fragment
FragmentTransaction fragmentTransaction3 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment3 = new maintanance();
fragmentTransaction3.replace(R.id.container1, fragment3).addToBackStack(getString(R.string.menu_home)).commit();
}
}`
Add below code in Home Fragment...
#Override
public void onHiddenChanged(Boolean hidden) {
super.onHiddenChanged(hidden);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Home");
}
I have four fragments in an Activity C. they are behaving as tabs. I have to go from a fragment to a new Activity X. Now i want to come back to fragment from Activity X to fragment.
here is my main activity
'public class MainInterface extends ActionBarActivity {
ViewPager pager;
PagerTabStrip tab_strp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_interface);
MainPagerAdapter mapager = new MainPagerAdapter(getSupportFragmentManager());
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(mapager);
tab_strp = (PagerTabStrip) findViewById(R.id.tab_strip);
//tab_strp.setTextColor(Color.WHITE);
//tab_strp.setTextSize(14,14);
//tab_strp.setTabIndicatorColor(Color.WHITE);
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#2196f3")));
getSupportActionBar().setTitle("Instructor");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//getSupportActionBar().setHomeButtonEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; goto parent activity.
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
'
here is activity
'public class Discussions extends Fragment implements View.OnClickListener {
ImageButton post;
TextView dTitle;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view =inflater.inflate(R.layout.discussions,container,false);
post=(ImageButton)view.findViewById(R.id.ibDisc);
post.setOnClickListener(this);
dTitle=(TextView)view.findViewById(R.id.tvDiscTitle);
return view;
}
#Override
public void onClick(View view) {
Intent in=new Intent(getActivity(),PostDiscussion.class);
startActivity(in);
}
}'
Save the name of your fragment in sharedPreferences before navigating to new activity and onBackpressed of that new activity or when you want to come back to same fragment get the name from SharedPreferences and add that particular fragment to the earlier activity
I have a MainActivity. It's layout contains a fragmentContainer and an actionBar. Then I have 2 different fragments containing various EditTexts.All of them have Ids. I populate the fragmentContainer with the fragments when user clicks a button in actionBar. Everything works perfectly.
Now...the app, is supposed to collect the contents of all EditTexts from both fragments when I push a button (in the menu of the actionBar). But it does not work. It crashes when I try to access the EditTexts directly from the activity. I understand that I should create a public method inside the code of the fragments that will return the values I am interested in. But I seem to be doing something wrong because the method is not accessible from the main (TabActivity)
Here is my code:
public class TabActivity extends Activity {
ActionBar.Tab tab_alocare, tab_merc;
Fragment fragmentTab1 = new aloc_fragment();
Fragment fragmentTab2 = new merc_fragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab); // this layout contains the fragmentContainer
...// here I do some actionBar stuff
}
...
}
An example of one of the fragments is bellow:
public class aloc_fragment extends Fragment {
EditText mEditText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_aloc, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mEditText = (EditText) getView().findViewById(R.id.edaloc);
}
public String getMyText() {
String rez = "";
if (mEditText.getText()!=null) {
rez = mEditText.getText().toString();
}
return rez;
}
}
Now... if inside the Activity code I want to access the edaloc EditText using findViewById, it crashes the app with nullException. So I then tried to access the public method of the fragment so that it would return me the value that I need. But "getMyText" method is not accessible from the TabActivity.
So, this code does not work:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
Fragment alocfragment = (Fragment) getFragmentManager().findFragmentByTag("aloc");
String s = alocfragment.getMyText(); // this is not compiling at all
I am clearly doing something wrong.
Please advise.
Thank you
There are lots of mistakes in your code, You have neither declared nor initialize the fragments at proper place. Also, you are trying to create another instance of fragment in onOptionsItemSelected which is wrong, you need to use same instance of fragment there to access your functions with values. I hope you know how to add and inflate fragment. See my comments and code changes.
Try with this -
public class TabActivity extends Activity {
ActionBar.Tab tab_alocare, tab_merc;
//Declare fragments here
Fragment fragmentTab1;
Fragment fragmentTab2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab); // this layout contains the fragmentContainer
//Initialize here
fragmentTab1 = new aloc_fragment();
fragmentTab2 = new merc_fragment();
//inflate/add fragments here to the activity
...// here do your actionBar stuff
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
//Now, use same instance of fragment to access your function
String s = fragmentTab1.getMyText();
}
}
public class aloc_fragment extends Fragment {
EditText mEditText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_aloc,
container, false);
//hold edittext here in the variable
mEditText = (EditText) view.findViewById(R.id.edaloc);
return view;
}
public String getMyText() {
String rez = "";
if (mEditText.getText()!=null) {
rez = mEditText.getText().toString();
}
return rez;
}
}
Also, must to go through Fragment tutorial on Android Developer Fragment Link Link 2, Using Fragments
I have a problem with one thing - when I change orientation my second fragment, which is active at the moment, replaces by first fragment. I have never so such a behaviour, how can If fix it?
MainActivity:
public class MainActivity extends SherlockFragmentActivity implements onDialogClickListener, ITaskLoaderListener {
FragmentManager fm;
public ActionBar actionBar;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pager_layout);
fm = getSupportFragmentManager();
actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(false);
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentTransaction ft = fm.beginTransaction();
ft.add(android.R.id.content, new FirstActivity.FirstFragment(), "loan").commit();
}
}
FirstFragment:
public class FirstActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "here");
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentById(android.R.id.content) == null) {
FirstFragment first = new FirstFragment();
fm.beginTransaction().add(android.R.id.content, first).commit();
}
}
public static class FirstFragment extends SherlockFragment implements OnClickListener, OnItemClickListener {
private static final String TAG = "LoanFragment";
private View rootView;
private Button bExtend;
private FragmentManager fm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (session.hasLoan()) {
rootView = inflater.inflate(R.layout.fragment_loan, container, false);
bExtend = (Button) rootView.findViewById(R.id.b1);
return rootView;
}
}
#Override
public void onClick(View v) {
FragmentTransaction ft = fm.beginTransaction();
switch (v.getId()) {
case R.id.b1:
ft.add(android.R.id.content, new SecondActivity.SecondFragment(), "second").addToBackStack(null).commit();
break;
}
Second Fragment:
public class SecondActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentById(android.R.id.content) == null) {
SecondFragment second = new secondFragment();
fm.beginTransaction().add(android.R.id.content, second).commit();
}
}
public static class SecondFragment extends SherlockFragment {
private View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_extend, container, false);
return rootView;
}
That`s to say when I am in second fragment and try to change orientation then my second fragment will replaced on first fragment. Why? How to fix it?
onCreate will be called on orientation change and you add the first fragment there. You can save which fragment you want to show in onSaveInstanceState and then use the instance state in onCreate to add the correct fragment.
EDIT:
You need to maintain a variable currentFragmentIndex and save it in onSaveInstanceState like so:
protected void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putInt("currentFragment", currentFragment);
}
Then retrieve it in onCreate and initialize the fragment accordingly:
public void onCreate(Bundle bundle) {
if (bundle!= null){
currentFragmentIndex= bundle.getInt("currentFragment");
} else {
currentFragmentIndex = 0;
}
switch(currentFragmentIndex) {
case 0:
// TODO: Add first fragment
break;
case 1:
// TODO: Add second fragment
break;
}
}
Don't forget to change currentFragmentIndex to 1 when you switch to the second fragment.
I ran into the same issue, though as a note, I'm using the v4 support library. After reading Sapan Diwakar's answer, I wondered if this was necessary; instead, I tried this...
if (null == mFragmentManager.findFragmentByTag(TAG_HERE)) {
mFragmentManager.beginTransaction()./*blah blah blah*/.commit();
}
...so the original fragment is only instantiated/attached if there's nothing already attached where it's supposed to go.
I've tested this a bit and it seems to be fine... of course, the fact that it works doesn't mean it's a good idea, but I'm too new at this to know why it wouldn't be. If anyone can chime in on that, it'd be useful.
Thanks for posting this question, and also to everyone with input!