146dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk/*
246dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk * Copyright (C) 2016 The Android Open Source Project
346dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk *
446dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
546dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk * except in compliance with the License. You may obtain a copy of the License at
646dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk *
746dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk *      http://www.apache.org/licenses/LICENSE-2.0
846dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk *
946dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk * Unless required by applicable law or agreed to in writing, software distributed under the
1046dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1146dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk * KIND, either express or implied. See the License for the specific language governing
1246dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk * permissions and limitations under the License.
1346dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk */
1446dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
1546dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkpackage com.android.systemui;
1646dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
1746dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport android.annotation.Nullable;
1846dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport android.content.Context;
1946dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport android.content.res.Configuration;
2046dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport android.content.res.TypedArray;
2123cbe85610f780134cc77dd4a54732a22ed6e86eYohei Yukawaimport android.os.LocaleList;
2246dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport android.util.AttributeSet;
2346dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport android.view.LayoutInflater;
2446dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport android.view.View;
2546dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport android.widget.FrameLayout;
2646dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
27d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupinimport com.android.systemui.statusbar.policy.ConfigurationController;
28d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin
2946dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport java.util.ArrayList;
3046dbfb475fe0d1644f27f78e35735ba32c92225bJason Monkimport java.util.List;
3146dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
329b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri/**
339b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri * Custom {@link FrameLayout} that re-inflates when changes to {@link Configuration} happen.
34d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin * Currently supports changes to density, asset path, and locale.
359b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri */
36d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupinpublic class AutoReinflateContainer extends FrameLayout implements
37d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        ConfigurationController.ConfigurationListener {
3846dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
3946dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    private final List<InflateListener> mInflateListeners = new ArrayList<>();
4046dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    private final int mLayout;
4146dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
429b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri    public AutoReinflateContainer(Context context, @Nullable AttributeSet attrs) {
4346dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        super(context, attrs);
4446dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
459b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoReinflateContainer);
469b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri        if (!a.hasValue(R.styleable.AutoReinflateContainer_android_layout)) {
479b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri            throw new IllegalArgumentException("AutoReinflateContainer must contain a layout");
4846dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        }
499b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri        mLayout = a.getResourceId(R.styleable.AutoReinflateContainer_android_layout, 0);
50d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        a.recycle();
5146dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        inflateLayout();
5246dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    }
5346dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
5446dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    @Override
55d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    protected void onAttachedToWindow() {
56d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        super.onAttachedToWindow();
57d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        Dependency.get(ConfigurationController.class).addCallback(this);
58d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    }
599b1fdff2e70e695a0104dbc63fc26e434dc7f188Clara Bayarri
60d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    @Override
61d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    protected void onDetachedFromWindow() {
62d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        super.onDetachedFromWindow();
63d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        Dependency.get(ConfigurationController.class).removeCallback(this);
6446dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    }
6546dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
66beda2ddbec2f32adeba20d562a53bb3dd83b902dJason Monk    protected void inflateLayoutImpl() {
6746dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        LayoutInflater.from(getContext()).inflate(mLayout, this);
68beda2ddbec2f32adeba20d562a53bb3dd83b902dJason Monk    }
69beda2ddbec2f32adeba20d562a53bb3dd83b902dJason Monk
70d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    public void inflateLayout() {
71beda2ddbec2f32adeba20d562a53bb3dd83b902dJason Monk        removeAllViews();
72beda2ddbec2f32adeba20d562a53bb3dd83b902dJason Monk        inflateLayoutImpl();
7346dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        final int N = mInflateListeners.size();
7446dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        for (int i = 0; i < N; i++) {
7546dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk            mInflateListeners.get(i).onInflated(getChildAt(0));
7646dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        }
7746dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    }
7846dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
7946dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    public void addInflateListener(InflateListener listener) {
8046dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        mInflateListeners.add(listener);
8146dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        listener.onInflated(getChildAt(0));
8246dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    }
8346dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk
84d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    @Override
85d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    public void onDensityOrFontScaleChanged() {
86d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        inflateLayout();
87d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    }
88d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin
89d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    @Override
90d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    public void onOverlayChanged() {
91d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        inflateLayout();
92d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    }
93d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin
94d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    @Override
95d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    public void onLocaleListChanged() {
96d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin        inflateLayout();
97d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin    }
98d2ddb44922df105031c529b84fb91ade14d0bb0bLucas Dupin
9946dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    public interface InflateListener {
10046dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        /**
10146dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk         * Called whenever a new view is inflated.
10246dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk         */
10346dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk        void onInflated(View v);
10446dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk    }
10546dbfb475fe0d1644f27f78e35735ba32c92225bJason Monk}
106