So I'm trying to add some content to my navigation drawer dynamically. In principle, it works. I can add stuff in my app, and I can make it show up in the navigation drawer. Only problem is, I have to restart the app for the new stuff in the navigation drawer to popup (because I can only get the code working in the onCreate method), which is not the desired behaviour.
This is what I've got in the onCreate method at the moment:
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu menu = navigationView.getMenu();
MenuItem it1 = menu.add(R.id.group1, 1, 2, "TEST DYNAMIC");
Very basic, but it does what I want. It adds a "test" header to the menu.
What I want, is to be able to access this bit of code at will, so for example when I press a button. I haven't been able to do this myself unfortunately. It doesn't matter if it's in a method in the MainActivity, or in one of my other fragments, but it shouldn't only be run when the MainActivity is created, that's not enough. Also, I probably need a Navigation Drawer re-draw after adding something to it (I'm guessing), but I don't know how to do that either, so any help on that would be great.
I tried the following code
Here button is the variable if type Button and i added onClickListener on it.
EDIT :: In Activity do like this
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
Menu menu = navigationView.getMenu();
SubMenu topChannelMenu = menu.addSubMenu("Category");
topChannelMenu.add("Menu Name");
MenuItem mi = menu.getItem(menu.size()-1);
mi.setTitle(mi.getTitle());
}
});
EDIT :: In Fragment do like this
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
Menu menu = navigationView.getMenu();
SubMenu topChannelMenu = menu.addSubMenu("Category");
topChannelMenu.add("Menu Name");
MenuItem mi = menu.getItem(menu.size()-1);
mi.setTitle(mi.getTitle());
}
});
Its working...
This adds menu to the end of previous menu.
Related
I built a customizable navigation drawer from scratch(didn't make use of the default drawer provided by Android Studio). In my weather app's navigation bar menu https://i.stack.imgur.com/SIjdx.jpg, whenever I select an option on the menu(say settings), it displays the contents of the option along with the bottom navigation view and my Activity's Toolbar contents which comprises of the nav hamburger icon, the edittext and the search button(the activity hosting my 3 fragments) which spoils the app and makes it look very ugly i.e. https://i.stack.imgur.com/gxj5n.jpg (From that screenshot, the entire content should be empty if implemented well). The case is the same for the other bar menu options. All I want is an empty space to work on, I want the app to only display the navigation bar contents without the rest. Example; https://i.stack.imgur.com/3Jtga.png Please how should I do this?
The view of the Navigation Menu is controlled by this code(on line 185):
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.settings_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new Settings()).commit();
break;
case R.id.ads_upgrade_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new Upgrade()).commit();
break;
case R.id.privacy_policy_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new Privacy_Policy()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
"fragment" there represents that I'm currently using my fragment's container view on my activity to display the Nav menu contents which I know is wrong for sure, so what should I use in replace? I lack strong experience as it's my first time building an app and I've tirelessly spent 3 hours on my own trying to figure out the issue which proved abortive.
Here is my Activity code:
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
// Last update time, click sound, search button, search panel.
TextView timeField;
MediaPlayer player;
ImageView Search;
EditText textfield;
// For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
ConstraintLayout constraintLayout;
public static int count = 0;
int[] drawable = new int[]{R.drawable.dubai, R.drawable.norway, R.drawable.eiffel_tower, R.drawable.hong_kong, R.drawable.statue_of_liberty,
R.drawable.beijing, R.drawable.chicago, R.drawable.colombia, R.drawable.vienna,R.drawable.tokyo};
Timer _t;
private WeatherDataViewModel viewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// use home activity layout.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Allow activity to make use of the toolbar
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);
// Trigger action to open & close navigation drawer
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar
, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
timeField = findViewById(R.id.textView9);
Search = findViewById(R.id.imageView4);
textfield = findViewById(R.id.textfield);
// find the id's of specific variables.
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
// host 3 fragments along with bottom navigation.
final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert navHostFragment != null;
final NavController navController = navHostFragment.getNavController();
NavigationUI.setupWithNavController(bottomNavigationView, navController);
// Make hourly & daily tab unusable
bottomNavigationView.setOnNavigationItemSelectedListener(item -> {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
}
return false;
});
navController.addOnDestinationChangedListener((controller, destination, arguments) -> navController.popBackStack(destination.getId(), false));
// For scheduling background image change
constraintLayout = findViewById(R.id.layout);
constraintLayout.setBackgroundResource(R.drawable.dubai);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// run on ui thread
runOnUiThread(() -> {
if (count < drawable.length) {
constraintLayout.setBackgroundResource(drawable[count]);
count = (count + 1) % drawable.length;
}
});
}
}, 5000, 5000);
Search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// make click sound when search button is clicked.
player = MediaPlayer.create(HomeActivity.this, R.raw.click);
player.start();
getWeatherData(textfield.getText().toString().trim());
// make use of some fragment's data
Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
if (currentFragment instanceof FirstFragment) {
FirstFragment firstFragment = (FirstFragment) currentFragment;
firstFragment.getWeatherData(textfield.getText().toString().trim());
} else if (currentFragment instanceof SecondFragment) {
SecondFragment secondFragment = (SecondFragment) currentFragment;
secondFragment.getWeatherData(textfield.getText().toString().trim());
} else if (currentFragment instanceof ThirdFragment) {
ThirdFragment thirdFragment = (ThirdFragment) currentFragment;
thirdFragment.getWeatherData(textfield.getText().toString().trim());
}
}
private void getWeatherData(String name) {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(#NonNull Call<Example> call, #NonNull Response<Example> response) {
try {
assert response.body() != null;
timeField.setVisibility(View.VISIBLE);
timeField.setText("First Updated:" + " " + response.body().getDt());
} catch (Exception e) {
timeField.setVisibility(View.GONE);
timeField.setText("First Updated: Unknown");
Log.e("TAG", "No City found");
Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NotNull Call<Example> call, #NotNull Throwable t) {
t.printStackTrace();
}
});
}
});
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.settings_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new Settings()).commit();
break;
case R.id.ads_upgrade_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new Upgrade()).commit();
break;
case R.id.privacy_policy_id:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
new Privacy_Policy()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
// Open/close drawer animation
}
}
}
In case you require any other code to look into the issue, please let me know. I'm just trying to avoid posting too much
EDIT:
My old bottomtabs nav graph:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/my_nav"
app:startDestination="#id/firstFragment">
<fragment
android:id="#+id/firstFragment"
android:name="com.viz.lightweatherforecast.FirstFragment"
android:label="fragment_first"
tools:layout="#layout/fragment_first" />
<fragment
android:id="#+id/secondFragment"
android:name="com.viz.lightpreciseweatherforecast.SecondFragment"
android:label="fragment_second"
tools:layout="#layout/fragment_second" />
<fragment
android:id="#+id/thirdFragment"
android:name="com.viz.lightpreciseweatherforecast.ThirdFragment"
android:label="fragment_third"
tools:layout="#layout/fragment_third" />
</navigation>
My new nav bar graph:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/bar_nav"
app:startDestination="#id/firstFragment">
<fragment
android:id="#+id/firstFragment"
android:name="com.viz.lightweatherforecast.FirstFragment"
android:label="fragment_first"
tools:layout="#layout/fragment_first" />
<fragment
android:id="#+id/settings_id"
android:name="com.viz.lightweatherforecast.Settings"
android:label="#string/settings"
tools:layout="#layout/settings" />
<fragment
android:id="#+id/ads_upgrade_id"
android:name="com.viz.lightweatherforecast.Upgrade"
android:label="#string/upgrade_to_remove_ads"
tools:layout="#layout/upgrade" />
<fragment
android:id="#+id/privacy_policy_id"
android:name="com.viz.lightweatherforecast.Privacy_Policy"
android:label="#string/privacy_policy"
tools:layout="#layout/privacy_policy"/>
</navigation>
You are using navigation architecture components, so the navController is the one that should control fragment transactions, you are doing that right with BottomNavigationView.
But within the navDrawer you are doing the transaction through the supportFragmentManager which should be done through the navController instead as both handle the navigation differently.
whenever I select an option on the menu(say settings), it displays the contents of the option along with the bottom navigation view
That is because the BottomNavView is a part of the activity, and you need to move it to a fragment; this requires to change the navigation design of your app; to do that change your app navigation like the below:
Main navigation:
<navigation
..... >
<fragment
android:name="......HomeFragment"/>
<fragment
android:name="......SettingFragment"/>
<fragment
android:name="......AdsUpgradeFragment"/>
<fragment
android:name="......PrivacyPolicyFragment"/>
</navigation>
The HomeFragment is the fragment that should hold the BottomNaviagtionView instead of the activity; and when you navigate to the SettingFragment, the navConroller will replace the entire fragment in the navHostFragment, and therefore the BottomNaviagtionView won't be shown.
my Activity's Toolbar contents which comprises of the nav hamburger
icon, the edittext and the search button(the activity hosting my 3
fragments) which spoils the app and makes it look very ugly
Unlike the BottomNaviagtionView, you can't do that with your toolBar that is used as the supportActionBar, because setting supportActionBar more than once in order to change its look; will duplicates it; so you have to accept a single toolbar; but instead you can hide/show the layout that holds the search button & the EditText whenever the destination changes:
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
LinearLayout searchBar = findViewById(R.id.searchbar); // change searchbar according to the layout id that holds the search button and the EditText
if (destination.getId() == R.id.nav_home) {
searchBar.setVisibility(View.VISIBLE);
} else {
searchBar.setVisibility(View.GONE);
}
});
and yes they currently exit the app when clicking back
To exit the app whenever, the bottom back button is pressed in any fragment use OnBackPressedDispatcher() within onCreateView() of those fragment (in your case SettingFragment, PrivacyPolicyFragment, & AdsUpgradeFragment):
And make sure that appBarConfiguration doesn't reference those fragments so, that the UP button can be shown instead of the burger.
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
// Exit the app when back is pressed
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
requireActivity().finishAndRemoveTask();
else requireActivity().finish();
}
});
Also, make sure that your setup the DrawerLayout & its navView in the navController with:
NavigationView navView = findViewById(....);
appBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home) // remove up button from all these fragments >> Keep the up/back button in R.id.settings_id, R.id.settings_id, ads_upgrade_id, privacy_policy_id
.setOpenableLayout(drawer)
.build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
And to make the Home fragment hidden by default in the navDrawer:
navView.getMenu().findItem(R.id.nav_home).setVisible(false); // adjust R.id.nav_home to yours
UPDATE
I currently have a single nav graph. The firstFragment represents the
today, 2nd - hourly and 3rd
I'm using is for my other weather tabs but the one you're suggesting
is for the navbar menu, should I replace yours with mine or just
create a new one for your suggestion?
You should use two navGraphs, the first is for the main navigation which I'd suggested; and the second is for the BottomNavigationView navigation which you already use; that is because we transferred the BottomNavigationView from the activity layout to the main/home fragment layout; and it' recommended the BottomNavigationView should have a separate navGraph;
So, you now need two FragmentContainerView; the first is in the activity layout which reference the navGraph provided in this answer, and the second is in the home fragment layout that references your original navGraph of the BottomNavigationView.
Sample:
I think I understood your problem very well (if I am not wrong). Thing is that what behavior you are getting right now is the normal scenario. You are using the same host activity to host both Navigation Drawer and Bottom Navigation fragments thus when you tried to navigate to another fragment from the same host the presence of the host's direct child view Bottom NavBar is showing. I think you can solve this problem in a few different but pretty simple logical ways.
(Not recommended) Using a different Activity for the Settings page. Just like startActivity(this, <some intent>). But in this way, you will end up creating lots of individual activities.
(Recommended) Using a common Navigation Host activity for navigating to independent pages/fragments. Like: Settings, Contact Us, etc. You can add different fragments into the common_nav_graph and set some actions with or without arguments for navigation. Just add the common_nav_graph as a nested graph inside your current one and set a simple argumented action. The arguments will help you to navigate desired pages/fragments without showing the bottom navigation bar.
Simply hide Bottom navigation when navigating to some fragments from your drawer.
My Android app has a navigation drawer with a menu. In the free version of the app, I want to have a menu item to allow the user to Upgrade to the paid version. Obviously I don't want this in the paid version.
How do I hide the menu item in the paid version?
The menu looks like this:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_home"
android:icon="#drawable/btn_home"
android:title="#string/nav_home"
/>
<item
android:id="#+id/action_acc_upgrade"
android:icon="#drawable/ic_star_black"
android:title="#string/str_acc_upgrade" />
<item
android:id="#+id/action_help"
android:icon="#drawable/ic_help_black"
android:title="#string/nav_help"
/>
</menu>
In the activity, I have:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = this.getMenuInflater();
inflater.inflate(R.menu.activity_main_drawer, menu);
if(isPaid()) {
MenuItem upgrade = menu.findItem(R.id.action_acc_upgrade);
upgrade.setVisible(false);
}
return true;
}
If I run this through the debugger, it reaches the line if(isPaid()) and then evaluates it as true, so goes into the setVisible part. The item still shows up in the menu, though.
I also tried removing the item from the menu instead of hiding it; the debugger shows that the item is removed, but then it still shows up when the menu is displayed.
How can I hide/remove this item?
Edit
I'm using a navigation drawer to hold the menu. This is set up in onCreate as follows:
// Set up toolbar
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Set up navigation drawer
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.nav_drawer_open, R.string.nav_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
I suspect that this somehow bypasses onPrepareOptionsMenu etc? Is there a way of adding a listener which is called when the "open navigation drawer" button is clicked? I can only find callbacks for the drawer being opened or closed, and they're called after the drawer has moved - I need to call them before.
You can do it in onCreate() of your activity:
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu navMenu = navigationView.getMenu();
navMenu.removeItem(R.id.action_acc_upgrade);
replace nav_view with your NavigationView's id.
There are several options:
The most convenient option: create 2 different productFlavours in your build.gradle file
productFlavors {
free {
...
}
paid {
...
}
}
And then override your menu file without action_acc_upgrade item for paid flavour.
If you want change visibility programmatically, try to use onPrepareOptionsMenu instead of onCreateOptionsMenu:
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
if(isPaid()) {
MenuItem upgrade = menu.findItem(R.id.action_acc_upgrade);
upgrade.setEnabled(false);
upgrade.setVisible(false);
}
}
If you need to change your menu after creation, invoke invalidateOptionsMenu().
You should override onPrepareOptionsMenu like this:
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
if(isPaid()) {
menu.findItem(R.id.action_settings).setVisible(false);
}
}
Notice:
Ensure get right value of isPaid() before onPrepareOptionsMenu callback, such as in onCreate() or onResume().
If it's on the fly, you need to override onPrepareOptionsMenu and call invalidateOptionsMenu if applicable:
#Override public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.action_acc_upgrade).setVisible(!isPaid());
}
See Activity.onPrepareOptionsMenu:
Prepare the Screen's standard options menu to be displayed. This is
called right before the menu is shown, every time it is shown. You can
use this method to efficiently enable/disable items or otherwise
dynamically modify the contents.
I am trying to make an app in which there will be a spinner with several values. A button will print that value in a text holder.
But, as you can see in the code bellow, the program cannot resolve the symbols "Teste1" and "Teste2".
Spinner merendas;
String[] morfes = {"Teste1","Teste2"};
ArrayAdapter <String> adapter;
merendas = (Spinner)findViewById(R.id.merendas);
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,morfes);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
merendas.setAdapter(adapter);
merendas.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long morfes) {
switch (position){
case 0:
morfes = Teste1;
break;
case 1:
morfes = Teste2;
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
Thanks for your time.
A button will print that value in a text holder.
If you want to print which spinner item is selected , You don't need setOnItemSelectedListener() for your spinner.
You can simply use
String selected = spinner.getSelectedItem().toString();
yourtextview.setText(selected);
So I'm kind of on the new side with Android Studio and Android programming as a whole. I'm currently working on an app that (where one of the features) will pull a user's profile picture from Facebook for example, and change the ImageView in the Navigation Drawer accordingly (for example on the Gmail app where it shows your G+ profile picture). The Facebook bit can be left for another day, however I've been stuck with a certain issue for the past 2 and a half hours, and might need some assistance. My onCreate method looks like the following:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View headerView = navigationView.inflateHeaderView(R.layout.nav_header_main);
imgProfilePic = (ImageView) headerView.findViewById(R.id.imgProfilePic);
imgProfilePic.setImageResource(R.drawable.troll_face);
}
A lot of my onCreate method is still pretty "vanilla", the bit where I think the issue lies is before NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);. My main issue I'm experiencing here is that 2 headers now show up below each other in my Navigation Drawer, the regular one before the .setImageResource() was done, and the one (where the resource was changed) after it.
I have done a lot of Googling with regards to this issue, and some people mentioned it was due to a bug in Android Studio.
Any assistance with my problem would be greatly appreciated.
In my application I show picture in this way:
if (mNavigationView.getHeaderCount() > 0) {
ImageView mBackground = (ImageView) mNavigationView.getHeaderView(0).findViewById(R.id.user_background);
CircleImageView mUserIcon = (CircleImageView) mNavigationView.getHeaderView(0).findViewById(R.id.user_icon);
Glide.with(this).load(R.drawable.background).centerCrop().into(mBackground);
Glide.with(this).load(R.drawable.me).centerCrop().into(mUserIcon);
}
The important thing that I'd advise for you is using Glide even for settings the picture from resources. This library compresses the picture size and thus makes your app work much faster.
About the question - you have to look for the first and only header. That's the trick in this issue :)
I am new to android and I am trying to learn by making a simple chat app in android studio.
I started by creating a navigation drawer. Now I want to add tabs to my app like this - chats / contact / calls below navigation drawer, but I could not find a simple step by step tutorial for doing this.
Before I started this chat app I worked on a simpler app and added some tabs to that old app like this:
public class MainActivity extends TabActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Resources resources = getResources();
TabHost tabHost = getTabHost();
// First tab
Intent intentTabOne = new Intent().setClass(this, TabOneActivity.class);
TabSpec tabSpecTabOne = tabHost
.newTabSpec("Tab One")
.setIndicator("", resources.getDrawable(R.drawable.icon_one_config))
.setContent(intentTabOne);
// Second tab
Intent intentTabTwo = new Intent().setClass(this, TabTwoActivity.class);
TabSpec tabSpecSecondTab = tabHost
.newTabSpec("Tab Two")
.setIndicator("", resources.getDrawable(R.drawable.icon_two_config))
.setContent(intentTabTwo);
// Third tab
Intent intentTabThree = new Intent().setClass(this, TabThree.class);
TabSpec tabSpecSent = tabHost
.newTabSpec("Tab Three")
.setIndicator("", resources.getDrawable(R.drawable.icon_three_invitations_config))
.setContent(intentTabThree);
// add all tabs
tabHost.addTab(tabSpecTabOne);
tabHost.addTab(tabSpecTabTwo);
tabHost.addTab(tabSpecTabThree);
//set Windows tab as default
tabHost.setCurrentTab(0);
}
But now my main activity looks like this:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed()...
Also, since TabActivity is now deprecated and I think I should use fragment, I got a little bit lost. I would really appreciate if someone could point me in the right direction. Thanks in advance.
I'd suggest to use a TabLayout that you can put below your Toolbar/Actionbar, so you can use it in parallel with the navigation drawer.
This answer shows how setup the Tabbar with a ViewPager. In short: You need to include the Design Support Library to use the TabLayout. In your XML layout, put the TabLayout and the ViewPager somewhere below the Toolbar, such that it fits your intentions. Then you can setup the different tabs with their own Fragments in your Activity.