I have a custom camera activity in my Android app. For android devices using KitKat, I needed to account for the visible navigation bar at the bottom of the screen. To do this, I use the following line to ensure my views are below the navigation bar:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN );
However, when I do this, one of my views becomes hidden behind the action bar. I'm trying to account for the height of the action bar by adding a top margin to this view, but it doesn't appear to be correct.
What am I doing wrong?
This is what I would like the view to look like (works on pre-KitKat devices):
And this is what it currently looks like on Kit Kat devices (you can see that the top of my view is cut off):
Here is my layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="left"
android:orientation="vertical" >
<HorizontalScrollView
android:id="#+id/gallery_scroll_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="fitXY" >
<com.example.helperClass.PictureHorizontalLayout
android:id="#+id/mygallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:scaleType="fitXY" >
</com.example.helperClass.PictureHorizontalLayout>
</HorizontalScrollView>
<FrameLayout
android:id="#+id/camerapreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/black" />
<LinearLayout
android:id="#+id/button_holder_customized_cam"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_alignParentBottom="true"
android:background="#838B8B"
android:gravity="bottom"
android:orientation="horizontal"
android:weightSum="0.9"
>
<ImageButton
android:id="#+id/gallery_customized_camera"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="1dp"
android:layout_weight="0.3"
android:adjustViewBounds="true"
android:background="#null"
android:contentDescription="#string/add"
android:maxWidth="75dp"
android:scaleType="center"
android:src="#drawable/ic_action_picture" >
<!-- android:background="#drawable/custom_button_blue" -->
</ImageButton>
<ImageButton
android:id="#+id/shutter_customized_camera"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="1dp"
android:layout_weight="0.3"
android:adjustViewBounds="true"
android:background="#drawable/custom_button_blue"
android:contentDescription="#string/add"
android:maxWidth="75dp"
android:scaleType="center"
android:src="#drawable/ic_action_camera" >
</ImageButton>
<ImageButton
android:id="#+id/video_customized_camera"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.3"
android:adjustViewBounds="true"
android:background="#null"
android:contentDescription="#string/add"
android:maxWidth="75dp"
android:scaleType="center"
android:src="#drawable/ic_action_video" >
<!-- android:background="#drawable/custom_button_blue" -->
</ImageButton>
</LinearLayout>
<TextView
android:id="#+id/camera_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/button_holder_customized_cam"
android:layout_alignParentRight="true"
android:padding="15dp"
android:text="#string/no_time"
android:textColor="#color/red"
android:textSize="20sp"
android:visibility="invisible" >
</TextView>
</RelativeLayout>
And here is how I set margins for the HorizontalScrollView:
myHorizontalLayout = (PictureHorizontalLayout) findViewById(R.id.mygallery);
// apply margin to horizontal scroll view to take into account height of status bar
TypedValue tv = new TypedValue();
int actionBarHeight = 0;
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
{
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
Log.d(TAG, "actionbarHeight before: " + actionBarHeight);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) myHorizontalLayout.getLayoutParams();
Log.d(TAG, "actionbarHeight after: " + actionBarHeight);
params.setMargins(0, actionBarHeight, 0, 0);
Log.d(TAG, "ADJUST MARGINS OF HORIZONTAL LAYOUT");
myHorizontalLayout.setLayoutParams(params);
}
NOTE: I also tried adding android:layout_marginTop="?attr/actionBarSize" to the HorizontalScrollView in my layout file, but this didn't work either (the vertical offset was still incorrect)
The best way to do what you want, is to use ActionBar in Overlay Mode.
Then, you can use the following margin in your view to make sure it does not hide behind the action bar.
<!-- Support library compatibility -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
...
</RelativeLayout>
Change your RelativeLayout to use the android:fitsSystemWindows="true" attribute.
From the View.SYSTEM_UI_FLAG_LAYOUT_STABLE docs:
When using other layout flags, we would like a stable view of the
content insets given to fitSystemWindows(Rect).
Also, the attribute android:orientation isn't inherited by RealtiveLayout and android:scaleType isn't inherited by HorizontalScrollView.
Related
I 'm trying to integrate a SearchView, on a custom Toolbar I 'm making.
The requirements are:
1) 2 ActionMenuViews
2) Centered Title
I have also subclassed SearchView to make it full width, so, apart from overriding onMeasure and applying a custom MaxWidth(Integer.MAX_VALUE), I, also. applied this terrible hack found online to remove the SearchView container's margins.
// Terrible hack (1) to set SearchView's main container margin to 0
LinearLayout searchEditFrame = (LinearLayout) findViewById(R.id.search_edit_frame); // Get the Linear Layout
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) searchEditFrame.getLayoutParams();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
params.setMarginStart(0);
} else {
params.leftMargin = 0;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
params.setMarginEnd(0);
} else {
params.rightMargin = 0;
}
searchEditFrame.setLayoutParams(params);
// End terrible hack (1)
I also took the liberty (sic) and applied similar logic to the magnifying glass ImageView directly.
// Terrible hack (2) to remove hardcoded padding from search icon magnifying glass icon
ImageView magIcon = (ImageView) findViewById(R.id.search_mag_icon);
params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
params.setMarginStart(0);
} else {
params.leftMargin = 0;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
params.setMarginEnd(0);
} else {
params.rightMargin = 0;
}
magIcon.setLayoutParams(params);
// End terrible hack (2)
(remember the ids are from abs_search_view.xml and they seem to match)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/search_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- This is actually used for the badge icon *or* the badge label (or neither) -->
<TextView
android:id="#+id/search_badge"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:layout_marginBottom="2dip"
android:drawablePadding="0dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorPrimary"
android:visibility="gone" />
<ImageView
android:id="#+id/search_button"
style="?attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:focusable="true"
android:contentDescription="#string/abc_searchview_description_search" />
<LinearLayout
android:id="#+id/search_edit_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal"
android:layoutDirection="locale">
<ImageView
android:id="#+id/search_mag_icon"
android:layout_width="#dimen/abc_dropdownitem_icon_width"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_gravity="center_vertical"
android:visibility="gone"
style="#style/RtlOverlay.Widget.AppCompat.SearchView.MagIcon" />
<!-- Inner layout contains the app icon, button(s) and EditText -->
<LinearLayout
android:id="#+id/search_plate"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<view class="android.support.v7.widget.SearchView$SearchAutoComplete"
android:id="#+id/search_src_text"
android:layout_height="36dip"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingLeft="#dimen/abc_dropdownitem_text_padding_left"
android:paddingRight="#dimen/abc_dropdownitem_text_padding_right"
android:singleLine="true"
android:ellipsize="end"
android:background="#null"
android:inputType="text|textAutoComplete|textNoSuggestions"
android:imeOptions="actionSearch"
android:dropDownHeight="wrap_content"
android:dropDownAnchor="#id/search_edit_frame"
android:dropDownVerticalOffset="0dip"
android:dropDownHorizontalOffset="0dip" />
<ImageView
android:id="#+id/search_close_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="8dip"
android:paddingRight="8dip"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:contentDescription="#string/abc_searchview_description_clear" />
</LinearLayout>
<LinearLayout
android:id="#+id/submit_area"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="#+id/search_go_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:background="?attr/selectableItemBackgroundBorderless"
android:visibility="gone"
android:focusable="true"
android:contentDescription="#string/abc_searchview_description_submit" />
<ImageView
android:id="#+id/search_voice_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:background="?attr/selectableItemBackgroundBorderless"
android:visibility="gone"
android:focusable="true"
android:contentDescription="#string/abc_searchview_description_voice" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
This is what I 'm getting. The left action menu view has an MenuItem defined via xml and has custom styling (applied through actionButtonStyle property in Toolbar's theme).
The right action menu view has a searchview MenuItem defined via xml
The same result is if I move SearchView to the left menu.
Can somebody explain to me how to strip the searchIcon image of its padding and/or right margin?
PS: This is the expanded SearchView. Notice the right part, where I click the button. It is obviously expanded to full width without margins
OK, so here's what I think is happening.
Notice this line
<ImageView
android:id="#+id/search_button"
style="?attr/actionButtonStyle"
I think the actionButtonStyle of the Toolbar gets applied twice. I haven't had the time to look it into depth...
If anyone's got any comment, be my guest :)
I'm trying to change the height of RelativeLayout as user scrolls, so it smoothly moves up. It's kinda working but its all flickering and glitching.
I tried to use setTranslationY, but that doesn't move the scrollview with the RelativeLayout.
int top = mScrollView.getScrollY();
int maxRelative = formulas.dpToPx(250);
int actualRelative = (int)((1.0-((float)top)/300.0)*((float)maxRelative));
RelativeLayout.LayoutParams layout_description = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
actualRelative);
mCollapsingLayout.setLayoutParams(layout_description);
mCollapsingLayout.requestLayout();
This is how it looks
http://imgur.com/7PL6Yt5
If you have any better idea how to shrink the RelativeLayout as you scroll, its appreciated.
Edit: here's my xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="#dimen/app_bar_height"
android:id="#+id/collapsing.view">
<ImageView
android:id="#+id/collapsing.view.image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/theflash"
android:tint="#7F000000"
android:scaleType="centerCrop"/>
<ImageButton
android:id="#+id/favorite.button"
android:layout_width="70dp"
android:layout_height="70dp"
android:background="?android:attr/selectableItemBackground"
android:scaleType="fitCenter"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp"
android:src="#drawable/favorite_button"
/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingBottom="30px">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The Flash"
android:textColor="#fff"
android:textSize="25sp"
android:layout_centerInParent="true"
/>
</FrameLayout>
</RelativeLayout>
<ScrollView
android:id="#+id/detail.scrollview"
android:layout_below="#+id/collapsing.view"
android:layout_width="match_parent"
android:fillViewport="true"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
There are several approaches to this, including readily available classes such as this one which basically does what you want. You may need to remove the parts for the shrinking text and so forth, but it's right where you need it
You need to place your RelativeLayout inside the ScrollView and try setTranslationY again - it should work
I'm trying to align the seekbar to the top of a view, but i can't center it with the thumb.
Is there some kind of "alignCenter" with the RelativeLayout children.
Here's a sample of my xml code :
<RelativeLayout
android:id="#+id/rl_fragment_audio_player"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/black_transparent"
android:padding="5dp"
android:visibility="gone" >
<TextView
android:id="#+id/tv_fragment_audio_begin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:textColor="#color/white" />
<TextView
android:id="#+id/tv_fragment_audio_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:textColor="#color/white" />
<Button
android:id="#+id/btn_fragment_audio_play"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:background="#drawable/btn_play"
android:visibility="gone" />
</RelativeLayout>
<SeekBar
android:id="#+id/sb_fragment_audio"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_above="#id/rl_fragment_audio_player" />
For example, Google Play Music does it.
As you said the height of your seekbar might vary, unless you specify it different. Here is how you can make sure it fits all, always.
android:layout_above="#id/rl_fragment_audio_player"
is setting your seekbar bottom above rl_fragment_audio_player top. There is no direct method to specify centerAlignWith but I would remove the space it occupies within it's parent. To know the height of the seekbar you must wait until the global layout has changed. This code should be placed inside your onCreateView
sb = (SeekBar) rootView.findViewById(R.id.sb_fragment_audio);
sb.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener(){
#Override
public void onGlobalLayout() {
sb.getViewTreeObserver().removeOnGlobalLayoutListener(this);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) sb.getLayoutParams();
params.setMargins(0, - sb.getHeight() / 2, 0, - sb.getHeight() / 2);
sb.setLayoutParams(params);
// I suggest you set the seekbar visible after this so that it won't jump
}
});
The last view in the xml will be in the front. Therefore make sure your seekbar is added after the the other views. Like this
<RelativeLayout
android:id="#+id/rl_fragment_audio_player"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
// your bottom panel
</RelativeLayout>
<View
android:id="#+id/image_above"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/rl_fragment_audio_player" />
<SeekBar
android:id="#+id/sb_fragment_audio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/image_above" />
Have you tried adding a negative margin to the seekbar?
<SeekBar
android:id="#+id/sb_fragment_audio"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_marginBottom="-15dp"
android:layout_above="#id/rl_fragment_audio_player" />
I'm just starting android development coming from IOS and again stubbled onto a problem.
And after 1 day of trying i decided that i will ask the people of stack overflow.
So my problem:
I have an app and in the action bar (default no sherlock) i want 1 logo and 2 lines of text.
And trough the internet i fount the setCustomView for the action bar.
And the custom xml is loaded but i can't get the layout right.
So first i setup the action bar:
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowHomeEnabled(false);
LayoutParams lp1 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
View customNav = LayoutInflater.from(this).inflate(R.layout.actionbar, null); // layout which contains your button.
actionBar.setCustomView(customNav, lp1);
}
Than the xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_horizontal"
android:orientation="horizontal"
android:background="#color/Blue">
<TextView
android:id="#+id/text_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/title_menu"
android:textColor="#color/White"
android:paddingLeft="5dp"
android:layout_gravity="left"/>
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/Icon"
android:layout_gravity="center"/>
<TextView
android:id="#+id/text_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/title_help"
android:layout_gravity="right"
android:textColor="#color/White"
android:paddingRight="5dp"/>
</LinearLayout>
But the result is something what i'm not looking for:
So what am i forgetting/doing wrong/or should i do?
try change the root layout into relative layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_horizontal"
android:orientation="horizontal">
<TextView
android:text="left text"
android:layout_toLeftOf="#+id/icon"
android:layout_alignParentLeft="true"
android:id="#+id/text_left"
android:gravity="left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"/>
<ImageView
android:layout_centerHorizontal="true"
android:id="#+id/icon"
android:layout_width="10dp"
android:layout_height="wrap_content"
android:src="#drawable/bg_sunrise"
android:layout_gravity="center"/>
<TextView
android:text="Right txt"
android:layout_toRightOf="#+id/icon"
android:id="#+id/text_right"
android:layout_width="match_parent"
android:gravity="right"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:paddingRight="5dp"/> </RelativeLayout>
you're not getting your result because:
u need to:
if you use AppCompat theme
add to your activity layout
in code eg. in onCreate() set a toolbar to replace the action bar.
You could also use LinearLayout as a root and add android:weightSum and specify a layout_weight on the three child views.
What is android:weightSum in android, and how does it work?
I have put up a spinner on Android Action Bar, i have placed the spinner in test.xml layout and i am calling it like this in the main activity in the OnCreate() method
ActionBar actionBar = getActionBar();
actionBar.setBackgroundDrawable(new ColorDrawable(Color.GREEN));
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setCustomView(R.layout.activity_test);
setContentView(R.layout.activity_main);
actionBar.setTitle("Home");
But my title is not showing. i want to show HOME as title on that action bar what should i do?
My activity_test
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Spinner
android:id="#+id/planets_spinner"
android:layout_width="100dp"
android:layout_height="50sp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#drawable/arrow2"
android:layout_weight="0.08"
android:drawSelectorOnTop="true" />
</RelativeLayout>
I have solved the problem by adding a textView to my activity_test, as this whole activity is showing on the ActionBar so i have added a text view and problem is solved :)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Spinner
android:id="#+id/planets_spinner"
android:layout_width="100dp"
android:layout_height="50sp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#drawable/arrow2"
android:drawSelectorOnTop="true" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/planets_spinner"
android:layout_alignParentLeft="true"
android:layout_marginBottom="6dp"
android:layout_marginLeft="6dp"
android:textStyle="bold"
android:textSize="20sp"
android:textColor="#ffffff"
android:text="Scene" />
</RelativeLayout>
When you set android:layout_alignParentRight="true" , RelativeLayout uses all the space including the title space and title is not displayed. You can check the behaviour by drawing a border around the RelativeLayout. But RelativeLayout doesnt consume more space if you dont use android:layout_alignParentRight="true". It doesnt consume more space if you use android:layout_alignParentLeft="true", too. It works weird for only android:layout_alignParentRight="true". In order to show a view at the right of the parent, the following worked for me:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/profile_image"
android:layout_width="40dp"
android:src="#drawable/ic_launcher"
android:layout_height="40dp"
android:background="?android:selectableItemBackground"
android:padding="3dp"
android:scaleType="centerCrop" />
Do not use RelativeLayout. Just the view you need.
Then you can align right with the LayoutParams shown as following:
actionBar.setCustomView(R.layout.actionbar_layout);
actionBar.setDisplayShowCustomEnabled(true);
ImageView imageProfile = (ImageView)actionBar.getCustomView();
int length = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, getResources().getDisplayMetrics());
Toolbar.LayoutParams layoutParams = new Toolbar.LayoutParams(
length,
length, Gravity.RIGHT
| Gravity.CENTER_VERTICAL);
imageProfile.setLayoutParams(layoutParams);
Now you should be able to view both ActionBar title and the ImageView.