I'm developing an android app and I'm stuck in organizing the layout in a input form activity. I would like to organize the layout of my activity like this sample (found in google android's docs): https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0Bzhp5Z4wHba3Skg2b19UVS1LSmc/components_textfields_labels2.png . So a big app bar will contain one or two text field, referencing the name and the description of a user's activity, and within the activity layout's content the rest of input controls. The behaviour I would reach is:
- the activity title is initially empty and toolbar collapsed
- when I get down the toolbar the text input appear and the user insert some text
- when the user collapse the toolbar, the activity title (that is, the toolbar title) must be set to the input text value
The problem is that only one time this mechanism works: once set value and collapse the toolbar, when I get down again the toolbar, set the text input value and collapse the toolbar, the title is not setted, that is, setTitle has no effect over the first time.
I will now list my code: I tried to use a custom app bar layout, a collapsing tool bar layout, a toolbar and a text input in the following way:
<?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="wrap_content"
android:orientation="vertical"
tools:context="com.example.davide.inputformapp.MainActivity">
<com.example.davide.inputformapp.MyAppBarLayout.MyAppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="400dp"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="@dimen/activity_horizontal_margin"
app:expandedTitleMarginStart="@dimen/activity_horizontal_margin"
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="parallax"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TextInputEditText
android:id="@+id/textInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.design.widget.CollapsingToolbarLayout>
</com.example.davide.inputformapp.MyAppBarLayout.MyAppBarLayout>
</android.support.design.widget.CoordinatorLayout>
where MyAppBarLayout is the class defined in this way(the code is not mine, I found here in a stackoverflow discussion):
public class MyAppBarLayout extends AppBarLayout
implements AppBarLayout.OnOffsetChangedListener {
private State state;
private OnStateChangeListener onStateChangeListener;
public MyAppBarLayout(Context context) {
super(context);
}
public MyAppBarLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!(getLayoutParams() instanceof CoordinatorLayout.LayoutParams)
|| !(getParent() instanceof CoordinatorLayout)) {
throw new IllegalStateException(
"MyAppBarLayout must be a direct child of CoordinatorLayout.");
}
addOnOffsetChangedListener(this);
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (verticalOffset == 0) {
if (onStateChangeListener != null && state != State.EXPANDED) {
Log.d("MYAPP","---> EXPANDED");
onStateChangeListener.onStateChange(State.EXPANDED);
}
state = State.EXPANDED;
} else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
if (onStateChangeListener != null && state != State.COLLAPSED) {
Log.d("MYAPP","---> COLLAPSED");
onStateChangeListener.onStateChange(State.COLLAPSED);
}
state = State.COLLAPSED;
} else {
if (onStateChangeListener != null && state != State.IDLE) {
Log.d("MYAPP","---> IDLE");
onStateChangeListener.onStateChange(State.IDLE);
}
state = State.IDLE;
}
}
public void setOnStateChangeListener(OnStateChangeListener listener) {
this.onStateChangeListener = listener;
}
public interface OnStateChangeListener {
void onStateChange(State toolbarChange);
}
public enum State {
COLLAPSED,
EXPANDED,
IDLE
}
}
The code in the main activity's onCreate() method is:
toolbar = (Toolbar) findViewById(R.id.toolbar);
textInput = (TextInputEditText) findViewById(R.id.textInput);
final MyAppBarLayout collapsableAppBar = (MyAppBarLayout) findViewById(R.id.appbar);
setSupportActionBar(toolbar);
setTitle(null);
collapsableAppBar.setOnStateChangeListener(new MyAppBarLayout.OnStateChangeListener() {
@Override
public void onStateChange(MyAppBarLayout.State toolbarChange) {
String value = textInput.getText().toString();
toolbar.setTitle(value);
}
});
Any suggestion?
Thanks, davide