I set swipe tab view on activity which is works fine but the problem is the Action bar of activity get disappeared while it was appeared before tab view. Please guide me how to again appear action bar at the top of tab view.
MainActivity:
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the view from activity_main.xml
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(myToolbar);
// Locate the viewpager in activity_main.xml
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
((ViewPager.LayoutParams) (findViewById(R.id.tab_strip)).getLayoutParams()).isDecor = true;
// Set the ViewPagerAdapter into ViewPager
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
}
}
Tab1: simlar for tab2 and tab3
public class FragmentTab1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Get the view from fragmenttab1.xml
View view = inflater.inflate(R.layout.fragmenttab1, container, false);
return view;
}
}
ViewPageAdapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
// Tab Titles
private String tabtitles[] = new String[] { "Tab1", "Tab2", "Tab3" };
Context context;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
switch (position) {
// Open FragmentTab1.java
case 0:
FragmentTab1 fragmenttab1 = new FragmentTab1();
return fragmenttab1;
// Open FragmentTab2.java
case 1:
FragmentTab2 fragmenttab2 = new FragmentTab2();
return fragmenttab2;
// Open FragmentTab3.java
case 2:
FragmentTab3 fragmenttab3 = new FragmentTab3();
return fragmenttab3;
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
return tabtitles[position];
}
}
Styles.xml:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="windowActionBar">true</item>
<item name="windowNoTitle">false</item>
</style>
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.zohaibsiddique.myapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.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.support.v7.widget.Toolbar
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="10dp"
app:theme="#style/ThemeOverlay.AppCompat.Dark"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:minHeight="?attr/actionBarSize" />
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tab_strip"
android:layout_gravity="top"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:textColor="#000000" />
</android.support.v4.view.ViewPager>
</LinearLayout>
Add the PagerTabStrip to display page title :
<android.support.v4.view.ViewPager
android:id="#+id/vpPager"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.view.PagerTabStrip
android:id="#+id/pager_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="4dp"
android:paddingTop="4dp" />
</android.support.v4.view.ViewPager>
For more details, please see this link:
https://github.com/codepath/android_guides/wiki/ViewPager-with-FragmentPagerAdapter
I resolves my problem by myself. I just extends MainActivity to AppCompatActivity and re-appear action bar.
Related
Please teach me how to add navigation drawer in this activity.
MainActivity (Tab Layout)
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
assert tabLayout != null;
tabLayout.addTab(tabLayout.newTab().setText(R.string.welcome));
tabLayout.addTab(tabLayout.newTab().setText(R.string.venue));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager()) {
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new WelcomeFragment();
case 1:
return new pptp();
}
return null;
}
#Override
public int getCount() {
return 2;
}
};
assert viewPager != null;
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
public void refreshNow() {
finish();
overridePendingTransition(0,0);
startActivity(getIntent());
overridePendingTransition(0,0);
}
}
Teach me how to add navigation drawer it will helps me a lot.
Thank you in advance for those who willing to help me.
add the following dependencies to your apps module's build.gradle file:
dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support:design:27.0.2'
}
Inside the DrawerLayout, add a layout for the main content for the UI (your primary layout when the drawer is hidden) and another view that contains the contents of the navigation drawer.
For example, the following layout uses a DrawerLayout with two child views: a FrameLayout to contain the main content (which could, for example, by populated by a Fragment at runtime), and a NavigationView for the contents of the navigation drawer.
<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true" />
</android.support.v4.widget.DrawerLayout>
To configure the menu items listed in the drawer, specify a menu resource with the app:menu attribute, as shown in the example code below:
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_view" />
Create the menu resource with the corresponding file name. For example, at res/menu/drawer_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_camera"
android:icon="#drawable/ic_menu_camera"
android:title="#string/import" />
<item
android:id="#+id/nav_gallery"
android:icon="#drawable/ic_menu_gallery"
android:title="#string/gallery" />
<item
android:id="#+id/nav_slideshow"
android:icon="#drawable/ic_menu_slideshow"
android:title="#string/slideshow" />
<item
android:id="#+id/nav_manage"
android:icon="#drawable/ic_menu_manage"
android:title="#string/tools" />
</group>
</menu>
I have a Bottom Navigation View with 4 items.
I wish to set the items in the middle of each bottom navigation view button and I have found a method but it works only when the application starts.
After I select another item, every icon moves up and I don't know why they are not keeping their position.
public class MainActivity extends AppCompatActivity{
private Toolbar mToolbar;
private BottomNavigationView bottomNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.customToolbar);
setSupportActionBar(mToolbar);
setTitle("");
mToolbar.setNavigationIcon(R.mipmap.back_icon);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
BottomNavigationViewShiftDisable.disableShiftMode(bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.profile:
fragment = new FirstFragment();
break;
case R.id.friends:
fragment = new SecondFragment();
break;
case R.id.circle:
fragment = new ThirdFragment();
break;
case R.id.settings:
fragment = new ForthFragment();
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, fragment);
transaction.commit();
setMenuIconsInMiddle(bottomNavigationView);
return true;
}
});
bottomNavigationView.setSelectedItemId(R.id.profile);
}
/**
* This method is used to set margins for all the icons in the menu that is used in the
* bottom navigation view.
* #param navigationView an instance of the Bottom navigation view that holds the menu with
* the icons.
*/
public void setMenuIconsInMiddle(BottomNavigationView navigationView){
BottomNavigationMenuView menuView = (BottomNavigationMenuView)navigationView.getChildAt(0);
for(int index = 0; index <menuView.getChildCount(); index++){
final View iconView = menuView.getChildAt(index).findViewById(android.support.design.R.id.icon);
final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)iconView.getLayoutParams();
layoutParams.setMargins(0,50,0,0);
navigationView.requestLayout();
}
}
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hermes.profilescreen.MainActivity">
<include layout="#layout/custom_toolbar"/>
<include layout="#layout/bottom_navigation"/>
</RelativeLayout>
bottom_nav_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="#+id/profile"
android:enabled="true"
android:icon="#drawable/ic_people_outline_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/friends"
android:enabled="true"
android:icon="#drawable/ic_person_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/circle"
android:enabled="true"
android:icon="#drawable/ic_panorama_fish_eye_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/settings"
android:enabled="true"
android:icon="#drawable/setting_white"
app:showAsAction="ifRoom"
android:title=""
/>
</menu>
bottom_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frame_layout"
android:layout_above="#+id/bottom_navigation"
>
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/light_black"
app:itemBackground="#drawable/set_backgorund"
app:itemIconTint="#color/item_state"
app:menu="#menu/bottom_nav_main"
/>
</RelativeLayout>
call setMenuIconsInMiddle on a thread. try this:-
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
//your code here
...
...
...
//Looper.getMainLooper() runs on main thread
new Handler(Looper.getMainLooper()).post(new Runnable(){
#Override
public void run() {
setMenuIconsInMiddle(bottomNavigationView);
}
});
return true;
}
});
this is working for me...
I have an Activity with a NoActionBar theme containing a ViewPager, I set it up like so:
public class MainActivity extends AppCompatActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
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();
}
});
}
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Intent i = new Intent(this, SettingsActivity.class);
startActivity(i);
return true;
case R.id.action_refresh_token:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
//return PlaceholderFragment.newInstance(position + 1);
switch (position){
case 0:
return CustomFragment.newInstance();
}
return PlaceholderFragment.newInstance(0);
}
#Override
public int getCount() {
// Show 3 total pages.
return 1;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
}
return null;
}
}
}
This is the layout:
<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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
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:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_dialog_email"/>
</android.support.design.widget.CoordinatorLayout>
And then I have a fragment to put into the viewpager:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity$PlaceholderFragment">
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
Everytime I open the fragment in Android Studio, I get the following exception:
java.lang.ClassCastException: android.support.v7.widget.ActionBarOverlayLayout cannot be cast to android.support.v7.internal.widget.ActionBarOverlayLayout
at android.support.v7.internal.app.WindowDecorActionBar.init(WindowDecorActionBar.java:196)
at android.support.v7.internal.app.WindowDecorActionBar.<init>(WindowDecorActionBar.java:192)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.jetbrains.android.uipreview.ViewLoader.createNewInstance(ViewLoader.java:465)
at org.jetbrains.android.uipreview.ViewLoader.loadClass(ViewLoader.java:172)
at org.jetbrains.android.uipreview.ViewLoader.loadClass(ViewLoader.java:150)
at com.android.tools.idea.rendering.LayoutlibCallbackImpl.loadView(LayoutlibCallbackImpl.java:184)
at com.android.layoutlib.bridge.bars.AppCompatActionBar.<init>(AppCompatActionBar.java:89)
at com.android.layoutlib.bridge.impl.Layout.createActionBar(Layout.java:238)
at com.android.layoutlib.bridge.impl.Layout.<init>(Layout.java:150)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:301)
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:429)
at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:389)
at com.android.tools.idea.rendering.RenderTask$2.compute(RenderTask.java:548)
at com.android.tools.idea.rendering.RenderTask$2.compute(RenderTask.java:533)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:966)
at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:533)
at com.android.tools.idea.rendering.RenderTask.lambda$inflate$72(RenderTask.java:659)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
But If I start a Tabbed project from Android Studio, I dont get this even though the code seems to be the same (in fact, I copied the code from this project).
Styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
</resources>
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.camerawizard.demoapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity>
<android:name=".SettingsActivity">
<android:label="#string/title_activity_settings">
<android:parentActivityName=".MainActivity">
</activity>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</application>
</manifest>
I have tabs in my app. Each tab is of different fragments and has different menu. Below is the layout which I am using
<?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"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background">
<include
layout="#layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
<com.CustomViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:background="#color/background"
app:layout_anchor="#id/view_pager"
app:layout_anchorGravity="bottom|center_horizontal"
app:layout_behavior="com.widget.ScrollTabBehavior"
app:tabBackground="#color/background"
app:tabIndicatorColor="#color/toolbar"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp" />
</android.support.design.widget.CoordinatorLayout>
<RelativeLayout
android:id="#+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_marginLeft="-64dp"
android:layout_marginStart="-64dp"
android:background="#color/toolbar"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp">
<ImageButton
android:id="#+id/close_btn"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#android:color/transparent"
android:padding="5dp"
android:src="#drawable/close_icon" />
<view
android:id="#+id/drawerlist"
class="android.support.v7.widget.RecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/close_btn" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
Now with every Fragment in onCreate() I have mentioned setHasOptionsMenu(true); further more. I have overriden the function onCreateOptionsMenu() in each fragment which has menu.clear(); at first then calling it's super constructor then inflating fragment's own menu xml. But result I am getting is something like this -
Suppose there are 5 tabs. 2nd and 3rd tab has viewpager within each consist of two more fragments within
1st tab has no menu
2nd tab has menu_2 (only for 2nd child fragment)
3rd tab again has no menu
4th tab has menu_4 (only for 1st child fragment)
5th tab has menu_5
Initially, there should be no menu for tab 1 which is ok. Then moving to 3rd tab directly it shows menu_4 which by default should show no menu. Then sliding to tab 4, it will show proper menu_4 then sliding back to 3rd tab it will show no menu (which is as required).
This same thing happens for tab 5. If I am switching to 2nd child fragment within 2nd tab then the same behavior is observed with 1st tab.
In short, according to my observation it is showing the menu of adjacent tabs which is actually getting executed after the current fragment and therefore such behavior is occurring.
So how to avoid this?
I have written small test-application to check the behaviour.
Let's go through the sample and see, if something wrong with your fragments (as you see above, ViewPager with different menus works like a charm)
Activity's XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_below="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Activity class. Important part is invalidateOptionsMenu() every time ViewPager has PageSelected event. Then, we setting setHasOptionsMenu to all fragments and subfragments(from the nested ViewPagers) to false if they out of screen.
public class MainActivity extends AppCompatActivity {
PagerAdapter pagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment[] fragments = {
Fragment.instantiate(this, FragmentNoMenu.class.getName()),
Fragment.instantiate(this, FragmentA.class.getName()),
Fragment.instantiate(this, FragmentNoMenu.class.getName()),
Fragment.instantiate(this, FragmentB.class.getName()),
};
TabLayout tabLayout = (TabLayout)findViewById(R.id.tabLayout);
ViewPager viewPager = (ViewPager)findViewById(R.id.viewPager);
pagerAdapter = new PagerAdapter(getSupportFragmentManager(), fragments);
viewPager.setAdapter(pagerAdapter);
viewPager.setOffscreenPageLimit(0);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
#Override
public void onPageSelected(int position) {
invalidateOptionsMenu(position);
}
#Override
public void onPageScrollStateChanged(int state) {}
});
invalidateOptionsMenu(0);
tabLayout.setupWithViewPager(viewPager);
}
private void invalidateOptionsMenu(int position) {
for(int i = 0; i < pagerAdapter.getCount(); i++) {
Fragment fragment = pagerAdapter.getItem(i);
fragment.setHasOptionsMenu(i == position);
if (fragment instanceof FragmentWithViewPager) {
FragmentWithViewPager fragmentWithViewPager = (FragmentWithViewPager)fragment;
if (fragmentWithViewPager.pagerAdapter != null) {
for (int j = 0; j < fragmentWithViewPager.pagerAdapter.getCount(); j++) {
fragmentWithViewPager.pagerAdapter.getItem(j).setHasOptionsMenu(i == position);
}
}
}
}
invalidateOptionsMenu();
}
}
PagerAdapter class:
public class PagerAdapter extends FragmentPagerAdapter {
private final Fragment[] fragments;
public PagerAdapter(FragmentManager fragmentManager, Fragment[] fragments) {
super(fragmentManager);
this.fragments = fragments;
}
#Override
public CharSequence getPageTitle(int position) {
return fragments[position].getClass().getSimpleName();
}
#Override
public Fragment getItem(int position) {
return fragments[position];
}
#Override
public int getCount() {
return fragments.length;
}
}
Here're my test fragments I used:
FragmentNoMenu class:
public class FragmentNoMenu extends android.support.v4.app.Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_no_menu, container, false);
}
}
FragmentNoMenu layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#0F0F50"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
FragmentA class is a Fragment with nested ViewPager:
public class FragmentA extends FragmentWithViewPager {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_a, container, false);
Fragment[] fragments = {
Fragment.instantiate(getContext(), SubFragmentA.class.getName()),
Fragment.instantiate(getContext(), SubFragmentB.class.getName()),
Fragment.instantiate(getContext(), SubFragmentC.class.getName()),
};
if (pagerAdapter == null) {
pagerAdapter = new PagerAdapter(getChildFragmentManager(), fragments);
}
viewPager = (ViewPager)rootView.findViewById(R.id.viewPager);
viewPager.setAdapter(pagerAdapter);
return rootView;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_a, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
FragmentA's layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#B0B0B0"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_marginTop="80dp"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</FrameLayout>
FragmentA's menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_item_1"
android:title="Item 1"
android:orderInCategory="250"
app:showAsAction="never" />
<item
android:id="#+id/action_item_2"
android:title="Item 2"
android:orderInCategory="300"
app:showAsAction="never" />
</menu>
NB! FragmentA extends FragmentWithViewPager - it's a small extension of Fragment to make it easier to distinguish Fragments with nested fragments in MainActivity:
public class FragmentWithViewPager extends Fragment {
PagerAdapter pagerAdapter;
ViewPager viewPager;
}
FragmentB:
public class FragmentB extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_b, container, false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_b, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
It's layout & menu:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#999999"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
.....
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_item3"
android:title="Item 3"
android:icon="#drawable/ic_triage_star"
android:orderInCategory="250"
app:showAsAction="always" />
</menu>
Subfragments (they are all look the same from the code perspective):
Layouts:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#AA0000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="SubFragment C (with icon Menu)"
android:textSize="24sp"
android:textColor="#00BB00"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
Code:
public class SubFragmentB extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.subfragment_b, container, false);
}
}
That's it! I've uploaded the project to my dropbox - feel free to check it out!
I hope, it helps
In my application I am using actionbar tabs at bottom. I have searched many tutorials but I am not understanding the solutions. Most of the answers said to use TabActivity, but that is deprecated. So can any one tell me how can approach this?
The best way to implement tabs now is to use a TabLayout from the design library.
Here is an example of a TabLayout aligned at the bottom of the screen.
First set up the dependencies in the build.gradle file:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}
Here is the layout xml for the Main Activity:
<RelativeLayout
android:id="#+id/main_layout"
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"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
app:tabMode="fixed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="6dp"
app:tabTextColor="#d3d3d3"
app:tabSelectedTextColor="#ffffff"
app:tabIndicatorColor="#ff00ff"
android:minHeight="?attr/actionBarSize"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
Here is the Activity code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
PagerAdapter pagerAdapter =
new PagerAdapter(getSupportFragmentManager(), MainActivity.this);
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
// Iterate over all tabs and set the custom view
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_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);
}
class PagerAdapter extends FragmentPagerAdapter {
String tabTitles[] = new String[] { "Tab One", "Tab Two", "Tab Three", };
Context context;
public PagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return tabTitles.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new BlankFragment();
case 1:
return new BlankFragment();
case 2:
return new MapFragment();
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
public View getTabView(int position) {
View tab = LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_tab, null);
TextView tv = (TextView) tab.findViewById(R.id.custom_text);
tv.setText(tabTitles[position]);
return tab;
}
}
}
custom_tab.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">
<TextView
android:id="#+id/custom_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:textSize="16dip"
android:textColor="#ffffff"
android:singleLine="true"
/>
</LinearLayout>
App theme in styles.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- your app branding color for the app bar -->
<item name="colorPrimary">#3F51B5</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="colorPrimaryDark">#303F9F</item>
<!-- theme UI controls like checkboxes and text fields -->
<item name="colorAccent">#FF4081</item>
</style>
Result:
If you want to hide the ActionBar, just remove the toolbar from the layout xml, and remove the toolbar code from the Activity, and make sure to use Theme.AppCompat.Light.NoActionBar in the AppTheme. The result of those changes would make it look like this:
this is an example
Toolbar toolbarBottom = (Toolbar) findViewById(R.id.toolbar_bottom);
toolbarBottom.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId()){
case R.id.action_settings:
// TODO
break;
// TODO: Other cases
}
return true;
}
});
// Inflate a menu to be displayed in the toolbar
toolbarBottom.inflateMenu(R.menu.menu_main);
and this xml
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_bottom"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?attr/colorPrimary"
android:layout_alignParentBottom="true"
android:minHeight="?attr/actionBarSize" />
Step 1 - Create a custom layout for your toolbar.
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
Step 2 - Include this layout into your activity layout. Give it the bottom position.
<include
android:id="#+id/toolbar_main"
layout="#layout/main_toolbar" />
Step 3 - Call the toolbar into your activity and done. It will behave as any toolbar but positioned at bottom.