2

So to tell you exactly what's going on, let me explain the context first.

I followed this tutorial : https://viksaaskool.wordpress.com/2014/11/16/using-auto-resize-to-fit-edittext-in-android/

which is basically a simple autoresizeEditText, based on the autoFitTextView library ( https://github.com/grantland/android-autofittextview ).

What I want to achieve : When I click on a button, the entire layout is zoomed in, and I simulate a click on the editText to let the user enter some text.

What I have been achieving so far : well, pretty much everything, excepts that it only works on some devices, and not on others.

FYI, here are two animated gifs that'll illustrate what I'm talking about :

GOOD BEHAVIOUR(Nexus 5 API 21) : http://giphy.com/gifs/xTiTnH1hyuJzjnDl6w

BAD BEHAVIOUR(Nexus 6 API 22) : http://giphy.com/gifs/3-1-2-3o85xDB4Wyve1jh0XK

As you can see, zooming is fine, then entering text is fine until, in some cases, the text won't appear after what seems to be the right-hand-side of the unzoomed editText. But as soon as the text size has to be changed (or I zoom out the views), everything goes back to normal.

So my question : anyone would have an idea of what could make this strange behaviour? Anyone encountered this problem, either on the autoFitTextView or an extension of it?

Thanks in advance!

PS : I could post some code, but as both libraries + links are provided and are pretty long, I prefer not posting them here, as they're basically the same. What I can provide though is the calls made to animate the views and show the keyboard (even if I'm not sure it's related) :

@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);
}
NSimon
  • 5,212
  • 2
  • 22
  • 36
  • 1
    I'm not sure what I'm seeing in the animations (not smooth enough maybe?). But have you tried other ways to animate? The one you used is of the old API of Android (pre-Honeycomb). Try using "view.animate()...." , or even try animating the layout itself if needed (example here: http://stackoverflow.com/a/19616416/878126 ) . The reason that I suggest those is that the old API doesn't really change the size and/or position of the views, just how they look. – android developer Mar 31 '15 at 21:24
  • That's an approach I didn't realize @androiddeveloper, I'll definitely test this tomorrow morning, and hopefully this could solve this problem. It would seem any that for some reason, it's actually changing size/position of the views on some devices/APIs, but not on others. I'll keep you posted asap, but thanks for the tip! – NSimon Mar 31 '15 at 21:42
  • Using the old API should never change the size/position of views. You can make a POC in order to see this behavior: make a button that upon clicking will show a toast. set an animation that moves it from one place to another and let it stay there. try clicking the button. The button isn't clickable on its new position because it's not really there. clicking on the original location would trigger the clicking event. Same goes if you try to change its size using the old API animation. – android developer Apr 01 '15 at 08:49
  • @androiddeveloper Your solution is working like a charm, I moved to the new animation system with animate() and I don't have any more problem, on any device! Would you mind writing a short brief on that as an answer, so that I can accept it? BTW, Thanks ! – NSimon Apr 01 '15 at 09:00

1 Answers1

0

Okay, so thanks to @android developer who pointed out the problem, this was caused by the old version of the animations I was using.

So by replacing

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);

by the new ones :

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;
                }
            });

resolved everything.

NSimon
  • 5,212
  • 2
  • 22
  • 36
  • Happy you've made it. Do note that this will work only starting from certain API. It will be quite challenging to make it work on old versions of Android (API 10 and below, for example). – android developer Apr 12 '15 at 06:20