Collapsingtoolbar in fragment not show/hide header when scrolling - android

I replace fragment in a activity and in my fragment I need a CoordinatorLayout.
Here is my code :
CoordinatorActivity class:
public class CoordinatorActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_coordinator);
Fragment newFragment = new FragmentCoordinator();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fr_main, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
activity_coordinator.xml file:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="#+id/fr_main"
tools:context="com.app.hoatv.CoordinatorActivity">
</FrameLayout>
FragmentCoordinator class:
public class FragmentCoordinator extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_coordinator, container, false);
}
}
fragment_coordinator.xml file :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.app.hoatv.CoordinatorActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:elevation="0dp"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme">
<include layout="#layout/layout_group_header"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_height="match_parent"
android:layout_width="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fillViewport="true">
<android.support.v7.widget.AppCompatTextView
android:layout_height="1000dp"
android:layout_width="match_parent"
android:text="#string/lorem"
android:background="#color/colorAccent"
android:id="#+id/container"/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
layout_group_header.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#a70000">
</LinearLayout>
but when I scrolling NestedScrollView layout_group_header.xml not show or hide. It always show in my fragment screen.
What happened in my code? and How I can fix it?

What happened in my code? and How I can fix it?
There are few things which you should consider. First, you are opening a view(LinearLayout) inside AppBarLayout which there might be a Toolbar but that's not just the case.
First part: (Important one): The best idea and correct way of creating such layouts is to first, remove LinearLayout from the root of the fragment_coordinator layout then copy-paste the codes from fragment_coordinator to activity_coordinator. After that, use FrameLayout as the content's Container inside NestedScrollView.
Making Changes Part (As your requirements): After all, you can place codes anywhere you want in the main layout, for example, if you want the layout_group_header to be hidden after scrolling in the layout, you may wanna use layout_group_header codes inside fragment_coordinator which it will be a scrolling content. Othewise, you can use the codes inside CoordinatorLayout or anywhere instead of including it like that.
P.s: Design is completely seems to be wrong. Use first part which is an important part of creating such layouts. Note that there will be some changes inside java-kotlin sides too. (Changing layout address or etc)

Related

Replacing DrawerLayout's RelativeLayout with a Fragment's layout doesn't work but no error is shown [duplicate]

I have the following XML:
<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>
<!--I use this include as container with the FrameLayout below-->
<!--<include layout="#layout/content_main" />-->
<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:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.improvemybrand.MainActivity"
tools:showIn="#layout/app_bar_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_input_add" />
and the problem is simple:
When I try to replace the container FrameLayout from my Coordinator, it does not work, it shows the new fragment but also keeps the old one, in my simple example, the TextView with Hello world will remains.
To replace, I'm using the following code:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content_main, fragment);
transaction.commit();
Any ideas?
FragmentTransactions deal only with Fragments and their Views. The TextView you've defined in your layout is not (part of) a Fragment's View, so it will not be affected by a FragmentTransaction, and the Fragment in your snippet will just be added on top of it.
You have a few options. You could hide or remove the TextView yourself when performing the transaction. This might be preferable, if that simple TextView is all you need initially, and sticking it in a Fragment could be overkill. You could also simply set an opaque background on the Fragment's layout, which will effectively hide the TextView.
The probably best option, however, is to put the TextView in a layout for another Fragment which is loaded at startup. Subsequent transactions will then replace/remove it as you're expecting. Do note that any Fragment you wish to replace/remove at runtime must be loaded dynamically in your code. That is, they cannot be defined in <fragment> elements in your Activity's layout.
You should move TextView into Fragment's layout.
like this.
fragment_hello_world.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
</LinearLayout>
HelloWorldFragment
public class HelloWorldFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_hello_world, container, false);;
}
}

android: Replace fragment container inside a CoordinatorLayout

I have the following XML:
<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>
<!--I use this include as container with the FrameLayout below-->
<!--<include layout="#layout/content_main" />-->
<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:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.improvemybrand.MainActivity"
tools:showIn="#layout/app_bar_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_input_add" />
and the problem is simple:
When I try to replace the container FrameLayout from my Coordinator, it does not work, it shows the new fragment but also keeps the old one, in my simple example, the TextView with Hello world will remains.
To replace, I'm using the following code:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content_main, fragment);
transaction.commit();
Any ideas?
FragmentTransactions deal only with Fragments and their Views. The TextView you've defined in your layout is not (part of) a Fragment's View, so it will not be affected by a FragmentTransaction, and the Fragment in your snippet will just be added on top of it.
You have a few options. You could hide or remove the TextView yourself when performing the transaction. This might be preferable, if that simple TextView is all you need initially, and sticking it in a Fragment could be overkill. You could also simply set an opaque background on the Fragment's layout, which will effectively hide the TextView.
The probably best option, however, is to put the TextView in a layout for another Fragment which is loaded at startup. Subsequent transactions will then replace/remove it as you're expecting. Do note that any Fragment you wish to replace/remove at runtime must be loaded dynamically in your code. That is, they cannot be defined in <fragment> elements in your Activity's layout.
You should move TextView into Fragment's layout.
like this.
fragment_hello_world.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
</LinearLayout>
HelloWorldFragment
public class HelloWorldFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_hello_world, container, false);;
}
}

Floating action button will not disappear when going to another fragment

I built a project based on Scrolling Activity, and faced a strange issue. Consider the following scenario:
I click on fab button to go to another fragment but when the fragment displaces, the fab button will not disappear!
Can anybody know how to fix this problem?
Here is my XML of Scrolling Activity that I added to my frameLayout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="ir.apio.myapplication.ScrollingActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="#dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_scrolling" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email"
app:layout_anchor="#id/app_bar"
app:layout_anchorGravity="bottom|end" />
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.design.widget.CoordinatorLayout>
content_scrolling.xml :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="ir.apio.myapplication.ScrollingActivity"
tools:showIn="#layout/activity_scrolling">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/text_margin"
android:text="#string/large_text" />
</android.support.v4.widget.NestedScrollView>
My fab ClickListener :
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frame,new TestFragment())
.commit();
}
});
And also my TestFragment :
public static class TestFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test,container,false);
return view;
}
}
Here is the screen-shot in the first place:
Here is screen-shot when going to the new fragment:
The reason you are still seeing the FAB is elevation, which refers to a views depth on the screen. It affects which elements are above or below one another and the shadows they cast(for example a FAB sits on top of the main content and casts a shadow).
The FAB by default will have some elevation, which you can override using the elevation attribute, eg app:elevation="4dp". The other elements will be at the 0dp level.
In your case, you've put the FrameLayout last in your layout file, and I presume that's where you are loading your fragment into. What this does is not actually replace your other content, but just cover it with the content of your FrameLayout.
The reason it doesn't cover the FAB, is because the FAB has some elevation and the FrameLayout doesn't. So although you've put your FrameLayout last and would normally expect that to be "on top", the FAB actually has a higher elevation which overrides that.
A quick fix, would be to give your floating action button app:elevation=0dp which would put it back on the same elevation level as everything else and the normal rules would apply, the FrameLayout is last and would be on top.
In reality, just putting a big frame covering the previous content is not usually the best thing to do and you would want to look at other ways to structure the app.
I had the same problem. I called the .hide() method on the FragmentTransaction and it worked for me.
fab.setOnClickListener {
val fragmentManager = fragmentManager
val fragmentTransaction = fragmentManager?.beginTransaction()
val fragment = YourFragment()
fragmentTransaction?.add(R.id.fragment_container, fragment)
fragmentTransaction?.addToBackStack(null)
fragmentTransaction?.hide(this)
fragmentTransaction?.commit()
}

Using MPChartLibrary within a fragment

I am working on an Android project and I am trying to implement a Library called MPAndroidChart from https://github.com/PhilJay/MPAndroidChart.
I am trying to implement it in a fragment but I keep getting an error and I cannot see why.
Below is my activity.
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment chartFragment = new ChartFragment();
transaction.replace(R.id.fragmentContainer, chartFragment);
transaction.commit();
}
}
Below is my activities layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/toolbar" />
<FrameLayout android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Below is my Fragment class
public class ChartFragment extends Fragment
{
private LineChart mChart;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.graph, container, false);
return v;
}
}
And below is the layout for the fragment
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.LineChart
android:id="#+id/lineChart1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
At the moment it crashes when it tries to inflate the view in my OnCreateView function.
The error I am getting is:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.MyCompany.ChartTest/com.MyCompany.ChartTest.MainActivity}:
android.view.InflateException: Binary XML file line #5: Error
inflating class com.github.mikephil.charting.charts.LineChart
I honestly do not see anything that could be wrong.
The only difference I see between the Fragments used in the example project is that they use wrap_content instead of match_parent for the width and height of the chart.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.github.mikephil.charting.charts.LineChart
android:id="#+id/lineChart1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
I've managed to confirm where the problem is.
I have my apps theme defined in a library that is used by my various other apps, but for some reason when referencing the theme from the library when using MPAndroidChartLib I get this exception. If I copy and paste the theme style from my Library and it to my apps own styles file and reference this instead it works fine.
Try this, it may help:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.LineChart
android:id="#+id/lineChart1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
The line:
xmlns:app="http://schemas.android.com/apk/res-auto"
is important.
I hope it helps.
I struggled with this exact issue and finally found a working solution.
The clue was an error message on the design preview of the chart fragment:
The following classes could not be instantiated:
charting.charts.LineChart
Exception Details
java.lang.ClassNotFoundException:
com.nineoldandroids.animation.ValueAnimator$AnimatorUpdateListener
Adding com.nineoldandroids:library:2.4.+ to my project's build.gradle file fixed the issue:
dependencies {
compile 'com.android.support:support-v4:19.1.0'
compile 'joda-time:joda-time:2.5'
compile 'com.nineoldandroids:library:2.4.+'
compile files('libs/MPChart.jar')
}
Adding lines below in onCreate() did the trick for me
getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

Add ViewPager to Activity which extends superclass with a Navigation Drawer

I have several activities which extend my class DrawerActivity, so they will have a navigation drawer. Only one of these activities requires a ViewPager.
Question: How can I add a ViewPager to only one of the activities, ActivityA?
I am somewhat familiar with creating a ViewPager, but in this situation I'm unsure of where to put the ViewPager code, and what layouts to use. I've seen a few examples including the official tutorial on Google's developer site, but I'm not sure how to best implement it into my application.
I've provided some relevant code below, but please let me know if you need to see more. Any advice is appreciated, thanks!
In DrawerActivity's onCreate:
setContentView(R.layout.activity_fragment);
if (fragment == null)
{
fragment = createFragment();
fm.beginTransaction()
.add(R.id.fragmentContainer, fragment)
.commit();
}
Layout activity_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
<ListView android:id="#+id/leftDrawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
In ActivityA:
public class ActivityA extends DrawerActivity
{
//this is all I do in this activity
#Override
protected Fragment createFragment()
{
UUID id = (UUID) getIntent().getSerializableExtra(FragmentA.EXTRA_ID);
return FragmentA.newInstance(id);
}
}
In FragmentA's onCreateView:
View v = inflater.inflate(R.layout.fragment_a, parent, false);
Layout fragment_a.xml is a simple LinearLayout with a few Button and TableLayout children.
fragment_a.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.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
and create an adapter for example FragmentStatePagerAdapter and fill it with what you want to show in viewpager. notice that because you are using viewpager inside a fragment you should pass ChildFragmentManaget instead of activity FragmentManager.

Categories

Resources