3

I'm using TextInputLayout (and TextInputEditText) for the password field, but my app it's breaking when I'm pressing the toggle button on my tablet.

I tested on another devices an the app work like a charm Here's some information:

Worked on
- Nexus 5 - 6.0.1
- Positivo S440 - 4.4.2
- Samsung Galaxy Tab SM-P550 - 6.0.1

Crashed on
- Tablet: Samsung SM-T530
- Android: 5.0.2
- Android Support Design Version: 25.3.1

My XML


android.support.design.widget.TextInputLayout
    android:id="@+id/til_password"
    style="@style/Text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="16dp"
    android:layout_marginStart="16dp"
    android:hint="@string/lbl_password"
    app:passwordToggleEnabled="true"
    app:passwordToggleTint="@color/theme_accent"

    android.support.design.widget.TextInputEditText
        android:id="@+id/inp_password"
        style="@style/Text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@null"
        android:imeOptions="actionDone"
        android:inputType="textPassword"
        android:textColor="@color/theme_accent"
        android:textSize="@dimen/text_size_subhead"

android.support.design.widget.TextInputLayout

My code


public class SyncFragment extends GenericFragment implements TaskCallback,
        View.OnClickListener, WifiAdapter.WifiListener, BackIntercepter, TextView.OnEditorActionListener {

    private TextInputEditText mInpPassword;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.layout_sync, container, false);
        ButterKnife.bind(this, view);
        findViews(view);

        if (getArguments() != null) {
            List wifis = getArguments().getParcelableArrayList(Extras.WIFIS);
            if(wifis != null) {
                Log.d("HACL.TEST", "content extra info: " + Extras.WIFIS);
                Log.d("HACL.TEST", "content wifis: " + wifis.toString());
                updateSpinner(wifis);
                networkId = getArguments().getInt(Extras.NETWORK_ID);
                airConWifiSSID = getArguments().getString(Extras.AIR_CON_WIFI);
            }
        }

        setListeners();
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        try {
            // If return from SyncingFragment, load which Wi-Fi network was selected and show
            // credential screen instead of Wi-Fi list screen
            if(getArguments().getBoolean(Extras.BACK_FROM_SYNCING)) {
                if (getArguments().getParcelable(Extras.WIFI) != null) {
                    Wifi wifi = getArguments().getParcelable(Extras.WIFI);
                    mOutNetwork.setText(wifi.getSsid());
                    mOutNetwork.setTextColor(getResources().getColor(R.color.theme_accent));
                    mOutNetwork.setAlpha(1);
                    mOutNetwork.setTag(wifi);
                    Typeface face = Typeface.createFromAsset(getContext().getAssets(), "fonts/FonteX-Regular.ttf");
                    mOutNetwork.setTypeface(face);
                    mInpPassword.setTypeface(face);
                }
                showCredentials();
            }
            else {
                showList();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void findViews(View view) {
        Typeface face = Typeface.createFromAsset(getContext().getAssets(),"fonts/FontX-Regular.ttf");

        mInpPassword = (TextInputEditText) view.findViewById(R.id.inp_password);
        mInpPassword.setTypeface(face);

        .....
    }

    private void finishSync() {

        if (mOutNetwork.getTag() == null) {
            Toast.makeText(getActivity(), R.string.msg_select_an_network, Toast.LENGTH_SHORT).show();
            return;
        }

        String password = mInpPassword.getText().toString();
        if (verifyPassword(password)) {
            Wifi wifi = (Wifi) mOutNetwork.getTag();
            wifi.setPassphrase(password);

            Bundle bundle = new Bundle();
            bundle.putParcelable(Extras.WIFI, wifi);
            bundle.putParcelableArrayList(Extras.WIFIS, new ArrayList(wifiOnSpinner));
            bundle.putInt(Extras.NETWORK_ID, networkId);
            bundle.putString(Extras.AIR_CON_WIFI, airConWifiSSID);
            getGenericActivity().openMainFragment(SyncingFragment.class, bundle);
        } else {
            Toast.makeText(getActivity(), R.string.msg_password_invalid, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onClick(View v) {
        if (v.equals(mLyNetwork)) {
            try {
                CommonUtils.hideInputKeyboard(getActivity());
            } catch (RuntimeException ignored) {

            }
            showList();
        }

        if (v.equals(mBtnSync)) {
            finishSync();
        }
    }

    @Override
    public void onWifiSelected(Wifi wifi) {
        mOutNetwork.setText(wifi.getSsid());
        mOutNetwork.setTextColor(getResources().getColor(R.color.theme_accent));
        mOutNetwork.setAlpha(1);
        mOutNetwork.setTag(wifi);
        Typeface face = Typeface.createFromAsset(getContext().getAssets(),"fonts/ElectroluxSans-Regular.ttf");
        mOutNetwork.setTypeface(face);
        mInpPassword.setTypeface(face);

        if (wifi.getSecurityType() > 0) {
            showCredentials();
        } else {
            finishSync();
        }
    }

    @Override
    public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
        Wifi tag = (Wifi) mOutNetwork.getTag();
        // If Wi-Fi network has some security type, minimum password length is:
        // For a 64 bit WEP network the password is 5-characters.
        // For a 128 bit WEP network the password is 13-characters.
        // WPA uses either a passphrase (a shared secret) that is comprised of 8 to 63 characters
        if (textView.getText() != null
                && textView.getText().length()  0) {
            mBtnSync.setEnabled(false);
        } else {
            mBtnSync.setEnabled(true);
        }

        if (i == EditorInfo.IME_ACTION_DONE && mBtnSync.isEnabled()) {
            finishSync();
            return true;
        }
        return false;
    }
    public void showCredentials() {
        int duration = getResources().getInteger(android.R.integer.config_mediumAnimTime);
        lyCredentials.setVisibility(View.VISIBLE);
        ViewCompat.animate(listNetwork).alpha(0f)
                .setInterpolator(new DecelerateInterpolator())
                .setDuration(duration)
                .setListener(new ViewPropertyAnimatorListenerAdapter() {

                    @Override
                    public void onAnimationEnd(View view) {
                        listNetwork.setVisibility(View.GONE);
                    }

                })
                .start();
        ViewCompat.animate(lyCredentials).alpha(1f)
                .setStartDelay(duration)
                .setInterpolator(new DecelerateInterpolator())
                .setListener(new ViewPropertyAnimatorListenerAdapter() {

                    @Override
                    public void onAnimationEnd(View view) {
                        mInpPassword.requestFocus();
                        CommonUtils.showInputKeyboard(getActivity(), mInpPassword);
                    }

                })
                .setDuration(duration)
                .start();

        mBtnSync.setEnabled(false);
    }

    @Override
    public void onWifiSelected(Wifi wifi) {
        mOutNetwork.setText(wifi.getSsid());
        mOutNetwork.setTextColor(getResources().getColor(R.color.theme_accent));
        mOutNetwork.setAlpha(1);
        mOutNetwork.setTag(wifi);
        Typeface face = Typeface.createFromAsset(getContext().getAssets(),"fonts/FontX-Regular.ttf");
        mOutNetwork.setTypeface(face);
        mInpPassword.setTypeface(face);

        if (wifi.getSecurityType() > 0) {
            showCredentials();
        } else {
            finishSync();
        }
    }
    private void setListeners() {
        mLyNetwork.setOnClickListener(this);
        mInpPassword.setOnEditorActionListener(this);
        mBtnSync.setOnClickListener(this);
    }
}

And here is the logcat


05-15 09:22:31.199 20164-20164/com.xxxxxxx.yyyyyyyy.zzzz E/AndroidRuntime: FATAL EXCEPTION: 
main
Process: com.xxxxxxxx.yyyyyyyyy.zzzzz, PID: 20164
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at android.graphics.drawable.AnimatedVectorDrawable.start(AnimatedVectorDrawable.java:423)
at android.graphics.drawable.AnimatedStateListDrawable$AnimatedVectorDrawableTransition.start(AnimatedStateListDrawable.java:322)
at android.graphics.drawable.AnimatedStateListDrawable.selectTransition(AnimatedStateListDrawable.java:226)
at android.graphics.drawable.AnimatedStateListDrawable.onStateChange(AnimatedStateListDrawable.java:153)
at android.graphics.drawable.Drawable.setState(Drawable.java:644)
at android.support.v4.graphics.drawable.DrawableWrapperGingerbread.setState(DrawableWrapperGingerbread.java:145)
at android.support.v4.graphics.drawable.DrawableWrapperLollipop.setState(DrawableWrapperLollipop.java:95)
at android.widget.ImageView.drawableStateChanged(ImageView.java:1129)
at android.support.v7.widget.AppCompatImageButton.drawableStateChanged(AppCompatImageButton.java:149)
at android.view.View.refreshDrawableState(View.java:17099)
at android.support.design.widget.CheckableImageButton.setChecked(CheckableImageButton.java:75)
at android.support.design.widget.TextInputLayout.passwordVisibilityToggleRequested(TextInputLayout.java:1302)
at android.support.design.widget.TextInputLayout$4.onClick(TextInputLayout.java:1076)
at android.view.View.performClick(View.java:5214)
at android.view.View$PerformClick.run(View.java:20978)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6134)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

As you can see, the problem is in the android support design library

I found this link below and we have more developers with the same problem.
Google Issue Tracker: Error Support Design

If anyone knows some workaround or solution, please tell us.

groff07
  • 2,363
  • 3
  • 32
  • 48
  • 2
    show xml and java code of using this element – Volodymyr Kulyk May 15 '17 at 12:57
  • @VladimirKulyk I edited my question and put the code and xml – groff07 May 15 '17 at 13:37
  • in general: 1) you did several times `setTypeface`, keep it only in `findViews(View view)`; 2) use `synchronized` modifier for `finishSync()` and `showCredentials`; Suggestions: use `EditText` instead of `android.support.design.widget.TextInputEditText`, read last comment of [this question](http://stackoverflow.com/questions/42009150/nullpointerexception-on-textinputlayout-passwordvisibilitytogglerequested) – Volodymyr Kulyk May 15 '17 at 14:12
  • Ok @VladimirKulyk but I need the toggle button for the user, so the solution I was thinking it will be to create an edit text with an image button and click function or calculating the position of click on the edit text (the position will be exactly above on the drawable of the edit text). What's is your opinion? – groff07 May 15 '17 at 17:22
  • I don't have clear solution. probably it's kind of system bug.. But I can can help you with your idea bellow – Volodymyr Kulyk May 15 '17 at 17:30

1 Answers1

1
{
    //...
    EditText et;
    //...
    //left, top, right, bottom
    et.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.some_icon, 0);
    et.setOnTouchListener(someTouchListener);
    //...
}

private View.OnTouchListener someTouchListener = new OnTouchListener() {
    final int DRAWABLE_LEFT = 0;
    final int DRAWABLE_TOP = 1;
    final int DRAWABLE_RIGHT = 2;
    final int DRAWABLE_BOTTOM = 3;
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (event.getRawX() >= (v.getRight() - ((EditText) v).getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
               //TODO Drawable click here 
                return true;
            }
        }
        return false;
    }
};
Volodymyr Kulyk
  • 6,455
  • 3
  • 36
  • 63