EDIT: After more investigation, it turns out that this has nothing to do with the ViewPager. The issue is with setting a visibility attribute on a ViewGroup in XML, then attempting to change it at runtime. I'm leaving the original question as it is. See my answer below for more information.
I have a layout with a ViewPager and a custom PagerIndicator class. On the 0th page of the ViewPager, I want the indicator to be View.GONE. On other pages, I want it to be View.VISIBLE. Here's my code, which is called during onCreate:
void setupPager() {
mPager.setAdapter(new TutorialPagerAdapter());
mPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int currentPage) {
Log.d(TAG, String.valueOf(currentPage));
if (currentPage == 0) {
mPagerIndicator.setVisibility(View.GONE);
} else {
mPagerIndicator.setVisibility(View.VISIBLE);
}
mPagerIndicator.setCurrentPage(currentPage);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
The mPagerIndicator is set with android:visibility="invisible" in the XML layout. When I scroll between pages, I can see that the callback is being called, and the page number is correct. However, the pager doesn't appear.
This is where it gets bizarre: I loaded up the Android Hierarchy Viewer that comes with the SDK. When it loaded the view hierarchy from the emulator, POOF, the indicator appeared. It also doesn't seem to be a problem on a physical device. (EDIT: After some more testing, it appears to be an issue with 2.3, as it doesn't happen on higher versioned devices, but does happen on a 2.3.6 phone.)
Any idea why this is happening? Is it reasonable to assume that this is just a quirk of the emulator, or should I be worried that it won't work on some devices? Any hacks to get it to show up? What does the hierarchy viewer do that might be forcing it to refresh itself?
What do you mean by "it doesn't seem to be a problem on a physical device"? Do you mean you see the indicator OK, or that the indicator is visible in the HierarchyViewer?
Everything looks OK to me in your code. Sounds like your indicator is simply covered by another view - maybe the ViewPager - but it exists just fine, therefore you can see it in the HierarchyViewer.
Try removing the code above to toggle visibility, then set your PagerIndicator to View.VISIBLE in the xml. If you still can't see it, then there's your problem.
It appears that there is an issue in Android 2.3.3+ involving visibility of ViewGroups. Setting the ViewGroup with android:visibility=X in the XML seems to set the visibility of all of the subviews. However, when changing the visibility at runtime, it does not apply it to the subviews. Because of this, starting with a visibility of gone or invisibile will cause setting the visibility later to fail.
The solution is to override setVisibility in my custom view, to make it set the visibility on all of its subviews as well:
#Override
public void setVisibility(int visibility) {
super.setVisibility(visibility);
for (ImageView image : mImages) {
image.setVisibility(visibility);
}
}
Thanks to http://www.kittehface.com/2011/03/view-visibility-bug-on-android-233.html and android setVisibility does not display if initially set to invisble for getting me pointed in the right direction.
Related
I have a simple navigation drawer layout setup. I'm using the design support library so I have one a navigation view that slides in above the support library's toolbar. However, the header layout is responding to taps in the UI. I'm getting that ripple effect appearing behind the header layout when I tap it. How can I do either of the following:
Disable the tap interaction all together? (so no ripple effect occurs)
Respond to the tap interaction.
I can't seem to find any documentation on this.
I noticed the same issue. This component uses a ListView internally (called menuView below), and unfortunately there is no option to disable the header selection because it's hard-coded:
this.mHeader = (LinearLayout)this.mLayoutInflater.inflate(layout.design_navigation_item_header, this.mMenuView, false);
this.mMenuView.addHeaderView(this.mHeader);
this.mMenuView.setAdapter(this.mAdapter);
this.mMenuView.setOnItemClickListener(this);
Adding that to the fact that the NavigationView also has an icons coloring bug (in version 22.2.0), I would suggest to not use it for the moment.
This can be a workaround for the issue:
View headerView = getLayoutInflater().inflate(R.layout.header_nav, mNavigationView, false);
mNavigationView.addHeaderView(headerView);
//Use this if you don't want the click listener,
//be sure to use the appropriate background color
//((ViewGroup) headerView.getParent()).setBackgroundResource(R.color.background_material_light);
//If you want your header to respond to clicks, this should suffice
headerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Open to your implementation
}
});
You can override the layout resource "design_navigation_item_header" and add background color and then you will not see the ripple.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:orientation="vertical"
android:paddingBottom="#dimen/navigation_separator_vertical_padding"/>
If you wanted to respond to the click you could look up the view by id and add an OnClickListener.
Taking hints from razzledazzle's post, simply consuming the onClick works
View headerView = LayoutInflater.from(getActivity()).inflate(R.layout.drawer_header_view, menuItemsNavigationView, false);
headerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Consume input from header view. This disables the ripple effect
}
});
menuItemsNavigationView.addHeaderView(headerView);
I just dealt with this in my own app. A NavigationView is a ScrimInsetsFrameLayout wrapped around a ListView and it explicitly ignores (throws out) clicks on the first item of the list, which is the header.
However, you can retrieve them yourself by wrapping the NavigationView’s onItemClickListener with your own:
ListView menuList = (ListView) navigationView.getChildAt(0);
final AdapterView.OnItemClickListener nativeListener = menuList.getOnItemClickListener();
menuList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
drawerLayout.closeDrawer(GravityCompat.START);
onUserClicked(prefs.getUser());
}
nativeListener.onItemClick(parent, view, position, id);
}
});
Normally I don’t endorse this kind of relying on the internals of Android widgets, but in this case it’s the support library, which is packaged and shipped with your app. It’s probably better to build your own custom navigation view in the long run, but sometimes you need a quick fix!
None of the solutions on this page worked for me, and probably with good reason. As the accepted answer by BladeCoder states, the listener is hard-coded into the NavigationDrawer ListView, and the header view is the 0th item of the ListView's Adapter. Simply overriding the onClickListener for the inflated header view won't work if you want to actually disable it, as you need to reference the onClickListener for the ListView's Adapter item instead of just the inflated view.
The below solution works for me to disallow clicking/tapping the header view, but it does not disable focusability (with a d-pad or keyboard for example). I can't seem to figure out how just yet.
//get the listview within the navigation drawer (0th child)
ListView menuList = (ListView) mNavigationView.getChildAt(0);
//get the header view (0th item in listview adapter)
final View headerView = menuList.getAdapter().getView(0, null, null);
if (headerView != null) {
headerView.setEnabled(false); //doesn't work, should
headerView.setFocusable(false); //doesn't work, should
headerView.setFocusableInTouchMode(false); //doesn't work, should
headerView.setClickable(false); //doesn't work, should
headerView.setOnClickListener(null); //WORKS! works to disallow clicking! is still focusable via keyboard
}
I've spent about 6 hours on this so far, and been hitting nothing but roadblocks. The general premise is that there is some row in a ListView (whether it's generated by the adapter, or added as a header view) that contains an EditText widget and a Button. All I want to do is be able to use the jogball/arrows, to navigate the selector to individual items like normal, but when I get to a particular row -- even if I have to explicitly identify the row -- that has a focusable child, I want that child to take focus instead of indicating the position with the selector.
I've tried many possibilities, and have so far had no luck.
layout:
<ListView
android:id="#android:id/list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
Header view:
EditText view = new EditText(this);
listView.addHeaderView(view, null, true);
Assuming there are other items in the adapter, using the arrow keys will move the selection up/down in the list, as expected; but when getting to the header row, it is also displayed with the selector, and no way to focus into the EditText using the jogball. Note: tapping on the EditText will focus it at that point, however that relies on a touchscreen, which should not be a requirement.
ListView apparently has two modes in this regard:
1. setItemsCanFocus(true): selector is never displayed, but the EditText can get focus when using the arrows. Focus search algorithm is hard to predict, and no visual feedback (on any rows: having focusable children or not) on which item is selected, both of which can give the user an unexpected experience.
2. setItemsCanFocus(false): selector is always drawn in non-touch-mode, and EditText can never get focus -- even if you tap on it.
To make matters worse, calling editTextView.requestFocus() returns true, but in fact does not give the EditText focus.
What I'm envisioning is basically a hybrid of 1 & 2, where rather than the list setting if all items are focusable or not, I want to set focusability for a single item in the list, so that the selector seamlessly transitions from selecting the entire row for non-focusable items, and traversing the focus tree for items that contain focusable children.
Any takers?
This helped me.
In your manifest :
<activity android:name= ".yourActivity" android:windowSoftInputMode="adjustPan"/>
Sorry, answered my own question. It may not be the most correct or most elegant solution, but it works for me, and gives a pretty solid user experience. I looked into the code for ListView to see why the two behaviors are so different, and came across this from ListView.java:
public void setItemsCanFocus(boolean itemsCanFocus) {
mItemsCanFocus = itemsCanFocus;
if (!itemsCanFocus) {
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
}
}
So, when calling setItemsCanFocus(false), it's also setting descendant focusability such that no child can get focus. This explains why I couldn't just toggle mItemsCanFocus in the ListView's OnItemSelectedListener -- because the ListView was then blocking focus to all children.
What I have now:
<ListView
android:id="#android:id/list"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:descendantFocusability="beforeDescendants"
/>
I use beforeDescendants because the selector will only be drawn when the ListView itself (not a child) has focus, so the default behavior needs to be that the ListView takes focus first and draws selectors.
Then in the OnItemSelectedListener, since I know which header view I want to override the selector (would take more work to dynamically determine if any given position contains a focusable view), I can change descendant focusability, and set focus on the EditText. And when I navigate out of that header, change it back it again.
public void onItemSelected(AdapterView<?> listView, View view, int position, long id)
{
if (position == 1)
{
// listView.setItemsCanFocus(true);
// Use afterDescendants, because I don't want the ListView to steal focus
listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
myEditText.requestFocus();
}
else
{
if (!listView.isFocused())
{
// listView.setItemsCanFocus(false);
// Use beforeDescendants so that the EditText doesn't re-take focus
listView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
listView.requestFocus();
}
}
}
public void onNothingSelected(AdapterView<?> listView)
{
// This happens when you start scrolling, so we need to prevent it from staying
// in the afterDescendants mode if the EditText was focused
listView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
}
Note the commented-out setItemsCanFocus calls. With those calls, I got the correct behavior, but setItemsCanFocus(false) caused focus to jump from the EditText, to another widget outside of the ListView, back to the ListView and displayed the selector on the next selected item, and that jumping focus was distracting. Removing the ItemsCanFocus change, and just toggling descendant focusability got me the desired behavior. All items draw the selector as normal, but when getting to the row with the EditText, it focused on the text field instead. Then when continuing out of that EditText, it started drawing the selector again.
My task was to implement ListView which expands when clicked. The additional space shows EditText where you can input some text. App should be functional on 2.2+ (up to 4.2.2 at time of writing this)
I tried numerous solutions from this post and others I could find; tested them on 2.2 up to 4.2.2 devices.
None of solutions was satisfactionary on all devices 2.2+, each solution presented with different problems.
I wanted to share my final solution :
set listview to android:descendantFocusability="afterDescendants"
set listview to setItemsCanFocus(true);
set your activity to android:windowSoftInputMode="adjustResize"
Many people suggest adjustPan but adjustResize gives much better ux imho, just test this in your case. With adjustPan you will get bottom listitems obscured for instance. Docs suggest that ("This is generally less desirable than resizing"). Also on 4.0.4 after user starts typing on soft keyboard the screen pans to the top.
on 4.2.2 with adjustResize there are some problems with EditText focus. The solution is to apply rjrjr solution from this thread. It looks scarry but it is not. And it works. Just try it.
Additional 5. Due to adapter being refreshed (because of view resize) when EditText gains focus on pre HoneyComb versions I found an issue with reversed views:
getting View for ListView item / reverse order on 2.2; works on 4.0.3
If you are doing some animations you might want to change behaviour to adjustPan for pre-honeycomb versions so that resize doesnt fire and adapter doesn't refresh the views. You just need to add something like this
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
All this gives acceptable ux on 2.2 - 4.2.2 devices.
Hope it will save people some time as it took me at least several hours to come to this conclusion.
This saved my life--->
set this line
ListView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
Then in your manifest in activity tag type this-->
<activity android:windowSoftInputMode="adjustPan">
Your usual intent
We're trying this on a short list that does not do any view recycling. So far so good.
XML:
<RitalinLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="#+id/cart_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
/>
</RitalinLayout>
Java:
/**
* It helps you keep focused.
*
* For use as a parent of {#link android.widget.ListView}s that need to use EditText
* children for inline editing.
*/
public class RitalinLayout extends FrameLayout {
View sticky;
public RitalinLayout(Context context, AttributeSet attrs) {
super(context, attrs);
ViewTreeObserver vto = getViewTreeObserver();
vto.addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {
#Override public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (newFocus == null) return;
View baby = getChildAt(0);
if (newFocus != baby) {
ViewParent parent = newFocus.getParent();
while (parent != null && parent != parent.getParent()) {
if (parent == baby) {
sticky = newFocus;
break;
}
parent = parent.getParent();
}
}
}
});
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override public void onGlobalLayout() {
if (sticky != null) {
sticky.requestFocus();
}
}
});
}
}
this post was matching exactly my keywords. I have a ListView header with a search EditText and a search Button.
In order to give focus to the EditText after loosing the initial focus the only HACK that i found is:
searchText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// LOTS OF HACKS TO MAKE THIS WORK.. UFF...
searchButton.requestFocusFromTouch();
searchText.requestFocus();
}
});
Lost lots of hours and it's not a real fix. Hope it helps someone tough.
If the list is dynamic and contains focusable widgets, then the right option is to use RecyclerView instead of ListView IMO.
The workarounds that set adjustPan, FOCUS_AFTER_DESCENDANTS, or manually remember focused position, are indeed just workarounds. They have corner cases (scrolling + soft keyboard issues, caret changing position in EditText). They don't change the fact that ListView creates/destroys views en masse during notifyDataSetChanged.
With RecyclerView, you notify about individual inserts, updates, and deletes. The focused view is not being recreated so no issues with form controls losing focus. As an added bonus, RecyclerView animates the list item insertions and removals.
Here's an example from official docs on how to get started with RecyclerView: Developer guide - Create a List with RecyclerView
some times when you use android:windowSoftInputMode="stateAlwaysHidden"in manifest activity or xml, that time it will lose keyboard focus. So first check for that property in your xml and manifest,if it is there just remove it. After add these option to manifest file in side activity android:windowSoftInputMode="adjustPan"and add this property to listview in xml android:descendantFocusability="beforeDescendants"
Another simple solution is to define your onClickListener, in the getView(..) method, of your ListAdapter.
public View getView(final int position, View convertView, ViewGroup parent){
//initialise your view
...
View row = context.getLayoutInflater().inflate(R.layout.list_item, null);
...
//define your listener on inner items
//define your global listener
row.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
doSomethingWithViewAndPosition(v,position);
}
});
return row;
That way your row are clickable, and your inner view too :)
The most important part is to get the focus working for the list cell.
Especially for list on Google TV this is essential:
setItemsCanFocus method of the list view does the trick:
...
mPuzzleList = (ListView) mGameprogressView.findViewById(R.id.gameprogress_puzzlelist);
mPuzzleList.setItemsCanFocus(true);
mPuzzleList.setAdapter(new PuzzleListAdapter(ctx,PuzzleGenerator.getPuzzles(ctx, getResources(), version_lite)));
...
My list cell xml starts like follows:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/puzzleDetailFrame"
android:focusable="true"
android:nextFocusLeft="#+id/gameprogress_lessDetails"
android:nextFocusRight="#+id/gameprogress_reset"
...
nextFocusLeft/Right are also important for D-Pad navigation.
For more details check out the great other answers.
I just found another solution. I believe it's more a hack than a solution but it works on android 2.3.7 and android 4.3 (I've even tested that good old D-pad)
init your webview as usual and add this: (thanks Michael Bierman)
listView.setItemsCanFocus(true);
During the getView call:
editText.setOnFocusChangeListener(
new OnFocusChangeListener(View view,boolean hasFocus){
view.post(new Runnable() {
#Override
public void run() {
view.requestFocus();
view.requestFocusFromTouch();
}
});
Just try this
android:windowSoftInputMode="adjustNothing"
in the
activity
section of your manifest.
Yes, it adjusts nothings, which means the editText will stay where it is when IME is opening. But that's just an little inconvenience that still completely solves the problem of losing focus.
In my case, there is 14 input edit text in the list view. The problem I was facing, when the keyboard open, edit text focus lost, scroll the layout, and as soon as focused view not visible to the user keyboard down. It was not good for the user experience. I can't use windowSoftInputMethod="adjustPan". So after so much searching, I found a link that inflates custom layout and sets data on view as an adapter by using LinearLayout and scrollView and work well for my case.
I'm creating a grid that displays values that change very often. Because of this, I'm using a TextView that autoresizes when its content changes (Auto Scale TextView Text to Fit within Bounds). The resize takes place, but the view doesn't layout properly
The thing is, when I examine the activity with HierarchyViewer the layout displays as I want.
My guess is that HierarchyViewer invokes requestLayout() or invalidate() on the view, but I've tried that with no success. This code is invoked in the main activity with no effect.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
getWindow().getDecorView().requestLayout();
getWindow().getDecorView().invalidate();
}
}, 5000);
I've also tried invalidating the view after resizing.
The TextView has gravity set to Center, and if no resize takes place, it looks ok.
Any hint will be welcome, thanks in advance!
I solved it by overriding onLayout in one of the TextView's parent and using a Handler created in the constructor
public class CellView extends LinearLayout{
public CellView(Context context) {
super(context);
mHandler = new Handler();
View.inflate(context, R.layout.cellview, this);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if(changed){
mHandler.post(new Runnable() {
#Override
public void run() {
requestLayout();
}
});
}
super.onLayout(changed, left, top, right, bottom);
}
I had tried calling requestLayout inside TextView's onLayout, tho it didn't work, I'm not sure why. It might be because the value was updated through an Observer, but the onTextChanged listener should happen in the UI Thread. I hope it serves someone else
The way requestLayout() works is that when called on a view, it will schedule a layout pass on itself and all of it's children. This is desirable whenever a view has shifted or resized do to margin, padding, or content changes.
The documentation on the method getDecorView() isn't very clear on what exactly it gives you. However, per the documentation on the website:
Note that calling this function for the first time "locks in" various window characteristics as described in setContentView(View, android.view.ViewGroup.LayoutParams).
This leaves me to believe that there's something special about the view that getDecorView() retrieves. What you are probably doing is making the layout of the view permanent thus never changing when you make a requestLayout() pass.
This is apparently the proper way to get the root view of your entire activity.
However, for efficiency reasons, I recommend calling requestLayout() on the lowest child you possibly can. Like I said before, it schedules a layout pass on a view and it's children. If you do a layout pass on the top-most view, you're essientially rebuilding everything which includes the views that stay in place.
You probably need to run the timer code in the UI thread using runOnUiThread as explained here.
Can someone please explain to a noob the correct way to animate a View so its touch area and image actually move together?!
I have read lots of posts and questions and tutorials, but none explains what moves the layout and what moves the image such that I can animate a view and then leave it at its new position.
This is an example method I'm working with, trying lots of different combinations to no success. The view is in the parent RelativeLayout. It's a touchable menu of icons, and is animated with an xml resource on a click to slide off screen leaving just a little tab showing, where it needs to stay until clicked again.
public void RetractTools (View v){
final ImageView finalImage1 = (ImageView) findViewById(R.id.paintsView);
Animation slideout = AnimationUtils.loadAnimation(this, R.anim.slideout_tools);
slideout.setFillAfter(true);
slideout.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
finalImage1.setEnabled(true);
optionMenu.showing = false;
optionMenu.inMotion = false;
finalImage1.layout(1258, 668, 1697, 752);
finalImage1.setRight(1280);
finalImage1.invalidate();
}
#Override
public void onAnimationRepeat(Animation arg0) {
}
#Override
public void onAnimationStart(Animation arg0) {
finalImage1.setEnabled(false);
}
});
optionMenu.inMotion = true;
v.startAnimation(slideout);
}// End RetractMenu
No matter what I try, I encounter problems. setFillAfter does nothing when set in the xml file. Set programmatically, it leaves the image in the right place but the touch controls remain where the menu was. I have tried setLeft and setRight which apparently only move the image, not the view position, and all sorts of different layout options, and fill and no fill and invalidating and not, but can't solve it. I clearly don't undersatnd the underlying mechanics needed to position and render a view! :D
Thanks.
EDIT : Solution
For anyone having similar issues, this is how I have found to work with relative layouts. You create a LayoutParams object with the specified size, and then you can assign it positions. eg.
final RelativeLayout.LayoutParams position = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
position.leftMargin = 440;
Then assign that to your view
myView.setLayoutParams(position);
So in summary, you use a LayoutParams object as an interface to your view's position, rather than accessing the view's coordinates directly as I assumed.
What you have is basically fine, with two flaws:
You are using setFillAfter(), which is not especially useful
You are calling layout() and setRight() and stuff, which is not especially effective
Instead, in onAnimationEnd(), you need to modify the LayoutParams of the View to reflect the new position you want the widget to be in. The size and position of a widget is dictated by the layout rules it negotiates with its container. Initially, those are set via your layout XML resource. By modifying the LayoutParams at runtime, you are changing what those rules are.
What those LayoutParams are (LinearLayout.LayoutParams, RelativeLayout.LayoutParams, etc.) and what values you should specify in them, we cannot tell you, because we don't know what you are doing.
I am trying to create a view that slides up from the bottom of the screen. I tried setting the initial position of the view (which should be offscreen) in xml, but instead of placing the imageview where I specified, it truncated it. My second thought was to set the position of the view programatically inside the onWindowFocusChanged method. Here's my code
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if(hasFocus) {
slide_dock.layout(slide_dock.getLeft(), phone_height - 70, slide_dock.getRight(), phone_height + 230);
}
}
The problem is that this only works SOME of the time. I've been debugging it, and I believe the issue is that the layout values of slide_dock get altered after my onWindowFocusChanged function completes, I'm just not sure where. Can anyone here help me out? Or link me to somewhere that explains the layout process in-depth? I've been searching around to no avail.
Have you tried using the Animation framework? Use a RelativeLayout and align your child view to the bottom of the parent. Then use the following animation, maybe showing and hiding your view appropriately with View.setVisibility(int)
View myView = View(this);
TranslateAnimation slideUp = new TranslateAnimation(myView.getHeight(), 0, 0, 0);
slideUp.setDuration(250); // millis
slideUp.setFillAfter(true); // Required for animation to "stick" when done
myView.startAnimation(slideUp);
You might have to play with the TranslateAnimation constructor parameters to get it to work right (this is from the top of my head).
So I figured out the cause for the issue above, and I'm posting it here in case anyone ever runs into the same problem.
The reason why the ImageView was resizing was because in ImageView's onMeasure function, it resizes itself if it doesn't think that it will fit onto the screen. You can view the ImageView source here and see how it works: http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/widget/ImageView.java&d=3
To work around this, I created a custom view that extended ImageView and overrode the onMeasure method. In my new onMeasure method, I simply called setDimension to give my new view the dimensions that I wanted it to have, this effectively stopped the view from resizing as it was doing earlier
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), 300);
}