android-autofittextview 库的变体:缩放会产生奇怪的行为
Variant from android-autofittextview library : scaling makes strange behaviour
所以为了准确地告诉你发生了什么,让我先解释一下上下文。
我遵循了本教程:
https://viksaaskool.wordpress.com/2014/11/16/using-auto-resize-to-fit-edittext-in-android/
这基本上是一个简单的 autoresizeEditText,基于 autoFitTextView 库 (https://github.com/grantland/android-autofittextview)。
我想要实现的:当我点击一个按钮时,整个布局被放大,我模拟点击 editText 让用户输入一些文本。
到目前为止我取得的成就:好吧,几乎所有的东西,除了它只适用于某些设备,而不适用于其他设备。
仅供参考,这里有两个 gif 动画可以说明我在说什么:
行为良好(Nexus 5 API 21):http://giphy.com/gifs/xTiTnH1hyuJzjnDl6w
不良行为(Nexus 6 API 22):http://giphy.com/gifs/3-1-2-3o85xDB4Wyve1jh0XK
如您所见,缩放很好,然后输入文本也很好,直到在某些情况下,文本不会出现在似乎是未缩放的 editText 的右侧之后。但是一旦必须更改文本大小(或者我缩小视图),一切都会恢复正常。
所以我的问题是:任何人都知道是什么导致了这种奇怪的行为?
有人在 autoFitTextView 或其扩展上遇到过这个问题吗?
提前致谢!
PS :我可以 post 一些代码,但是由于提供了两个库 + 链接并且很长,我不希望在这里 posting 它们,因为它们是基本一样。我可以提供的是为视图设置动画和显示键盘的调用(即使我不确定它是否相关):
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.add_message_layout, null);
mMessageEditText = (AutoResizeEditText) mView.findViewById(R.id.messageEditText);
mMessageEditText.setEnabled(false);
mMessageEditText.setEnableSizeCache(false);
mMessageEditText.setMovementMethod(null);
mMessageEditText.setInterface(this);
mMessageEditText.setMinTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, MIN_SP_TEXT_SIZE, getResources().getDisplayMetrics()));
mMessageEditText.setMaxHeight((int) DisplayUtils.convertDpToPixel(getActivity().getApplicationContext(), mMessageEditText.getMeasuredHeight()));
mMessageEditText.setLines(MAX_LINES_COUNT);
mMessageEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
mLastMessage = mMessageEditText.getText().toString();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mMessageEditText.getLineCount() > MAX_LINES_COUNT) {
//If user tries to type more text than expected !
mMessageEditText.setText(mLastMessage);
mMessageEditText.setSelection(mLastMessage.length());
Toast.makeText(getActivity().getApplicationContext(), "Limit Reached", Toast.LENGTH_SHORT).show();
}
}
@Override
public void afterTextChanged(Editable s) {
mLastMessage = mMessageEditText.getText().toString();
mMessageEditText.invalidate();
}
});
mAddMessageButton = (RelativeLayout) mView.findViewById(R.id.rlAddMessage);
mAddMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setupAnimations();
animZoomIn();
}
});
mCardLayout = (LinearLayout) mView.findViewById(R.id.rearMainCardLayout);
return (mView);
}
private void setupAnimations() {
mPivotX = mMessageEditText.getPivotX() / mCardLayout.getMeasuredHeight();
mPivotY = mMessageEditText.getPivotY() / mCardLayout.getMeasuredWidth();
mZoomIn = new ScaleAnimation(1.0f, 1.3f, 1.0f, 1.3f, mPivotX, mPivotY);
mZoomIn.setDuration(1000);
mZoomIn.setFillAfter(true);
mSlideUp = new TranslateAnimation(0.0f, 100.0f, 0.0f, -100.0f);
mSlideUp.setDuration(1000);
mSlideUp.setFillAfter(true);
mEnterAnimation = new AnimationSet(true);
mEnterAnimation.setInterpolator(new LinearInterpolator());
mEnterAnimation.addAnimation(mZoomIn);
mEnterAnimation.addAnimation(mSlideUp);
mEnterAnimation.setFillAfter(true);
mEnterAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mBeginX = mMessageEditText.getLeft();
mBeginY = mMessageEditText.getTop();
}
@Override
public void onAnimationEnd(Animation animation) {
mMessageEditText.setPressed(true); //EditText will get highlighted
mMessageEditText.setFocusable(true);
mMessageEditText.setFocusableInTouchMode(true);
mMessageEditText.setTextIsSelectable(true);
mMessageEditText.requestFocus();
mMessageEditText.invalidate();
mMessageEditText.setEnabled(true);
showKeyboard(getActivity().getApplicationContext(), mMessageEditText);
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
mZoomOut = new ScaleAnimation(1.3f, 1.0f, 1.3f, 1.0f, mPivotX, mPivotY);
mZoomOut.setDuration(1000);
mZoomOut.setFillAfter(true);
mSlideDown = new TranslateAnimation(100.0f, 0.0f, -100.0f, 0.0f);
mSlideDown.setDuration(1000);
mSlideDown.setFillAfter(true);
mExitAnimation = new AnimationSet(true);
mExitAnimation.setInterpolator(new LinearInterpolator());
mExitAnimation.addAnimation(mZoomOut);
mExitAnimation.addAnimation(mSlideDown);
mExitAnimation.setFillAfter(true);
mExitAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
mMessageEditText.invalidate();
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
}
private void animZoomIn() {
mCardLayout.startAnimation(mEnterAnimation);
}
private void animZoomOut() {
mCardLayout.startAnimation(mExitAnimation);
}
private static void closeKeyboard(Context c, IBinder windowToken) {
InputMethodManager manager = (InputMethodManager)c.getSystemService(Context.INPUT_METHOD_SERVICE);
manager.hideSoftInputFromWindow(windowToken, 0);
}
private static void showKeyboard(Context c, EditText text) {
InputMethodManager manager = (InputMethodManager) c.getSystemService(Context.INPUT_METHOD_SERVICE);
manager.showSoftInput(text, InputMethodManager.SHOW_IMPLICIT);
}
好的,感谢指出问题的@android开发者,这是我使用的旧版本动画造成的。
所以通过替换
mZoomOut = new ScaleAnimation(1.3f, 1.0f, 1.3f, 1.0f, mPivotX, mPivotY);
mZoomOut.setDuration(1000);
mZoomOut.setFillAfter(true);
mSlideDown = new TranslateAnimation(100.0f, 0.0f, -100.0f, 0.0f);
mSlideDown.setDuration(1000);
mSlideDown.setFillAfter(true);
mExitAnimation = new AnimationSet(true);
mExitAnimation.setInterpolator(new LinearInterpolator());
mExitAnimation.addAnimation(mZoomOut);
mExitAnimation.addAnimation(mSlideDown);
mExitAnimation.setFillAfter(true);
mExitAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
mMessageEditText.invalidate();
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
mCardLayout.startAnimation(mEnterAnimation);
来自新的:
mCardLayout.animate().translationX(0.0f).translationY(0.0f).scaleX(1.0f).scaleY(1.0f).setDuration(1000).withEndAction(new Runnable() {
@Override
public void run() {
mMessageEditText.invalidate();
mIsViewZoomed = false;
}
});
一切都解决了。
所以为了准确地告诉你发生了什么,让我先解释一下上下文。
我遵循了本教程: https://viksaaskool.wordpress.com/2014/11/16/using-auto-resize-to-fit-edittext-in-android/
这基本上是一个简单的 autoresizeEditText,基于 autoFitTextView 库 (https://github.com/grantland/android-autofittextview)。
我想要实现的:当我点击一个按钮时,整个布局被放大,我模拟点击 editText 让用户输入一些文本。
到目前为止我取得的成就:好吧,几乎所有的东西,除了它只适用于某些设备,而不适用于其他设备。
仅供参考,这里有两个 gif 动画可以说明我在说什么:
行为良好(Nexus 5 API 21):http://giphy.com/gifs/xTiTnH1hyuJzjnDl6w
不良行为(Nexus 6 API 22):http://giphy.com/gifs/3-1-2-3o85xDB4Wyve1jh0XK
如您所见,缩放很好,然后输入文本也很好,直到在某些情况下,文本不会出现在似乎是未缩放的 editText 的右侧之后。但是一旦必须更改文本大小(或者我缩小视图),一切都会恢复正常。
所以我的问题是:任何人都知道是什么导致了这种奇怪的行为? 有人在 autoFitTextView 或其扩展上遇到过这个问题吗?
提前致谢!
PS :我可以 post 一些代码,但是由于提供了两个库 + 链接并且很长,我不希望在这里 posting 它们,因为它们是基本一样。我可以提供的是为视图设置动画和显示键盘的调用(即使我不确定它是否相关):
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.add_message_layout, null);
mMessageEditText = (AutoResizeEditText) mView.findViewById(R.id.messageEditText);
mMessageEditText.setEnabled(false);
mMessageEditText.setEnableSizeCache(false);
mMessageEditText.setMovementMethod(null);
mMessageEditText.setInterface(this);
mMessageEditText.setMinTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, MIN_SP_TEXT_SIZE, getResources().getDisplayMetrics()));
mMessageEditText.setMaxHeight((int) DisplayUtils.convertDpToPixel(getActivity().getApplicationContext(), mMessageEditText.getMeasuredHeight()));
mMessageEditText.setLines(MAX_LINES_COUNT);
mMessageEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
mLastMessage = mMessageEditText.getText().toString();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mMessageEditText.getLineCount() > MAX_LINES_COUNT) {
//If user tries to type more text than expected !
mMessageEditText.setText(mLastMessage);
mMessageEditText.setSelection(mLastMessage.length());
Toast.makeText(getActivity().getApplicationContext(), "Limit Reached", Toast.LENGTH_SHORT).show();
}
}
@Override
public void afterTextChanged(Editable s) {
mLastMessage = mMessageEditText.getText().toString();
mMessageEditText.invalidate();
}
});
mAddMessageButton = (RelativeLayout) mView.findViewById(R.id.rlAddMessage);
mAddMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setupAnimations();
animZoomIn();
}
});
mCardLayout = (LinearLayout) mView.findViewById(R.id.rearMainCardLayout);
return (mView);
}
private void setupAnimations() {
mPivotX = mMessageEditText.getPivotX() / mCardLayout.getMeasuredHeight();
mPivotY = mMessageEditText.getPivotY() / mCardLayout.getMeasuredWidth();
mZoomIn = new ScaleAnimation(1.0f, 1.3f, 1.0f, 1.3f, mPivotX, mPivotY);
mZoomIn.setDuration(1000);
mZoomIn.setFillAfter(true);
mSlideUp = new TranslateAnimation(0.0f, 100.0f, 0.0f, -100.0f);
mSlideUp.setDuration(1000);
mSlideUp.setFillAfter(true);
mEnterAnimation = new AnimationSet(true);
mEnterAnimation.setInterpolator(new LinearInterpolator());
mEnterAnimation.addAnimation(mZoomIn);
mEnterAnimation.addAnimation(mSlideUp);
mEnterAnimation.setFillAfter(true);
mEnterAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mBeginX = mMessageEditText.getLeft();
mBeginY = mMessageEditText.getTop();
}
@Override
public void onAnimationEnd(Animation animation) {
mMessageEditText.setPressed(true); //EditText will get highlighted
mMessageEditText.setFocusable(true);
mMessageEditText.setFocusableInTouchMode(true);
mMessageEditText.setTextIsSelectable(true);
mMessageEditText.requestFocus();
mMessageEditText.invalidate();
mMessageEditText.setEnabled(true);
showKeyboard(getActivity().getApplicationContext(), mMessageEditText);
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
mZoomOut = new ScaleAnimation(1.3f, 1.0f, 1.3f, 1.0f, mPivotX, mPivotY);
mZoomOut.setDuration(1000);
mZoomOut.setFillAfter(true);
mSlideDown = new TranslateAnimation(100.0f, 0.0f, -100.0f, 0.0f);
mSlideDown.setDuration(1000);
mSlideDown.setFillAfter(true);
mExitAnimation = new AnimationSet(true);
mExitAnimation.setInterpolator(new LinearInterpolator());
mExitAnimation.addAnimation(mZoomOut);
mExitAnimation.addAnimation(mSlideDown);
mExitAnimation.setFillAfter(true);
mExitAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
mMessageEditText.invalidate();
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
}
private void animZoomIn() {
mCardLayout.startAnimation(mEnterAnimation);
}
private void animZoomOut() {
mCardLayout.startAnimation(mExitAnimation);
}
private static void closeKeyboard(Context c, IBinder windowToken) {
InputMethodManager manager = (InputMethodManager)c.getSystemService(Context.INPUT_METHOD_SERVICE);
manager.hideSoftInputFromWindow(windowToken, 0);
}
private static void showKeyboard(Context c, EditText text) {
InputMethodManager manager = (InputMethodManager) c.getSystemService(Context.INPUT_METHOD_SERVICE);
manager.showSoftInput(text, InputMethodManager.SHOW_IMPLICIT);
}
好的,感谢指出问题的@android开发者,这是我使用的旧版本动画造成的。
所以通过替换
mZoomOut = new ScaleAnimation(1.3f, 1.0f, 1.3f, 1.0f, mPivotX, mPivotY);
mZoomOut.setDuration(1000);
mZoomOut.setFillAfter(true);
mSlideDown = new TranslateAnimation(100.0f, 0.0f, -100.0f, 0.0f);
mSlideDown.setDuration(1000);
mSlideDown.setFillAfter(true);
mExitAnimation = new AnimationSet(true);
mExitAnimation.setInterpolator(new LinearInterpolator());
mExitAnimation.addAnimation(mZoomOut);
mExitAnimation.addAnimation(mSlideDown);
mExitAnimation.setFillAfter(true);
mExitAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
mMessageEditText.invalidate();
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
mCardLayout.startAnimation(mEnterAnimation);
来自新的:
mCardLayout.animate().translationX(0.0f).translationY(0.0f).scaleX(1.0f).scaleY(1.0f).setDuration(1000).withEndAction(new Runnable() {
@Override
public void run() {
mMessageEditText.invalidate();
mIsViewZoomed = false;
}
});
一切都解决了。