Remove Space Gap between toolbar and tablayout - java

I have a AppBarLayout with TabLayout in a fragment that is into an Activity that has a Toolbar. But between toolbar and TabLayout appears a space, i don't know where it comes from.
fragment_packs.xml
<FrameLayout 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="studio.com.archeagemanager.EventosFragment">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="studio.com.archeagemanager.PacksFragment">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabTextColor="#ffffff" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
</FrameLayout>
PacksFragment.java
public class PacksFragment extends Fragment {
public PacksFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_packs, container, false);
AppBarLayout appBarLayout = (AppBarLayout) view.findViewById(R.id.appbar);
appBarLayout.setExpanded(false);
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
viewPager.setAdapter(new PagerAdapter(getFragmentManager()));
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
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) {
}
});
return view;
}
public class PagerAdapter extends FragmentStatePagerAdapter {
private String[] tabTitles = new String[]{"Tab1", "Tab2", "Tab3", "Tab4"};
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new TabFragmentA();
case 1:
return new TabFragmentA();
case 2:
return new TabFragmentA();
case 3:
return new TabFragmentA();
default:
return null;
}
}
#Override
public int getCount() {
return tabTitles.length;
}
}
}

In your CoordinatorLayout
instead of
android:fitsSystemWindows="true"
apply
android:fitsSystemWindows="false"
Here is a good Documentation why and when you should use a android:fitsSystemWindows
System windows are the parts of the screen where the system is drawing either non-interactive (in the case of the status bar) or interactive (in the case of the navigation bar) content.
Most of the time, your app won’t need to draw under the status bar or the navigation bar, but if you do: you need to make sure interactive elements (like buttons) aren’t hidden underneath them. That’s what the default behavior of the android:fitsSystemWindows=“true” attribute gives you: it sets the padding of the View to ensure the contents don’t overlay the system windows.
A few things to keep in mind:
1)fitsSystemWindows is applied depth first — ordering matters: it’s the first View that consumes the insets that makes a difference
2) Insets are always relative to the full window — insets may be applied even before layout happens, so don’t assume the default behavior knows anything about the position of a View when applying its padding
3) Any other padding you’ve set is overwritten — you’ll note that paddingLeft/paddingTop/ etc is ineffective if you are using android:fitsSystemWindows=”true” on the same View

When You are using Navigation Drawer, there is app_bar_main.xml where AppBarLayout is already present, so removing both AppBarLayout and Toolbar from app_bar_main.xml will solve the problem.
<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>
in both app_bar_main.xml and content_main.xml AppBarLayout and Toolbar present.
removing from one will solve the problem

Related

Google maps flicker/blink black on toggling content visibility

I have implemented my map fragment with map as <fragment> in two places:
(main) <DrawerLayout> --> <FrameLayout> (container)
--> (fragment inflated) <CoordinatorLayout> --> <LinearLayout> --> <ViewPager2> (container)
--> (fragment inflated) <NestedScrollView> --> <LinearLayout> --> <ViewPager2> (container)
--> (map fragment inflated) <FrameLayout> --> <fragment>
(main) <LinearLayout> --> <LinearLayout> (container)
--> (fragment inflated) <LinearLayout> --> <ViewPager2> (container)
--> (map fragment inflated) <FrameLayout> --> <fragment>
The problem is that in the first case my map flickers when I click on a map marker or when I click on an ImageView from my map fragment ViewGroup that does nothing but toggle icons visibility between GONE and VISIBLE. The second case works fine. It gives me a hint that map's blinking is due to other views changing their visibility in the NestedScrollView. Maybe it is also because of overwhelming number of parents.
I tried to implement android:layerType="hardware" but it doesnt help. Also, when the visibility is toggled between VISIBLE and INVISIBLE all works fine, but this is not the solution.
I have recorded the told map's behaviour and attached it here. On the record I click on a ToggleButton and toggle a small tick icon between GONE and VISIBLE.
Any ideas how to fix that?
Code
Main Activity
It is a Navigation Drawer Activity
public class MainActivityC extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_c);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_activity_c, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
}
Fragment 1
This fragment holds ViewPager2
public class GalleryFragment extends Fragment{
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_gallery, container, false);
}
private Context context;
private ViewPager2 viewPager2;
private TabLayout tabLayout;
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
context = getActivity();
initTab();
}
private void initTab() {
viewPager2 = getView().findViewById(R.id.viewpager2_walks_saved);
viewPager2.setAdapter(new WalksSavedPagerAdapter(getActivity()));
viewPager2.setUserInputEnabled(false); // NO SCROLL
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
switch (position) {
case 0:
String text1 = "Walks History";
((MainActivityC) context).getSupportActionBar().setTitle(text1);
break;
case 1:
String text2 = "Walks Statistics";
((MainActivityC) context).getSupportActionBar().setTitle(text2);
break;
}
}
});
tabLayout = getView().findViewById(R.id.tabLayout_walks_statistics);
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
switch (position) {
case 0:
tab.setText("Walks History");
break;
case 1:
tab.setText("Walks Statistics");
break;
}
}
}
);
tabLayoutMediator.attach();
}
}
Layout:
<androidx.coordinatorlayout.widget.CoordinatorLayout
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="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="?attr/colorPrimary">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|snap"
android:elevation="4dp">
<TextView
android:id="#+id/drawer_fragment_saved_walks_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Saved Walks"
android:textSize="30sp"
android:textColor="#color/white"
android:layout_gravity="center"/>
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="0dp"
android:layout_width="match_parent"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
<!--android:layout_height="?attr/actionBarSize"-->
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<!-- Tab to chose between Saved Walks and Statistics -->
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout_walks_statistics"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:layout_gravity="bottom"
app:tabIndicatorHeight="3dp"
app:tabMode="fixed"
app:tabPaddingBottom="4dp"
app:tabPaddingTop="4dp" />
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/viewpager2_walks_saved"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Fragment 2
This fragment is shown in the ViewPager2 and has its own ViewPager2
public class StatisticsFragment extends Fragment {
private ViewPager2 viewPager2;
private TabLayout tabLayoutViewPager;
private StatisticsPagerAdapter statisticsPagerAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_walks_statistics, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
init();
}
private void init(){
statisticsPagerAdapter = new StatisticsPagerAdapter(getActivity());
viewPager2 = getView().findViewById(R.id.viewpager2_statistics);
viewPager2.setAdapter(statisticsPagerAdapter);
viewPager2.setUserInputEnabled(false); // NO SCROLL
tabLayoutViewPager = getView().findViewById(R.id.tabLayout_statistics);
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
tabLayoutViewPager, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
switch (position) {
case 0:
tab.setText("Events");
break;
case 1:
tab.setText("Chronology");
break;
case 2:
tab.setText("Heat Map");
break;
}
}
}
);
tabLayoutMediator.attach();
}
}
Layout:
<androidx.core.widget.NestedScrollView
android:id="#+id/heatmap_nested_scroll_view"
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:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout_statistics"
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="#android:color/transparent"
android:layout_marginTop="8dp"
app:tabIndicatorHeight="3dp"
app:tabMode="fixed"
app:tabPaddingBottom="4dp"
app:tabPaddingTop="4dp" />
<View
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#android:color/darker_gray" />
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/viewpager2_statistics"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
Fragment 3 with GoogleMap
This fragment is shown in the ViewPager2 and holds the fickering map
public class StatisticsHeatmapFragment extends Fragment implements OnMapReadyCallback,
CompoundButton.OnCheckedChangeListener {
private Context context;
private Fragment parentFragment;
private ToggleButton iconRescale;
private ImageView iconCheck;
private MapFragment mapFragment;
private GoogleMap map;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_statistics_heatmap, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initiate();
}
#SuppressLint("ClickableViewAccessibility") // Due to the touch listener
private void initiate() {
context = getActivity();
// A neat way to find the parent fragment in a child ViewPager fragment
List<Fragment> fragment = getActivity().getSupportFragmentManager().getFragments();
for (Fragment f:fragment) {
if (f instanceof StatisticsFragment){
parentFragment = f;
}
}
ImageView transparentImageView = (ImageView) getView().findViewById(R.id.heatmap_transparent_image);
// Tag is automatically given by ViewPager2 like "f" + position, but I have overwritten it.
// So the StatisticsFragment is "f101". There the NestedScrollView locates.
final NestedScrollView nestedScrollView = (NestedScrollView)
getActivity().getSupportFragmentManager().findFragmentByTag("f101").getView();
// The warning comes up because Android wants to remind you to think about the blind or visually impaired people who may be using your app
transparentImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
nestedScrollView.requestDisallowInterceptTouchEvent(true);
// Disable touch on transparent view
return false;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
nestedScrollView.requestDisallowInterceptTouchEvent(false);
return true;
case MotionEvent.ACTION_MOVE:
nestedScrollView.requestDisallowInterceptTouchEvent(true);
return false;
default:
return true;
}
}
});
mapFragment = (MapFragment) getActivity().getFragmentManager()
.findFragmentById(R.id.map_statistics);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
initToggleButtons();
}
private void initToggleButtons() {
iconCheck = getView().findViewById(R.id.icon_check_heatmap_stats);
iconRescale = getView().findViewById(R.id.icon_rezoom_heatmap_stats);
iconRescale.setChecked(true);
iconRescale.setOnCheckedChangeListener(this);
}
/**
* CheckChange listener for events icon (ToggleButton)
*/
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (buttonView.equals(iconRescale)){
if (isChecked) {
DrawableCompat.setTint(
DrawableCompat.wrap(iconRescale.getBackground()),
ContextCompat.getColor(context, R.color.black));
iconCheck.setVisibility(View.VISIBLE);
Toast.makeText(context, "Map scale to the data is ON", Toast.LENGTH_SHORT).show();
} else {
DrawableCompat.setTint(
DrawableCompat.wrap(iconRescale.getBackground()),
ContextCompat.getColor(context, R.color.common_google_signin_btn_text_light));
iconCheck.setVisibility(View.GONE);
Toast.makeText(context, "Map scale to the data is OFF", Toast.LENGTH_SHORT).show();
}
}
}
}
Layout:
<FrameLayout 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">
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
android:name="com.google.android.gms.maps.MapFragment"
android:id="#+id/map_statistics"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:mapType="normal" />
<ImageView
android:id="#+id/heatmap_transparent_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#android:color/transparent" />
<ImageView
android:id="#+id/icon_check_heatmap_stats"
android:layout_width="14dp"
android:layout_height="14dp"
android:background="#drawable/ic_baseline_check_24"
android:backgroundTint="#android:color/holo_red_light"
android:layout_gravity="end|top"
android:layout_marginTop="28dp"
android:layout_marginEnd="69dp"/>
<ToggleButton
android:id="#+id/icon_rezoom_heatmap_stats"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="#drawable/ic_baseline_zoom_out_map_24"
android:backgroundTint="#color/black"
android:layout_gravity="end|top"
android:layout_marginTop="20dp"
android:layout_marginEnd="60dp"
android:textOn=" "
android:textOff=" "/>
</FrameLayout>
P.S. Multiple clicks on the icon are required to spot the problem using this code.
I have solved my own problem, however other solutions are more than welcome.
The issue is that the map's parent <NestedScrollView> has android:fillViewport="true" attribute, which forces the view to stretch its content to fill the viewport.
The solution is to set the map's view to a constant height. So, android:layout_height="match_parent" should be changed to android:layout_height="500dp" for example. Also, the height could be set dinamically as appropriate.
Addition
Google Map view in NestedScrollView can be kept android:layout_height="match_parent". Then, to fix the view's height (which is needed to avoid the flickers) add this snippet in onCreate or onCreateView in Activity or Fragment respectively:
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
int height = v.getHeight();
ViewGroup.LayoutParams params = view.getLayoutParams();
params.height = height;
view.setLayoutParams(params);
view.removeOnLayoutChangeListener(this);
}
});

tabbed layout inside fragment not working properly

i'm a beginner trying to apply the idea of having tabbed layout inside a "main" fragment that allows me to navigate to other "secondary fragments" as well, there is a main activity with a button which when clicked will inflate the tabbed fragment inside this activity.
but what i got is this: the tabs are duplicated on just the first fragment for some reason.
here is my code: MainActiviy.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void fragny(View view) {
FragmentTransaction ft=getSupportFragmentManager().beginTransaction();
ft.replace(R.id.ma,new labRatFrag());
ft.commit();
}
}
main_activity.xml
<androidx.constraintlayout.widget.ConstraintLayout 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/ma"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:onClick="fragny"
/>
FragmentPagerAdapter
public class FragAdapt extends FragmentPagerAdapter {
private static final String[] TAB_TITLES = new String[]{"test1","test2","test3"};
private final Context mContext;
public FragAdapt(Context context ,FragmentManager fm) {
super(fm);
mContext=context;
}
#NonNull
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new labRatFrag();
case 1:
return new labRatFrag2();
case 2:
return new labRatFrag3();
default:
return null;
}
}
#Override
public String getPageTitle(int position) {
return TAB_TITLES[position];
}
#Override
public int getCount() {
return 3;
}
}
my main fragment (labRatFrag.java)
public class labRatFrag extends Fragment {
public labRatFrag() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v= inflater.inflate(R.layout.fragment_lab_rat, container, false);
FragAdapt fa=new FragAdapt(getContext(),getActivity().getSupportFragmentManager());
ViewPager vp=v.findViewById(R.id.pagery);
vp.setAdapter(fa);
TabLayout tabs = v.findViewById(R.id.toto);
tabs.setupWithViewPager(vp);
return v;
}
}
fragment_lab_rat.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
>
<com.google.android.material.tabs.TabLayout
android:id="#+id/toto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/pagery"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
i want to do this in order to apply this idea with bottom navigation or navigation drawer for a future app i'm planning
FragAdapt is for your secondary fragment, right?
if yes, try replacing
FragAdapt fa=new FragAdapt(getContext(),getActivity().getSupportFragmentManager());
with
FragAdapt fa=new FragAdapt(getContext(),getChildFragmentManager());.
It might help. If not, will prepare a demo for you

Tablayout animation like whatsapp

I am using TabLayout and SearcView. How can I do , when click search button to hide tab layout like whatsapp.
I try setEnabled method but it can't work properly.
I also used Visibility,setActivated method.What can I do?I don't know. I must use setAnimation method or something else?
MainActivity.java
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private CoordinatorLayout coordinatorLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout)findViewById(R.id.root_view);
toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager)findViewById(R.id.view_pager);
setUpViewPager(viewPager);
tabLayout = (TabLayout)findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setUpViewPager(ViewPager viewPager) {
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapter.addFragment(CurrencyFragment.getInstance(),"Tracker"); // `CurrencyFragment.getInstance()` should be in `FragmentPagerAdapter.getItem()`
viewPagerAdapter.addFragment(ConvertFragment.getInstance(),"Converter"); // `ConvertFragment.getInstance()` should be in `FragmentPagerAdapter.getItem()`
viewPager.setAdapter(viewPagerAdapter);
}
activity_main.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:id="#+id/root_view"
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/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
app:titleTextColor="#android:color/white"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill">
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</android.support.design.widget.CoordinatorLayout>
If you have used menu item for search then you have to follow below code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.search) // set your own id if you have different id from search.
{
tabLayout.setVisibility(View.GONE);
return true;
}
return super.onOptionsItemSelected(item);
}
When you finished with search then set tablayout visible.
tabLayout.setVisibility(View.VISIBLE);
Follow these simple steps
In your XML file create Appbar. Inside that create a Constraintlayout and keep it as match parent match parent.
Inside that keep your toolbar at the top and below that your tab layout.
Now Create the Edittext of search view as WhatsApp and keep it also as Top_to_top of parent and make the view View. Gone.
In Activity on click of the search icon
toolbar.setVisibility(View.GONE);
tabLayout.setVisibility(View.GONE);
searchViewEditText.setVisibility(View.GONE);

Crash on Rotation with this error: Fragment has not been attached yet

i have an Activity with 02 tabLayout
i added First Fragment in my first tab, every thing was just fine since i added my Second Fragment in second tab
my Second Fragment works but when i rotate the device it'll be crash, here is my codes and logCat..
i tried to attach my FragmentTwo to my MainActivity in different ways.. can anybody tell me what's wroNg && how can i do this correctly?
Thanks in advancE.
Main Activity:
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] tabIcons = {
R.drawable.ic_tab_note,
R.drawable.ic_tab_calendar
};
private static final int TIME_DELAY = 2000;
private static long back_pressed;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//////// TOOLBAR
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
actionBar.setDisplayHomeAsUpEnabled(true);
///////// DRAWER
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView =
(NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener
(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
Toast.makeText(MainActivity.this,
menuItem.getTitle(),
Toast.LENGTH_LONG).show();
return true;
}
});
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentOne(), "ONE");
adapter.addFragment(new FragmentTwo(), "TWO");
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);
return null;
}
}
}
FragmentTwo:
import ir.mirrajabi.persiancalendar.PersianCalendarView;
import ir.mirrajabi.persiancalendar.core.PersianCalendarHandler;
import ir.mirrajabi.persiancalendar.core.interfaces.OnDayClickedListener;
import ir.mirrajabi.persiancalendar.core.interfaces.OnMonthChangedListener;
import ir.mirrajabi.persiancalendar.core.models.CalendarEvent;
import ir.mirrajabi.persiancalendar.core.models.PersianDate;
public class FragmentTwo extends Fragment {
private View view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_two_layout,
container, false);
final PersianCalendarView persianCalendarView = (PersianCalendarView) view.findViewById(R.id.persian_calendar);
final PersianCalendarHandler calendar = persianCalendarView.getCalendar();
final PersianDate today = calendar.getToday();
calendar.addLocalEvent(new CalendarEvent(
today, "Custom event", false
));
calendar.addLocalEvent(new CalendarEvent(
today.clone().rollDay(2, true), "Custom event 2", true
));
calendar.setOnMonthChangedListener(new OnMonthChangedListener() {
#Override
public void onChanged(PersianDate date) {
Toast.makeText(getActivity(), calendar.getMonthName(date), Toast.LENGTH_SHORT).show();
}
});
persianCalendarView.setOnDayClickedListener(new OnDayClickedListener() {
#Override
public void onClick(PersianDate date) {
for (CalendarEvent e : calendar.getAllEventsForDay(date))
Toast.makeText(getActivity(), e.getTitle(), Toast.LENGTH_LONG).show();
calendar.addLocalEvent(new CalendarEvent(
today.clone().rollDay(2, false), "Some event that will be added in runtime", false
));
persianCalendarView.update();
}
});
calendar.setHighlightOfficialEvents(false);
TextView txtDayMonth = (TextView) view.findViewById(R.id.txt_day_month);
TextView txtYear = (TextView) view.findViewById(R.id.txt_year);
String dayAndMonth = calendar.getWeekDayName(today) + calendar.formatNumber(today.getDayOfMonth())
+ calendar.getMonthName(today);
txtDayMonth.setText(dayAndMonth);
txtYear.setText(calendar.formatNumber(today.getYear()));
calendar.setColorBackground(getResources().getColor(android.R.color.holo_blue_dark));
persianCalendarView.update();
return view;
}
}
and here is my activity_main.xml :
<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">
<RelativeLayout
android:id="#+id/base2"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark"/>
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:tabGravity="fill"
android:theme="#style/ThemeOverlay.AppCompat.Dark"/>
<RelativeLayout
android:id="#+id/relativee"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout_weight="1"/>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
and here is fragment_two_layout.xml :
<LinearLayout
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="match_parent"
android:background="#color/colorPrimaryDark"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24dp">
<ir.mirrajabi.persiancalendar.PersianCalendarView
android:id="#+id/persian_calendar"
android:layout_width="match_parent"
android:layout_height="290sp"
app:pcv_colorBackground="#292929"
app:pcv_colorDayName="#bab6b6"
app:pcv_colorHoliday="#ffd506"
app:pcv_colorHolidaySelected="#f1f2f3"
app:pcv_colorNormalDaySelected="#d9d9d9"
app:pcv_colorNormalDay="#f3f4f5"
app:pcv_eventUnderlineColor="#02f0f0"
app:pcv_fontSize="20sp"
app:pcv_headersFontSize="14sp"/>
</android.support.v7.widget.CardView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="8dp">
<TextView
android:id="#+id/txt_day_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/colorAccent"
android:layout_gravity="center_horizontal"
android:textSize="30sp"/>
<TextView
android:id="#+id/txt_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textColor="#color/colorAccent"
android:textSize="20sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<Button
android:id="#+id/change_to_ad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change to Gregorian Calendar"
android:textSize="14dp"/>
</LinearLayout>
</LinearLayout>
logCat:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.drgnme.listhamrah/com.drgnme.listhamrah.MainActivity}: java.lang.IllegalStateException: Fragment has not been attached yet.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2434)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4095)
at android.app.ActivityThread.access$1000(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1353)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalStateException: Fragment has not been attached yet.
at android.support.v4.app.Fragment.instantiateChildFragmentManager(Fragment.java:2195)
at android.support.v4.app.Fragment.getChildFragmentManager(Fragment.java:745)
at ir.mirrajabi.persiancalendar.core.fragments.CalendarFragment.createViewPagers(CalendarFragment.java:55)
at ir.mirrajabi.persiancalendar.core.fragments.CalendarFragment.access$000(CalendarFragment.java:27)
at ir.mirrajabi.persiancalendar.core.fragments.CalendarFragment$1.update(CalendarFragment.java:46)
at ir.mirrajabi.persiancalendar.PersianCalendarView.update(PersianCalendarView.java:116)
at com.drgnme.listhamrah.FragmentTwo.onCreateView(FragmentTwo.java:87)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2239)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1332)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1574)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1641)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2959)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:550)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1238)
at android.app.Activity.performStart(Activity.java:6340)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2397)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4095) 
at android.app.ActivityThread.access$1000(ActivityThread.java:153) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1353) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5451) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Move all the below code to onActivityCreated():
final PersianCalendarView persianCalendarView = (PersianCalendarView) view.findViewById(R.id.persian_calendar);
final PersianCalendarHandler calendar = persianCalendarView.getCalendar();
final PersianDate today = calendar.getToday();
calendar.addLocalEvent(new CalendarEvent(
today, "Custom event", false
));
calendar.addLocalEvent(new CalendarEvent(
today.clone().rollDay(2, true), "Custom event 2", true
));
calendar.setOnMonthChangedListener(new OnMonthChangedListener() {
#Override
public void onChanged(PersianDate date) {
Toast.makeText(getActivity(), calendar.getMonthName(date), Toast.LENGTH_SHORT).show();
}
});
persianCalendarView.setOnDayClickedListener(new OnDayClickedListener() {
#Override
public void onClick(PersianDate date) {
for (CalendarEvent e : calendar.getAllEventsForDay(date))
Toast.makeText(getActivity(), e.getTitle(), Toast.LENGTH_LONG).show();
calendar.addLocalEvent(new CalendarEvent(
today.clone().rollDay(2, false), "Some event that will be added in runtime", false
));
persianCalendarView.update();
}
});
calendar.setHighlightOfficialEvents(false);
TextView txtDayMonth = (TextView) view.findViewById(R.id.txt_day_month);
TextView txtYear = (TextView) view.findViewById(R.id.txt_year);
String dayAndMonth = calendar.getWeekDayName(today) + calendar.formatNumber(today.getDayOfMonth())
+ calendar.getMonthName(today);
txtDayMonth.setText(dayAndMonth);
txtYear.setText(calendar.formatNumber(today.getYear()));
calendar.setColorBackground(getResources().getColor(android.R.color.holo_blue_dark));
persianCalendarView.update();
It is a best practice not do any works other than inflating the layout inside onCreateView()
Just move the persianCalendarView.update() line inside your FragmentTwo's onAttach and remove it from onCreate() :
#Override
public void onAttachFragment(Fragment childFragment) {
super.onAttachFragment(childFragment);
persianCalendarView.update();
}
Also remove the update() from the inside of persianCalendarView's OnDayClickedListener. I added that line when I was testing and forgot to remove that from the sample app. You don't have to update persianCalendarView unless you need to change the theme or when adding events in runtime.
Problem is not in your app, Problem is in PersianCalendar Lib,
You are inflating PersianCalendarView in your layout in the Fragment class if you check their implementation in PersianCalendarView.java, 1. they are inflating one layout and they are trying to add one Fragment in that layout in that FragmentManager and its working fine. 2. but not only that in that Fragment they are trying to add ViewPager using getChildFragmentManager() Problem comes her only.
You can ask why? In already one FragmentManager added this Fragment that time its working fine but now it's crashing, For that, you can check the difference between that 2 FragmnetManger in this S0 Answer
For this problem, you can do 3 things,
1. You can create ticket to them and wait for the result
2. You can fix that issue
3. Instead of Adding in Layout, Just Create one ViewGroup in Fragment and when onActivtyCreated called you can Add that layout runtime.
EDITED
I tried that sample, And I tried to add it in Fragment, Problem I faced is, Actually the CalendarView fragment is not attached even though our Fragment attached to the Activity, So as I Mentioned in Solution 3 that we can add it in onActivtyCreated that is wrong.
Then how we can solve temporarily?
I solved by adding the view in onStart(I know this is the wrong place this will call multiple time in the life cycle of Fragment), but we can add some logic and we can add this calendar view only once for making it work now till the dev fix in their lib.
My sample :
My fragment Layout:
<FrameLayout 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"
tools:context="ir.mirrajabi.pc.sample.BlankFragment">
<LinearLayout
android:id="#+id/calendar_container"
android:layout_width="match_parent"
android:layout_height="290dp"
android:orientation="vertical"/>
<TextView
android:id="#+id/txt_day_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textColor="#f0f2f3"
android:textSize="30sp"/>
<TextView
android:id="#+id/txt_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textColor="#c6d9e2"
android:textSize="20sp"/>
</FrameLayout>
Fragment code
public class BlankFragment extends Fragment {
private LinearLayout mLinearLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank, container, false);
mLinearLayout= (LinearLayout) view.findViewById(R.id.calendar_container);
return view;
}
#Override
public void onStart() {
super.onStart();
final PersianCalendarView persianCalendarView = new PersianCalendarView(getContext());
// All your remaining PersianCalendarView implementation code here
mLinearLayout.addView(persianCalendarView);
}
}
Note:
If you take above approach, Please add some logic and make sure it's
not adding multiple time when onStart calls in the Fragment.

Cause activity in actionbar tabs

I use action bar tabs android studio, his div on section and I want that touch section I cause scrolling activity! I dont want work with a fragments, I want see in my section scrolling activity.
Help please, because long time sit in this trouble.
This is what I want to achieve:
MainActivity.java:
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);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
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(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) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
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);
}
#Override
public int getCount() {
// Show 3 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
case 2:
return "SECTION 3";
case 3:
return "Секція 4";
}
return null;
}
}
}
main_activity.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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.vladislav.scrolable.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.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</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"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
fragment_main.xml:
<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="com.vladislav.scrolable.MainActivity$PlaceholderFragment">
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/scrollView"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
After tinkering with your code in git, we can make a scrollable TabLayout by changing the fragment_main.xml to:
<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"
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="com.vladislav.scrolable.MainActivity$PlaceholderFragment"
>
<android.support.v4.widget.NestedScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</android.support.v4.widget.NestedScrollView>
</RelativeLayout>
We must set the layout_width and layout_height of NestedScrollView to match_parent so that we can scroll the layout when we scrolling up the TextView.
Remember that we need to add the following code to NestedScrollView:
app:layout_behavior="#string/appbar_scrolling_view_behavior"
to inform AppBarLayout about the scrolling.
Please look at your Scrolable project after my edit in my Scrolable github.
Sample picture after scrolling up:

Categories