Reputation: 1618
I am trying to implement Collapsing Toolbar By Using ConstraintLayout. After Trying a lot, I couldn't able to get the desire effects.I have follow this link in youtube (https://www.youtube.com/watch?v=8lAXJ5NFXTM at the 21 min). My Source code is:-
activity.main.xml:-
<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"
tools:context=".activities.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:theme="@style/AppTheme.AppBarOverlay"
android:fitsSystemWindows="false">
<com.example.study.helpers.NoAnimCollapsibleConstraintLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:minHeight="40dp"
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"/>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<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="@drawable/ic_border_color_white_24dp"/>
</android.support.design.widget.CoordinatorLayout>
content_main.xml:-
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activities.MainActivity"
tools:showIn="@layout/activity_main">
<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/some_long_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
NoAnimCollapsibleConstraintLayout.java:-
import android.content.Context;
import android.support.constraint.ConstraintLayout;
import android.support.constraint.ConstraintSet;
import android.support.design.widget.AppBarLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Toast;
import com.example.study.R;
public class NoAnimCollapsibleConstraintLayout extends ConstraintLayout implements AppBarLayout.OnOffsetChangedListener {
private static final String TAG = NoAnimCollapsibleConstraintLayout.class.getSimpleName();
private float mTransitionThreshold = 0.35f;
private int mLastPosition = 0;
private boolean mToolbarOpen = true;
private ConstraintSet mOpenToolbarSet = new ConstraintSet();
private ConstraintSet mCloseToolbarSet = new ConstraintSet();
public NoAnimCollapsibleConstraintLayout(Context context) { super(context, null); }
public NoAnimCollapsibleConstraintLayout(Context context, AttributeSet attrs) { super(context, attrs, 0); }
public NoAnimCollapsibleConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (getParent() instanceof AppBarLayout){
Log.d(TAG, "Instance AppBarLayout");
AppBarLayout appBarLayout = (AppBarLayout)getParent();
appBarLayout.addOnOffsetChangedListener(this);
mOpenToolbarSet.clone(getContext(), R.layout.open);
mCloseToolbarSet.clone(getContext(), R.layout.close);
}else {
Log.d(TAG, "Instance if Not Parent");
}
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
Log.d(TAG, "onOffsetChanged");
if (mLastPosition == verticalOffset){
return;
}
mLastPosition = verticalOffset;
Float progress = ( Math.abs(verticalOffset / (float) (appBarLayout.getHeight()))) ;
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) getLayoutParams();
params.topMargin = -verticalOffset;
setLayoutParams(params);
if ( mToolbarOpen && progress > mTransitionThreshold) {
Log.d(TAG, "Apply close.xml");
mCloseToolbarSet.applyTo(this);
mToolbarOpen = false;
}else if ( !mToolbarOpen && progress < mTransitionThreshold){
Log.d(TAG, "Apply open.xml");
mOpenToolbarSet.applyTo(this);
mToolbarOpen = true;
}
}
}
open.xml:-
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/open"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:contentDescription="@string/app_name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/study" />
</android.support.constraint.ConstraintLayout>
close.xml:-
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/close"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView4"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/app_name"
android:textColor="@android:color/white"
android:textSize="@dimen/text_size_16"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
After Applying this code open.xml and close.xml design not shown when I am trying to collapse Toolbar. This is the screenshot which I am getting in output:-
Without Collapse (open.xml design missing) :- https://www.dropbox.com/s/c0rh126rinmopd4/Screen_Shot1.png?dl=0)
With Collpase (close.xml design missing):- https://www.dropbox.com/s/cdlbg84lmht3gv0/Screen_Shot2.png?dl=0
Upvotes: 1
Views: 2541
Reputation: 969
I've been trying to do the same thing after watching the video.
Add the id "constraint" to both root ConstraintLayout
You did inflate your view in NoAnimCollapsibleConstraintLayout, so inflate and then find constraint view
import android.content.Context;
import android.support.constraint.ConstraintLayout;
import android.support.constraint.ConstraintSet;
import android.support.design.widget.AppBarLayout;
import android.support.transition.TransitionManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
public class NoAnimCollapsibleConstraintLayout extends ConstraintLayout
implements AppBarLayout.OnOffsetChangedListener {
private static final String TAG = NoAnimCollapsibleConstraintLayout.class.getSimpleName();
private float mTransitionThreshold = 0.35f;
private int mLastPosition = 0;
private boolean mToolbarOpen = true;
private ConstraintSet mOpenToolbarSet = new ConstraintSet();
private ConstraintSet mCloseToolbarSet = new ConstraintSet();
private ConstraintLayout constraint;
public NoAnimCollapsibleConstraintLayout(Context context) {
this(context, null);
}
public NoAnimCollapsibleConstraintLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public NoAnimCollapsibleConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(getContext()).inflate(R.layout.open, this, true);
constraint = findViewById(R.id.constraint);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (getParent() instanceof AppBarLayout) {
Log.d(TAG, "Instance AppBarLayout");
AppBarLayout appBarLayout = (AppBarLayout) getParent();
appBarLayout.addOnOffsetChangedListener(this);
mOpenToolbarSet.clone(constraint);
mCloseToolbarSet.clone(getContext(), R.layout.close);
} else {
Log.d(TAG, "Instance if Not Parent");
}
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
Log.d(TAG, "onOffsetChanged");
if (mLastPosition == verticalOffset) {
return;
}
mLastPosition = verticalOffset;
Float progress = (Math.abs(verticalOffset / (float) (appBarLayout.getHeight())));
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) getLayoutParams();
params.topMargin = -verticalOffset;
setLayoutParams(params);
TransitionManager.beginDelayedTransition(constraint);
if (mToolbarOpen && progress > mTransitionThreshold) {
Log.d(TAG, "Apply close.xml");
mCloseToolbarSet.applyTo(constraint);
mToolbarOpen = false;
} else if (!mToolbarOpen && progress < mTransitionThreshold) {
Log.d(TAG, "Apply open.xml");
mOpenToolbarSet.applyTo(constraint);
mToolbarOpen = true;
}
}
}
This has an animation in and it seems to work for me. try and make sure the same view is in both, even if it is just to move it or visibility gone
EDIT: https://github.com/BigFishStudios/ConstraintToolbar here is a code example of this working
Hope this helps :D
Upvotes: 3