[英]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.
我的问题是我使用的EditText从来没有预期的行为。 (In the GIF below for exemple it does not resize after being moved).
(例如,在下面的GIF中,移动后不会调整大小)。
I tried using animate (which is what is shown here on the picture). 我尝试使用animate(这是图片上显示的内容)。 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). 我还尝试了布局动画,结合动画结束时的
setVisibility(View.GONE)
(它几乎完美但两者之间的一帧我们可以看到发生了什么)。 I finally tried setting android:animateLayoutChanges="true"
. 我终于尝试设置
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. 我也试过以各种方式将三者结合起来,但从未取得过成功。
Java:
Java的:
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:
XML:
<?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. 无论如何,我最终做的是使用动画(而不是动画),并且根据选项的存在,有2个主视图基本上在反对时间设置为GONE和VISIBLE。
Here is the code (I used an external class to synchronize the two EditText) 这是代码(我使用外部类来同步两个EditText)
activity_main.xml : 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 : 主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 : 而cutom类: 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);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.