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