简体   繁体   中英

Constructors not being called

I'm creating a custom View that requires a few flags to be set in the constructors. The flags are not set anywhere else, and are saved/restored in the onSaveInstanceState and onRestoreInstanceState methods.

The problem is when I try to use it, the flags are not always set. I logged which constructor is used for each instance, but it seems there are cases where none of them are used. I can't think of any other constructor that could be getting called instead.

public class TextViewCompat extends AppCompatTextView
{
    private int constructor = 0;
    private boolean isPreHoneycomb;
    private boolean isPreJellybean;

    public TextViewCompat(Context context)
    {
        this(context, null);
        constructor = 1;
    }

    public TextViewCompat(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
        constructor = 2;
    }

    public TextViewCompat(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);

        isPreHoneycomb = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
        isPreJellybean = Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1;

        constructor = 3;
    }

    @Override
    public Parcelable onSaveInstanceState()
    {
        Log.d("Kevin", "onSaveInstanceState");
        Bundle bundle = new Bundle();
        bundle.putParcelable("instanceState", super.onSaveInstanceState());
        bundle.putBoolean("isPreHoneycomb", isPreHoneycomb);
        bundle.putBoolean("isPreJellybean", isPreJellybean);

        return bundle;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state)
    {
        Log.d("Kevin", "onRestoreInstanceState");
        if (state instanceof Bundle)
        {
            Bundle bundle = (Bundle) state;
            isPreHoneycomb = bundle.getBoolean("isPreHoneycomb", Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB);
            isPreJellybean = bundle.getBoolean("isPreJellybean", Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1);

            state = bundle.getParcelable("instanceState");
        }
        super.onRestoreInstanceState(state);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter)
    {    
        Log.d("Kevin", "=================");
        Log.d("Kevin", "constructor=" + constructor);
        Log.d("Kevin", "isPreJellybean=" + isPreJellybean);
        Log.d("Kevin", "isPreHoneycomb=" + isPreHoneycomb);
        Log.d("Kevin", "=================");

        super.onTextChanged(text, start, lengthBefore, lengthAfter);
    }
}

I know that it would be pretty easy for me to work around this issue in this case, because the flags can be recalculated at any time. But the point is that the constructors aren't called and would be an issue for any other flag I'd like to keep.

Note: The views are inflated from xml instead of programatically, and testing on an API 10 emulator and device (both flags should be true).

You can try this .Pass super instead of this

public TextViewCompat(Context context)
{
    super(context);
    constructor = 1;
}

public TextViewCompat(Context context, AttributeSet attrs)
{
    super(context, attrs);
    constructor = 2;
}

I found the issue. I'm printing out the flags in the onTextChanged method. Since I'm inflating the view from the layout (text set in the attrs), the constructor is setting the text on the line super(context, attrs, defStyle); and firing onTextChanged before the flags are set.

Silly mistake, but thanks for any of the comments that nudged me in the correct direction.

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