1package com.xtremelabs.robolectric.shadows;
2
3import android.app.Application;
4import android.content.Context;
5import android.view.LayoutInflater;
6import android.view.View;
7import android.view.ViewGroup;
8import com.xtremelabs.robolectric.internal.AppSingletonizer;
9import com.xtremelabs.robolectric.internal.Implementation;
10import com.xtremelabs.robolectric.internal.Implements;
11import com.xtremelabs.robolectric.res.ResourceLoader;
12
13import static com.xtremelabs.robolectric.Robolectric.shadowOf;
14
15/**
16 * Shadow of {@code LayoutInflater} that actually inflates layouts into {@code View}s that are functional enough to
17 * support testing.
18 */
19
20@Implements(LayoutInflater.class)
21public class ShadowLayoutInflater {
22    private static AppSingletonizer<LayoutInflater> instances = new LayoutInflaterAppSingletonizer();
23
24    private Context context;
25
26    private static LayoutInflater bind(LayoutInflater layoutInflater, Context context) {
27        shadowOf(layoutInflater).context = context;
28        return layoutInflater;
29    }
30
31    @Implementation
32    public static LayoutInflater from(Context context) {
33        return bind(instances.getInstance(context), context);
34    }
35
36    @Implementation
37    public Context getContext() {
38        return context;
39    }
40
41    @Implementation
42    public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
43        return getResourceLoader().inflateView(context, resource, attachToRoot ? root : null);
44    }
45
46    @Implementation
47    public View inflate(int resource, ViewGroup root) {
48        return inflate(resource, root, root != null);
49    }
50
51    private ResourceLoader getResourceLoader() {
52        return shadowOf(context.getApplicationContext()).getResourceLoader();
53    }
54
55    private static class LayoutInflaterAppSingletonizer extends AppSingletonizer<LayoutInflater> {
56        public LayoutInflaterAppSingletonizer() {
57            super(LayoutInflater.class);
58        }
59
60        @Override protected LayoutInflater get(ShadowApplication shadowApplication) {
61            return shadowApplication.getLayoutInflater();
62        }
63
64        @Override protected void set(ShadowApplication shadowApplication, LayoutInflater instance) {
65            shadowApplication.layoutInflater = instance;
66        }
67
68        @Override protected LayoutInflater createInstance(Application applicationContext) {
69            return new MyLayoutInflater(applicationContext);
70        }
71
72        private static class MyLayoutInflater extends LayoutInflater {
73            public MyLayoutInflater(Context context) {
74                super(context);
75            }
76
77            @Override public LayoutInflater cloneInContext(Context newContext) {
78                return bind(new MyLayoutInflater(newContext), newContext);
79            }
80        }
81    }
82}
83