简体   繁体   中英

How to slide the main layout and force it to resize?

I want to create an text editor with options at the top (bold,..). I also want to be able to hide those options; using the exact transition style shown in the picture below. My problem is that the EditText that I use never has the intended behavious. (In the GIF below for exemple it does not resize after being moved).

例


I tried using animate (which is what is shown here on the picture). I also tried with layout animation, combined with setVisibility(View.GONE) when the animation ends (its nearly perfect but for one frame between the two we can see what's happening). I finally tried setting android:animateLayoutChanges="true" . Which works great but I cannot animate the transition as I want.

I also tried combining the three in various ways, but never was successful.

public class MainActivity extends AppCompatActivity {
boolean optionVisible = true;
LinearLayout Main;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Main = findViewById(R.id.main);

}

public void show(View v) {
    if (optionVisible) {
        Main.animate().setDuration(300).translationYBy(-Options.getHeight());
    } else {
        Main.animate().setDuration(300).translationYBy(Options.getHeight());
    }
    optionVisible = !optionVisible;
}
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout
    android:id="@+id/options"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:fillAfter="true">

        ... Defining buttons and slider ...

</LinearLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp">

       ... Defining Title EditText ...

</RelativeLayout>


 <EditText
     android:id="@+id/writter"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_margin="10dp"
     android:gravity="top"
     android:padding="0dp"
     android:text="azertyuio"
     android:textAlignment="gravity"
     android:textColor="@color/text"
     android:textSize="20sp"
     tools:ignore="HardcodedText"
     android:background="@null"
     />

</LinearLayout>

Well I finally managed to get it working properly. I still find the solution akward and would be glad to here another suggestion.

Anyway what I finally did was to use Animations (and not animate), and to have 2 main view basically being set GONE and VISIBLE at oppisite time depending on the presence of options or not.

Here is the code (I used an external class to synchronize the two EditText)

activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<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">

    <LinearLayout
        android:id="@+id/main_with_opt"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:visibility="gone">

        <LinearLayout
            android:id="@+id/options"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:fillAfter="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">


                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <Button
                        style="@style/Widget.AppCompat.Button.Borderless"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:text="@string/underline"/>

                </FrameLayout>

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <Button
                        style="@style/Widget.AppCompat.Button.Borderless"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:text="@string/italic"/>

                </FrameLayout>

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <Button
                        style="@style/Widget.AppCompat.Button.Borderless"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:text="@string/bold"/>

                </FrameLayout>

            </LinearLayout>


            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:id="@+id/size"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="aA"
                    android:paddingHorizontal="10dp"
                    android:paddingVertical="5dp"
                    tools:ignore="HardcodedText"
                    android:layout_alignParentStart="true"/>

                <SeekBar
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_toEndOf="@id/size"
                    android:layout_toStartOf="@+id/size_int"/>

                <TextView
                    android:id="@+id/size_int"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/text_size"
                    android:paddingHorizontal="10dp"
                    android:paddingVertical="5dp"
                    tools:ignore="HardcodedText"
                    android:layout_alignParentEnd="true"/>

            </RelativeLayout>

        </LinearLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp">

            <EditText
                android:id="@+id/title_with_opt"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:lines="1"
                android:text="@string/title"
                android:maxLines="1"
                android:textColor="@color/title"
                android:layout_marginStart="10dp"
                android:layout_toStartOf="@+id/arrow_with_opt"/>

            <ImageButton
                style="@style/Widget.AppCompat.Button.Borderless"
                android:id="@+id/arrow_with_opt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true"
                android:src="@drawable/arrow_less"
                android:onClick="show"/>

        </RelativeLayout>


         <com.example.mynotes.SyncEditText
             android:id="@+id/typer_with_opt"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_margin="10dp"
             android:gravity="top"
             android:padding="0dp"
             android:textAlignment="gravity"
             android:textColor="@color/text"
             android:textSize="20sp"
             android:background="@null"
             />

    </LinearLayout>

    <LinearLayout
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp">

            <EditText
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLines="1"
                android:text="@string/title"
                android:textColor="@color/title"
                android:layout_marginStart="10dp"
                android:layout_toStartOf="@+id/arrow"/>

            <ImageButton
                style="@style/Widget.AppCompat.Button.Borderless"
                android:id="@+id/arrow"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true"
                android:src="@drawable/arrow_less"
                android:onClick="show"/>

        </RelativeLayout>


        <com.example.mynotes.SyncEditText
            android:id="@+id/typer"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:gravity="top"
            android:padding="0dp"
            android:textAlignment="gravity"
            android:textColor="@color/text"
            android:textSize="20sp"
            android:background="@null"
            />

    </LinearLayout>

</FrameLayout>

Main Activity.java :

package com.example.mynotes;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {
    LinearLayout Options;
    boolean optionVisible = false;
    LinearLayout Main;
    LinearLayout Main_with_opt;
    LayoutAnimationController show_lessAnimation;
    LayoutAnimationController show_moreAnimation;
    com.example.mynotes.SyncEditText Typer;
    com.example.mynotes.SyncEditText Typer_with_opt;
    int mSelection;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Main_with_opt = findViewById(R.id.main_with_opt);
        Options = findViewById(R.id.options);

        Main = findViewById(R.id.main);

        Typer = findViewById(R.id.typer);
        Typer_with_opt = findViewById(R.id.typer_with_opt);

        Typer.setDependencies(Typer_with_opt);
        Typer_with_opt.setDependencies(Typer);

        show_lessAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.show_less_layout);
        show_moreAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.show_more_layout);
    }

    public void show(View v) {
        if (optionVisible) {
            Main_with_opt.setLayoutAnimationListener(show_lessAnimationListener);
            Main_with_opt.setLayoutAnimation(show_lessAnimation);
            Typer.requestFocus();
            Typer.setSelection(Typer_with_opt.getSelectionStart());
            Typer.scrollTo(Typer_with_opt.getScrollX(), Typer_with_opt.getScrollY());
            Main_with_opt.startLayoutAnimation();
        } else {
            Main_with_opt.setLayoutAnimationListener(show_moreAnimationListener);
            Main_with_opt.setLayoutAnimation(show_moreAnimation);
            Main_with_opt.setVisibility(View.VISIBLE);
            Typer_with_opt.requestFocus();
            Typer_with_opt.setSelection(Typer.getSelectionStart());
            Typer_with_opt.scrollTo(Typer.getScrollX(), Typer.getScrollY());
            Main.setVisibility(View.GONE);
            Main_with_opt.startLayoutAnimation();
        }
        optionVisible = !optionVisible;
    }

    Animation.AnimationListener show_lessAnimationListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            Main.setVisibility(View.VISIBLE);
            Main_with_opt.setVisibility(View.GONE);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };

    Animation.AnimationListener show_moreAnimationListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };

}

And the cutom class : SyncEditText.java :

package com.example.mynotes;

import android.content.Context;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;

public class SyncEditText extends AppCompatEditText implements TextWatcher {
    private SyncEditText[] mDependencies;
    private boolean shouldSync = true;

    public SyncEditText(Context context) {
        super(context);
    }

    public SyncEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SyncEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        // This is to avoid text changed event is called multiple time per character because auto suggestion
        setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

        addTextChangedListener(this);
    }

    private void addTextChangedListener(SyncEditText syncEditText) {
    }

    public void setDependencies(SyncEditText... dependencies) {
        mDependencies = dependencies;
    }

    public void setText(CharSequence text, boolean syncDependencies) {
        shouldSync = syncDependencies;
        setText(text);

        Log.d("Log", "Text sync: " + text);
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

    @Override
    public void afterTextChanged(Editable editable) { }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        if (mDependencies == null)
            return;

        if (!shouldSync) {
            // If this text is sync from other SyncEditText, ignore the change
            shouldSync = true;
            return;
        }

        Log.d("Log", "Text input: " + charSequence);

        // Sync to all dependencies
        for (SyncEditText syncEditText : mDependencies) {
            syncEditText.setText(charSequence, false);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM