-
Notifications
You must be signed in to change notification settings - Fork 55
Edit mode
Android Studio compiles views and uses the actual implementations to display them in the layout editor. In theory, it gives the same look and feel as it would on the device. In practice, it often doesn't work, because the environment is different.
- The renderer is different than on the device. For example, shadows and clipping don't work.
- The
Resources
andContext
classes cannot be overwritten. - You cannot interact with the views.
- You cannot provide dynamic data.
- Some classes and libraries don't load properly.
As you can see, there's a lot of problems with the preview. If your custom view doesn't render properly, you may want to display it a little different in the preview. To detect if the view is displayed by the IDE use isInEditMode()
. The usage is very simple:
if (!view.isInEditMode()) {
int resId = a.getResourceId(attr, 0);
if (resId != 0) {
if (view.getContext().getResources().getResourceTypeName(resId).equals("raw")) {
// the following line fails in the preview - VectorDrawable uses an external library
return new VectorDrawable(view.getResources(), resId);
} else {
return ContextCompat.getDrawable(view.getContext(), resId);
}
}
} else {
try {
return a.getDrawable(attr);
} catch (Exception e) {
return view.getResources().getDrawable(defaultValue);
}
}
The edit mode is not only about fixing weird bugs with the preview. You can also display additional information that only should be visible in the IDE. For example rulers and guides in a layout.
The following code draws a baseline used to align other views in the layout. On the device, the view will look empty. What's interesting, I'm allocating a Paint
object on every frame. I need it only here and it will be allocated only in the IDE, so it's fine to do that here.
@Override
protected void onDraw(Canvas canvas) {
if (isInEditMode()) {
@SuppressLint("DrawAllocation") Paint paint = new Paint();
paint.setColor(Carbon.getThemeColor(getContext(), R.attr.carbon_colorError));
canvas.drawLine(0, getBaseline(), getWidth(), getBaseline(), paint);
}
}