Android Navigation Component 'Up button' opens drawer navigation - android-actionbar

I am trying to implement a simple navigation using Navigation Component with navigation graph and navigation controller.
I have my MainActivity with actionbar with hamburger icon and app title, a drawer navigation and content area.
Content area is where I display different fragments.
Content area is first loaded with my homescreenFragment containing 4 buttons (news, events, timetable, profile) - each of them loads fragment into my MainActivity's Content area.
It works fine, the only problem is the following:
When I press news button and navigate from my homescreen to my NewsFragment it loads fragment OK and changes actionbar title to News. Hamburger icon is changed to 'Up button' icon, but when I press on it, application opens Navigation Drawer as if I press on the hamburger icon instead of navigating me back to the home screen.
How do I make Up button to go up and not showing left navigation drawer ?
here is my MainActivity.java:
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
public class MainActivity extends AppCompatActivity {
Toolbar m_toolbar;
DrawerLayout m_drawer;
ActionBarDrawerToggle m_toggle;
NavigationView m_navigationView;
NavController m_navController;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_toolbar = findViewById(R.id.toolbar);
setSupportActionBar(m_toolbar);
m_drawer = findViewById(R.id.drawer_layout);
m_navigationView = findViewById(R.id.nav_drawer_view);
m_navController = Navigation.findNavController(this, R.id.content);
m_toggle = new ActionBarDrawerToggle(
this, m_drawer, m_toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
m_drawer.addDrawerListener(m_toggle);
//m_toggle.syncState();
//connect actionbar icon and drawer with nav controller
NavigationUI.setupWithNavController(m_navigationView, m_navController);
NavigationUI.setupActionBarWithNavController(this, m_navController);
NavigationUI.setupActionBarWithNavController(this, m_navController, m_drawer);
}
#Override
public boolean onSupportNavigateUp() {
return Navigation.findNavController(this, R.id.nav_drawer_view).navigateUp() || super.onSupportNavigateUp();
}
#Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<LinearLayout
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/nav_graph"
app:defaultNavHost="true"/>
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_drawer_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
navigation 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/nav_graph"
app:startDestination="#id/homeScreenFragment">
<fragment
android:id="#+id/homeScreenFragment"
android:name="com.mysample.meganews.Fragments.HomeScreenFragment"
android:label="#string/app_name"
tools:layout="#layout/home_screen_fragment" >
<action
android:id="#+id/action_to_news"
app:destination="#id/newsFragment"
app:enterAnim="#anim/nav_default_enter_anim"
app:exitAnim="#anim/nav_default_exit_anim" />
<action
android:id="#+id/action_to_events"
app:destination="#id/eventsFragment"
app:enterAnim="#anim/nav_default_pop_enter_anim"
app:exitAnim="#anim/nav_default_pop_exit_anim" />
</fragment>
<fragment
android:id="#+id/newsFragment"
android:name="com.mysample.meganews.Fragments.NewsFragment"
android:label="#string/hs_title_news"
tools:layout="#layout/news_fragment" />
<fragment
android:id="#+id/eventsFragment"
android:name="com.mysample.meganews.Fragments.EventsFragment"
android:label="events_fragment"
tools:layout="#layout/events_fragment" />
</navigation>
HomeScreenFragment.java file:
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
/**
* A simple {#link Fragment} subclass.
*/
public class HomeScreenFragment extends Fragment {
public HomeScreenFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.home_screen_fragment, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RelativeLayout rl_news = view.findViewById(R.id.ll_news_btn);
RelativeLayout rl_events = view.findViewById(R.id.ll_events_btn);
rl_news.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_to_news));
rl_events.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_to_events));
}
}
build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.mysample.meganews"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'android.arch.lifecycle:extensions:1.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'android.arch.navigation:navigation-fragment:1.0.0-alpha11'
implementation 'android.arch.navigation:navigation-ui:1.0.0-alpha11'
}

This problem was due to mixing of different APIs . Here is the right code:
activity_main.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark" />
<fragment
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/nav_graph"
app:defaultNavHost="true"/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_drawer_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
MainActivity.java:
import android.os.Bundle;
import com.google.android.material.navigation.NavigationView;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProviders;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
import android.view.MenuItem;
import android.view.ViewParent;
public class MainActivity extends AppCompatActivity
{
private Toolbar mToolbar;
private DrawerLayout mDrawer;
private ActionBarDrawerToggle mToggle;
private NavigationView mNavigationView;
private NavController mNavController;
private MainViewModel mViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
setupNavigation();
}
private void setupNavigation()
{
mToolbar = findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawer = findViewById(R.id.drawerLayout);
mNavigationView = findViewById(R.id.nav_drawer_view);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// // we need this line to handle the navigation
// boolean handled = NavigationUI.onNavDestinationSelected(menuItem, mNavController);
// if (handled) {
// ViewParent parent = mNavigationView.getParent();
// if (parent instanceof DrawerLayout) {
// ((DrawerLayout) parent).closeDrawer(mNavigationView);
// }
// }
return true;
}
});
mNavController = Navigation.findNavController(this, R.id.content);
NavigationUI.setupActionBarWithNavController(this, mNavController, mDrawer);
// Tie nav graph to items in nav drawer
NavigationUI.setupWithNavController(mNavigationView, mNavController);
}
#Override
public boolean onSupportNavigateUp() {
//return Navigation.findNavController(this, R.id.content).navigateUp();
//return mNavController.navigateUp() || super.onSupportNavigateUp();
return NavigationUI.navigateUp(mNavController, mDrawer);
}
#Override
public void onBackPressed() {
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}

I had the same issue and fixed it with below workaround.
mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
#Override
public void onDestinationChanged(#NonNull NavController controller,
#NonNull NavDestination destination, #Nullable Bundle arguments) {
if (mAppBarConfiguration.getTopLevelDestinations().contains(destination.getId())) {
mToggle.setDrawerIndicatorEnabled(true);
} else {
mToggle.setDrawerIndicatorEnabled(false);
}
}
});
Also make sure to set the click listener to ActionBarDrawerToggle as below.
mToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mActivity.onBackPressed();
}
});

Navigation handle this by default you do not have to explicitly handle listener for this.
In your activity override "onSupportNavigationUp"
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController, drawer_layout)
}
and do above. It will handle back button and hamburger icon by default.

Related

How to replace one fragment with another on button click in Xamarin.Android?

I want to have the following screen:
When I click IMAGE 1 and IMAGE 2 buttons I want in IMAGE ZONE to appear Image1.jpg and Image2.jpg respectively. I want Image1.jpg and Image2.jpg to be in different fragments and replace those fragments on button click rather than changing simply the android:src of the ImageView in IMAGE ZONE on button click. I want Image1.jpg to be the first image to appear when opening the activity. I can't find how to do that with fragments in Xamarin.Android
You can create two Fragment and its xml first.
FragmentOne :
public class Fragment1 : Android.Support.V4.App.Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
return inflater.Inflate(Resource.Layout.layoutFragment1, container, false);
//return base.OnCreateView(inflater, container, savedInstanceState);
}
}
and its xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment1">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/th2"/>
</LinearLayout>
FragementTwo :
public class Fragment2 : Android.Support.V4.App.Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
return inflater.Inflate(Resource.Layout.layoutFragment2, container, false);
//return base.OnCreateView(inflater, container, savedInstanceState);
}
}
and its xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment2">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/th2"/>
</LinearLayout>
Then in MainActivity , you can set its xml as follow :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="80dip"
android:orientation="horizontal">
<Button
android:id="#+id/buttonone"
android:layout_width="150dip"
android:layout_height="80dip"
android:text="FragmentOne"/>
<Button
android:id="#+id/buttontwo"
android:layout_width="150dip"
android:layout_height="80dip"
android:text="FragmentTwo"/>
</LinearLayout>
<RelativeLayout
android:id="#+id/containerView"
android:layout_width="match_parent"
android:layout_height="430dip">
</RelativeLayout>
</LinearLayout>
Finally , in MainActivity.cs implement this function :
public class MainActivity : AppCompatActivity
{
Android.Support.V4.App.Fragment fragmentOne;
Android.Support.V4.App.Fragment fragmentTwo;
Android.Support.V4.App.FragmentTransaction fragmentManager;
[Obsolete]
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Button buttonone = FindViewById<Button>(Resource.Id.buttonone);
buttonone.Click += Buttonone_Click;
Button buttontwo = FindViewById<Button>(Resource.Id.buttontwo);
buttontwo.Click += Buttontwo_Click;
fragmentOne = new Fragment1();
fragmentTwo = new Fragment2();
fragmentManager = SupportFragmentManager.BeginTransaction();
fragmentManager.Add(Resource.Id.containerView, fragmentOne);
//adding first fragment when entering activity
fragmentManager.Commit();
}
private void Buttonone_Click(object sender, System.EventArgs e)
{
//throw new System.NotImplementedException();
Console.WriteLine("Buttonone_Click");
fragmentManager = SupportFragmentManager.BeginTransaction();
// replace to be the first fragment
fragmentManager.Replace(Resource.Id.containerView, fragmentOne);
fragmentManager.Commit();
}
private void Buttontwo_Click(object sender, System.EventArgs e)
{
//throw new System.NotImplementedException();
Console.WriteLine("Buttontwo_Click");
fragmentManager = SupportFragmentManager.BeginTransaction();
// replace ro be the second fragment
fragmentManager.Replace(Resource.Id.containerView, fragmentTwo);
fragmentManager.Commit();
}
}
The effect as follow :

App crash with actionbar

i'm new on Android. I'm trying to implent an actionbar im my activity. Everytime i run that, the app crash.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_percorsodisabili);
//Option Bar
getSupportActionBar().setTitle("Percorso Bici");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Resources res = getResources();
myVist3 = (ListView) findViewById(R.id.myVist3);
items = res.getStringArray(R.array.nomi_percorsi3);
descriptions = res.getStringArray(R.array.desc_percorsi3);
content = res.getStringArray(R.array.desc_percorsi3);
ItemAdapter itemAdapter = new ItemAdapter(percorsodisabili.this, items,foto,descriptions,content);
myVist3.setAdapter(itemAdapter);
}
}
Add the toolbar to your activity layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="wrap_content"
android:layout_height="56dp" />
<RelativeLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar">
<!--YOUR LAYOUT CODE-->
</RelativeLayout>
Then initialize java code for activity:
Use android.support.v7.widget.Toolbar in case you are using AppCompactActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
Toolbar toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}

5 BUTTONS for one action

I required some assistance on the code, I manage to to create this the code for 5 button and one action, however i run on the phone it does when I clicked on the button.
Can some advise me why?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.android.testing1.MainActivity"
tools:showIn="#layout/activity_main">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="104dp"
android:layout_marginTop="20dp"
android:text="Button1"
/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="100dp"
android:text="Button2" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="Button3" />
<Button
android:id="#+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="34dp"
android:text="Button4" />
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="24dp"
android:text="Button5" />
</RelativeLayout>
package com.example.android.testing1;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import static android.R.id.button1;
import static android.R.id.button2;
import static android.R.id.button3;
import static com.example.android.testing1.R.id.button4;
import static com.example.android.testing1.R.id.button5;
public class MainActivity extends AppCompatActivity {
Button b1, b2, b3, b4, b5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button dodo = (Button) findViewById(button1);
Button dede = (Button) findViewById(button2);
Button dada = (Button) findViewById(button3);
Button didi = (Button) findViewById(button4);
Button hehe = (Button) findViewById(button5);
return;
}
//boolean fafa, soso, raerae, gaga, gege;
public void main(Button args[]) {
final boolean fafa = true;
final boolean soso = true;
final boolean raerae = true;
final boolean gaga = true;
final boolean gege = true;
boolean returrn;
OnClickListener list = new OnClickListener() {
#Override
public void onClick(View v) {
if (fafa == true && soso == true && raerae == true && gaga == true && gege == true) {
Toast GetMeToast = Toast.makeText(MainActivity.this, "Open all buttons", Toast.LENGTH_SHORT);
GetMeToast.show();
}
}
};
}}
I tried to run the code above but was jammed once i clicked the button.
I am new to java. Required some assistance, what i need is that by clicking all the 5 buttons then the toast will appear.
I have tried many way it does not work. I think by creating a Boolean and if method can help me with this.

Cannot remove Padding from Tabs when using Custom views with Tab Layout

I have added a Relative Layout in Custom View and have added this in Tab Layout. I am using a white background for tabs and have not applied any padding in tabs custom layout. But then also I am getting padding on tabs due to which I am shown some grey background within tabs as if android is internally applying padding to tabs. I am trying to display three text views which I am able to do but one of them is truncating because of padding applied to tabs. Also I want to have consistent background color for tabs.
Here is my code:
activity_home.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.customtablayoutapplication.HomeActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_home" />
</android.support.design.widget.CoordinatorLayout>
fragment_home.xml:
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:theme="#style/AppTheme.AppBarOverlay"
tools:context="com.customtablayoutapplication.HomeFragment"
tools:showIn="#layout/activity_home">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabMode="fixed" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</LinearLayout>
custom_tab.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="#android:color/white"
android:layout_height="match_parent"
android:layout_gravity="center">
<TextView
android:id="#+id/total_request_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="12"
android:textAllCaps="false"
android:visibility="gone"
android:textColor="#color/colorPrimaryDark"
android:textSize="12sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:fitsSystemWindows="true"
android:gravity="center">
<TextView
android:id="#+id/request_status"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="New Request"
android:textAllCaps="false"
android:textColor="#color/colorPrimaryDark"
android:textSize="12sp" />
<TextView
android:id="#+id/badge_icon"
android:layout_width="13dp"
android:layout_height="13dp"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/request_status"
android:layout_marginLeft="-3dp"
android:layout_marginTop="15dp"
android:background="#drawable/circular_text_background"
android:clickable="false"
android:visibility="gone" />
</RelativeLayout>
</RelativeLayout>
HomeFragment.java:
package com.customtablayoutapplication;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* A placeholder fragment containing a simple view.
*/
public class HomeFragment extends Fragment {
private ViewPager viewPager;
private TabLayout tabLayout;
public HomeFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setUpTabIcons();
return view;
}
private void setUpTabIcons() {
RelativeLayout tabNewRequest= (RelativeLayout) LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
TextView tabNewRequesttxt = (TextView) tabNewRequest.findViewById(R.id.request_status);
tabNewRequesttxt.setText("New Request");
tabLayout.getTabAt(0).setCustomView(tabNewRequest);
RelativeLayout tabInProgress= (RelativeLayout) LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
TextView tabInProgresstxt = (TextView) tabInProgress.findViewById(R.id.request_status);
tabInProgresstxt.setText("In Progress");
tabLayout.getTabAt(1).setCustomView(tabInProgress);
RelativeLayout tabWorkDone= (RelativeLayout) LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
TextView tabWorkDonetxt = (TextView) tabWorkDone.findViewById(R.id.request_status);
tabWorkDonetxt.setText("Work Done");
tabLayout.getTabAt(2).setCustomView(tabWorkDone);
RelativeLayout tabDelivered= (RelativeLayout) LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
TextView tabDeliveredtxt = (TextView) tabDelivered.findViewById(R.id.request_status);
tabDeliveredtxt.setText("Delivered");
tabLayout.getTabAt(3).setCustomView(tabDelivered);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new NewRequestFragment(), "New Request");
adapter.addFragment(new InProgressFragment(), "In Progress");
adapter.addFragment(new WorkDoneFragment(), "Work Done");
adapter.addFragment(new DeliveredFragment(), "Delivered");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
Fixed Tab are having grey background arround white background:
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="210dp"
android:layout_height="28dp"
android:layout_centerInParent="true"
android:background="#drawable/bg_forum_tab"
app:tabIndicatorColor="#color/colorBtnBg"
app:tabIndicatorHeight="0dp"
app:tabPaddingBottom="-1dp"
app:tabPaddingEnd="-1dp"
app:tabPaddingStart="-1dp"
app:tabPaddingTop="-1dp"
app:tabSelectedTextColor="#color/colorBtnBg"
app:tabTextColor="#color/colorWhite" />
Set tabPaddingStart/tabPaddingEnd/tabPaddingTop/tabPaddingBottom like this.
It worked for me:
In your TabLayout you have to set tabPaddingEnd and tabPaddingStart to 0dp.
In your custom view you have to set the layout_width and layout_height to match_parent in order to fill all space with your custom color.
The TabLayout:
<android.support.design.widget.TabLayout
android:id="#+id/tl_dashboard"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentBottom="true"
app:tabGravity="fill"
app:tabIndicatorColor="#color/colorRed"
app:tabMode="fixed"
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"/>
And custom view:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Your widgets-->
</RelativeLayout>
Through XML you can remove only the left and right paddings like that:
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp"
Notice, that this way doesn`t work for TOP and BOTTOM paddings, but I find next solution:
When you use custom views as tab item, you need to set LayoutParams to the view and set paddings 0.
for (int i = 0; i < tabLayout.getTabCount(); i++) {
View tabView = LayoutInflater.from(context)
.inflate(LayoutInflater.from(this), R.layout.item_main_tabview, null, false);
tabView.setLayoutParams(new TableLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
tabView.setPadding(0, 0, 0, 0);
tabLayout.getTabAt(i).setCustomView(tabViewBinding.getRoot());
}
I solved this by setting the margin & padding of your custom view's parent to zero, when adding new tabs to tab layout.
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(0,0,0,0);
TabLayout.Tab newTab = mTabsBottom.newTab().setCustomView(R.layout.view_custom_tab);
setupTabParentLayout(newTab.getCustomView(), lp);
..
..
..
private void setupTabParentLayout(View customView, LinearLayout.LayoutParams lp) {
LinearLayout tabParent = (LinearLayout) customView.getParent();
tabParent.setLayoutParams(lp);
tabParent.setPadding(0,0,0,0);
}
Trick here was to use LinearLayout.LayoutParams for custom view's parent.
I know this is an old question but this can help someone else. Padding start and padding end is not removing space between tabs. Solution is :
android:clipToPadding="true"
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#color/colorGrayBackground"
app:tabGravity="fill"
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"
app:tabContentStart="0dp"
app:tabIndicatorHeight="0dp"
android:clipToPadding="true"
app:tabMode="fixed" />
Then you can set paddings to "0dp". Hope it helps someone.
In case you have tried many things and none of them did work, here is what I ended up doing: just setting
android:layout_height="20dp
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:layout_gravity="bottom"
android:layout_height="130dp"/>
<com.google.android.material.tabs.TabLayout
android:layout_height="20dp"
android:layout_width="match_parent"
android:layout_gravity="bottom"
app:tabBackground="#drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"/>
</FrameLayout>
I create TabLayout from code and me help only this
for (int position = 0; position < mTabLayout.getTabCount(); position++) {
TabLayout.Tab tab = mTabLayout.getTabAt(position);
if (tab != null) {
ViewCompat.setPaddingRelative(tab.view, 0, 0, 0, 0);
}
}
<android.support.design.widget.TabLayout
android:id="#+id/tabview"
app:layout_constraintTop_toBottomOf="#+id/ivpromo"
android:layout_width="0dp"
app:tabMode="scrollable"
app:tabIndicatorHeight="0dp"
app:tabContentStart="0dp"
android:clipToPadding="true"
app:tabMaxWidth="45dp"
app:tabGravity="fill"
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:tabIndicatorColor="#android:color/transparent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="#+id/tvcode"
android:layout_height="40dp"/>
First of all I've tried to use app:tabMinWidth="0dp"
Then I've tried dcanbatman's answer.
And it started to work only with both of these solutions:
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"
app:tabMinWidth="0dp"

How to add action bar to a DialogFragment?

How to add action bar to a DialogFragment? I found a way to style an activity to the way we require and then display it as a dialog as in the following link ActionBar in a DialogFragment I need to set an action bar on a proper DialogFragment. Is it possible?
As Up ActionBar action on DialogFragment
indicates: There is no way to attach an ActionBar to the DialogFragment even though you can set the theme of the DialogFragment it will not register as a ActionBar to it, Dialog.getActionBar() will always return null.
But there's always the cases that I really want to use DialogFragment(which contain ActionBar like style) instead of Activity. Just add a Layout that will look like an ActionBar into the DialogFragment's Layout
the following is the steps:
1) DialogFragment layout: about_dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/white" >
<include android:id="#+id/fake_action_bar"
layout="#layout/fake_action_bar_with_backbotton" />
2) Implement a ActionBar like layout: fake_action_bar_with_backbotton.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/fake_action_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
app:navigationIcon="#drawable/ic_menu_back"
android:background="#color/background_material_dark"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
Note: the #drawable/ic_menu_back is copied from sdk\platforms\android-21\data\res\drawable-hdpi
3) Update the DialogFragment code
public class AboutDialogFragment extends DialogFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// use Theme_Holo_Light for full screen
// use Theme_Holo_Dialog for not full screen
// first parameter: DialogFragment.STYLE_NO_TITLE no title
setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo_Light_DarkActionBar);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.about_dialog, container, false);
// set the listener for Navigation
Toolbar actionBar = (Toolbar) v.findViewById(R.id.fake_action_bar);
if (actionBar!=null) {
final AboutDialogFragment window = this;
actionBar.setTitle(R.string.about_title);
actionBar.setNavigationOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
window.dismiss();
}
});
}
return v;
}
}
Wish it can help!