1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui; 16 17 import android.annotation.Nullable; 18 import android.content.Context; 19 import android.content.res.Configuration; 20 import android.content.res.TypedArray; 21 import android.os.LocaleList; 22 import android.util.AttributeSet; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.widget.FrameLayout; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 30 /** 31 * Custom {@link FrameLayout} that re-inflates when changes to {@link Configuration} happen. 32 * Currently supports changes to density and locale. 33 */ 34 public class AutoReinflateContainer extends FrameLayout { 35 36 private final List<InflateListener> mInflateListeners = new ArrayList<>(); 37 private final int mLayout; 38 private int mDensity; 39 private LocaleList mLocaleList; 40 AutoReinflateContainer(Context context, @Nullable AttributeSet attrs)41 public AutoReinflateContainer(Context context, @Nullable AttributeSet attrs) { 42 super(context, attrs); 43 44 mDensity = context.getResources().getConfiguration().densityDpi; 45 mLocaleList = context.getResources().getConfiguration().getLocales(); 46 47 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoReinflateContainer); 48 if (!a.hasValue(R.styleable.AutoReinflateContainer_android_layout)) { 49 throw new IllegalArgumentException("AutoReinflateContainer must contain a layout"); 50 } 51 mLayout = a.getResourceId(R.styleable.AutoReinflateContainer_android_layout, 0); 52 inflateLayout(); 53 } 54 55 @Override onConfigurationChanged(Configuration newConfig)56 protected void onConfigurationChanged(Configuration newConfig) { 57 super.onConfigurationChanged(newConfig); 58 boolean shouldInflateLayout = false; 59 final int density = newConfig.densityDpi; 60 if (density != mDensity) { 61 mDensity = density; 62 shouldInflateLayout = true; 63 } 64 final LocaleList localeList = newConfig.getLocales(); 65 if (localeList != mLocaleList) { 66 mLocaleList = localeList; 67 shouldInflateLayout = true; 68 } 69 70 if (shouldInflateLayout) { 71 inflateLayout(); 72 } 73 } 74 inflateLayout()75 private void inflateLayout() { 76 removeAllViews(); 77 LayoutInflater.from(getContext()).inflate(mLayout, this); 78 final int N = mInflateListeners.size(); 79 for (int i = 0; i < N; i++) { 80 mInflateListeners.get(i).onInflated(getChildAt(0)); 81 } 82 } 83 addInflateListener(InflateListener listener)84 public void addInflateListener(InflateListener listener) { 85 mInflateListeners.add(listener); 86 listener.onInflated(getChildAt(0)); 87 } 88 89 public interface InflateListener { 90 /** 91 * Called whenever a new view is inflated. 92 */ onInflated(View v)93 void onInflated(View v); 94 } 95 } 96