I am facing a quite interesting but annoying error, in my linear layout i have hided another linear layout using margin in negative and when user selects a type from a list i bring layout to front using Translational Animation the error is that the layout comes to front have an edit text which becomes dead and when i scroll (my main layout is surrounded by scroll view) it comes alive and when i stop scrolling it becomes dead again... i really failed to judge why is this happening so guys plz help....
i have also pasted link of video below showing this annoying behavior of my app
http://www.dailymotion.com/video/xlskk8_android-app-edit-text-error_tech
my layout xml inside scroll view is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginTop="-110dip"
android:layout_marginBottom="5dip"
android:id="#+id/notes_editor"
android:orientation="vertical"
>
<EditText
android:id="#+id/enter_note"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:maxLines="2"
android:lines="2">
</EditText>
<Button
android:id="#+id/save_note"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Save" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-10dip"
android:id="#+id/notes_list"
android:orientation="vertical"
>
</LinearLayout>
</LinearLayout>
the empty linear layout below button is used for dynamically adding child views all other things are performing their functionality properly, only the edit text showing this abnormal behavior.
the code used for animation is below
public void animateEditor()
{
slider = new TranslateAnimation(0, 0, 0,180 );
slider.setDuration(1250);
slider.setFillAfter(true);
notes_list.startAnimation(slider);
notes_editor.startAnimation(slider);
}
The problem here was when applying slider.setFillAfter(true); the code animates the image of Views but not the actual Views that's why when I see them after sliding down animation they were (EditText and save button) stuck or you can say dead and not listening to their events because actual Views were there behind the layout and at front it was just their image
The solution I found for that problem is to apply following code:
slider.setFillAfter(false);
slider.setFillBefore(false);
// OR you can directly write
slider.setFillEnabled(false);
And then to show actual views on the new place by setting animation listener and using the following method:
public void onAnimationEnd(Animation a)
Placing the views to new position at the end of animation by using above method. And here still comes another problem of blinking which is due to the problem in android animation listener method which is that it is get called before actually animation ends and causes blinking effect, a tricky solution to it is by putting following line of code at first line of public void onAnimationEnd(Animation a) method.
// in my case animation applied to notes_editor so the code will be
notes_editor.clearAnimation();
Related
I have a main layout being hosted by an activity (setContentView method).
I have a button in the layout. I want to be able to click this button and a new layout will slide down from the left/top until the middle of the screen. So, the screen now will have two layouts where one is on top and another one is just beneath it.
This is something like the UI in Android Jelly Bean where you can pull the settings layout down using a touch gesture.
What are the possible implementations?
A method I have tried:
add the slide down layout into main.xml but set its visibility to gone
when button is clicked, run some code that will set the layout visibility to
VISIBLE and add some animations.
the result of this implementation is that this layout will push the rest of the
views down in order to have a "squeeze" space for itself which is not
what I intended to do (see above)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingTop="5dp" >
<LinearLayout
android:id="#+id/PR_slidedown" <---this is the intended slidedown layout
android:layout_width="8dp"
android:layout_height="40dp"
android:visibility="gone"
android:orientation="vertical" >
</LinearLayout>
....
Your implementation is partially correct, the other part is to host your two layouts in a FrameLayout so they can overlap with each other. Search for FrameLayout in here, there are a lot of example on how to use it.
Or try the SlidingDrawer
I have been searching for an answer to this for days, and while some things kinda work (and most don't), I'm hoping I can find the best practice for what I'm trying to do.
I'm trying to get a notification bar to display in my app. Ideally, it would slide down from the top, while shifting other elements in the layout to accommodate. Here's an illustration to help: illustration
Here is how the layout is structured (I took out a bit for brevity):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false">
<!-- notification -->
<RelativeLayout
android:id="#+id/notification_bar"
android:layout_width="match_parent"
android:layout_height="40dip"
android:background="#drawable/notification_background"
android:visibility="visible">
<!-- end notifcation -->
</RelativeLayout>
<!-- header -->
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="47dip"
android:layout_alignParentTop="true" >
<ImageView
android:id="#+id/header_bg"
android:layout_width="match_parent"
android:layout_height="47dip"
android:src="#drawable/home_header" />
<!-- end header -->
</RelativeLayout>
<!-- buttons -->
<LinearLayout
android:id="#+id/buttons"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/footer"
android:layout_below="#id/notification_bar"
android:layout_gravity="center_horizontal">
<ImageButton
android:id="#+id/button1"
android:src="#drawable/button1"
android:layout_width="86dip"
android:layout_height="65dip"
android:layout_weight=".4" />
<ImageButton
android:id="#+id/button2"
android:src="#drawable/button2"
android:layout_width="98dip"
android:layout_height="73dip"
android:layout_weight=".2" />
<ImageButton
android:id="#+id/button3"
android:src="#drawable/button3"
android:layout_width="86dip"
android:layout_height="71dip"
android:layout_weight=".4" />
<!-- end buttons -->
</LinearLayout>
<!-- footer -->
<LinearLayout
android:id="#id/footer"
android:layout_width="match_parent"
android:layout_height="76dip"
android:layout_alignParentBottom="true"
android:background="#drawable/home_footer" >
<!-- end footer -->
</LinearLayout>
</RelativeLayout>
MAIN PROBLEM:
To start, I animated the notification bar. It moves, and at the end of the animation, it snaps back into place. Yes, I have fillAfter set to true. It doesn't make a difference. Regardless, the 3 items that should shift are clickable, and from what I've read, the elements haven't actually moved, they just look like they have.
SECONDARY PROBLEM:
The entire view is a RelativeLayout, however the three elements are in a LinearLayout set via the XML to be layout_below the notification bar. I had hoped that shifting the notification bar would squeeze this LinearLayout, shifting the buttons to accommodate, but no such luck. If I have to shift the three elements as separate animations, that's fine. I've tried that, but they suffer from the same "snap-back" issue the notification bar does. I was hoping there would be a simpler, more logical approach, however.
I've found a number of posts about this snap-back problem, but none of the solutions quite work (or make sense to me, granted a bit of a noob). It sounds like something needs to happen in the onAnimationEnd handler. I think it's something with adjusting the LayoutParams, but I'm not sure how or what to do there.
I'm targeting for API 8 (2.2), so the Honeycomb animation APIs won't help. I've looked into NineOldAndroids, which looks promising, but figure there has got to be a way to do this with the native API.
** Bonus points if we can get the notification bar to be dismissed, and everything moves back to its original position.
** UPDATE: The following code KIND OF works **
Here is the animation method to slide the notification bar out:
private void showNotification() {
mNotificationBar.setVisibility(View.VISIBLE);
Animation slideOut = AnimationUtils.loadAnimation(this, R.anim.slide_notification_out);
slideOut.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// do nothing
}
#Override
public void onAnimationRepeat(Animation animation) {
// do nothing
}
#Override
public void onAnimationEnd(Animation animation) {
// do SOMETHING
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mNotificationBar.getLayoutParams();
params.addRule(RelativeLayout.BELOW, mHeader.getId());
mNotificationBar.setLayoutParams(params);
mNotificationBar.clearAnimation();
}
});
mNotificationBar.startAnimation(slideOut);
}
Altering the LayoutParams on AnimationEnd keeps the Notification bar in place. AND, when the animation is done, the Buttons layout squeezes to accommodate! BUT, the button layout doesn't smoothly animate like the Notification Bar, it just snaps into place at the end of the animation. Also, the Notification Bar also jumps a bit at the very end of the animation, I'm guessing because the layout is being redrawn. SO CLOSE, but so far.
Snap back problem
You need to define the notification in the final place that you want it to appear in the layout. For you it's probably as the first item in the LinearLayout you refer above. Then you set visibilityto gone.
Finally you use a piece of code similar to the one bellow (I´m using it to animate buttons into the screen):
private void buttonFadeOut() {
linear_layout_buttons.startAnimation(AnimationUtils.loadAnimation(MyMapActivity.this, android.R.anim.slide_out_right));
linear_layout_buttons.setVisibility(View.GONE);
}
private void buttonFadeIn() {
if(linear_layout_buttons.getVisibility() == View.GONE){
linear_layout_buttons.startAnimation(AnimationUtils.loadAnimation(MyMapActivity.this, R.anim.slide_in_right));
linear_layout_buttons.setVisibility(View.VISIBLE);
}
}
Squeeze problem
This one I've never tried with an animation, but you can set the android:layout_weight="1.0" in each one of the items in your relative layout, to split the available space equaly between them (or play with the value to assign diferent space for each).
Regards.
I'm a novice on the Android platform when it cames to development. However I'm going further from basic Views and I'd like to create something like the following buttons:
This is what I want to achieve. I first tought that a Button with a custom background would have sufficed. However I don't know any way to make that small darker line with the text inside. All of the image reacts like a button and gets highlighted when you touch it.
Can you help me?
If you look at the source code for Apollo you can see ArtistsFragment is not made up of Buttons but rather an inflated RelativeLayout created by a subclass of the SimpleCursorAdapter class.
Since any view can have an OnClickListener you can make any create a layout to look however you want and still have it act like a button:
// Or load it as an item from an existing layout.
View myView = this.getLayoutInflater().inflate(R.layout.anything);
myView.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
// Do stuff.
}
});
Every segment with an image could be a Layout with the background set to the appropriate image. Then, you just put the button inside of the layout.
You have to use Framelayout or RelativeLayout. For example:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="#drawable/your_drawabele" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"
android:padding="12dip"
android:background="#AA000000"
android:textColor="#ffffffff"
android:text="your_text" />
</FrameLayout>
long time listener, first time caller...
I am creating a splash screen derived from Activity called SplashBase that is placed inside a shared project. The layout is the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linlytSplash"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
android:id="#+id/imgvwSplash"
android:src="#drawable/splashscreen"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
></ImageView>
<LinearLayout
android:id="#+id/linlytProgress"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:gravity="center"
>
<ProgressBar
android:id="#+id/progbarProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
></ProgressBar>
<TextView
android:id="#+id/txtvwProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:gravity="center_vertical"
android:text="#string/loading_ellipsis"
android:textStyle="bold"
></TextView>
</LinearLayout>
</LinearLayout>
I am loading the animations like this :
Animation animation = AnimationUtils.loadAnimation(this, R.anim.splashscreen_anim);
animation.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
// Advance to the next screen.
if (null != m_intentToLaunch) {
startActivity(m_intentToLaunch);
}
finish();
}
});
animation.setStartTime(AnimationUtils.currentAnimationTimeMillis() + 1000);
I have a derived class called Splash which lives in my main project.
I've had this splash screen for a long time now, the animation has always worked. My ImageView is shown for 2 seconds, and then animates and disappears before calling finish() and loading the next Activity.
I am now adding a ProgressBar which only be shown for the first second (not exactly, but it's clearer if I explain it that way). For some reason, after I hide the ProgressBar, the animation no longer works on the ImageView. When I call
findViewById(R.id.linlytProgress).setVisibility(View.INVISIBLE);
the animation no longer works. In order to test I have placed the following calls:
findViewById(R.id.txtvwProgress).setVisibility(View.INVISIBLE);
and then
findViewById(R.id.progbarProgress).setVisibility(View.INVISIBLE);
When I hide only the TextView, things work as expected. When I hide the ProgressBar, boom, my ImageView no longer animates. I'm at a loss.
Sounds like a bug to me. Create a sample project that reproduces the error and file a bug with that sample project on http://b.android.com. Be sure to mention on the bug where you're seeing this (particular hardware or emulator version). If you think of it, add a comment to this answer with a link to the bug report.
I finally found the answer to my own question. The view needed to be invalidated.
findViewById(R.id.imgvwSplash).invalidate();
et voila! It works exactly as expected, and so far on every platform that I tried it on.
Thanks to everyone who took a look at the question.
-I_Artist
Okay, so I've done some looking around and I see how you are SUPPOSED to do it, but for me, it is just not working.
I need to be able to set the alpha of a RelativeLayout both in XML and in code. For my XML, I have the following
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/player_controls"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:alpha="0.0">
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/player_controls_touch_me"
>
</RelativeLayout>
</RelativeLayout>
I get the error: no resource identifier found for attribute 'alpha' in package 'android'
Also, based on the Android documentation, I should be able to call setAlpha(double) on any View object, but when I try to make that call on a RelativeLayout it tells me that this method is not defined for this object.
Why am I not able to control the alpha transparency for a RelativeLayout object in Android? Am i missing something? Thanks!
Update
Although using the visibility property works, it prevents me from be able to click on the ViewGroup. This is important for me because I am utilizing the OnTouchListener of the ViewGroup.
What I am trying to do is to have a layer with media controls, initially hidden. when the user taps anywere on the screen, I want the controls to fade in and when they tap the screen again I want the controls to fade out. I have this part already working. I am using a viewgroup that sits over-top my entire application with an OnTouchListener attached that can determine if it has or hasn't been touched. My problem is that after the animation runs to fade out the controls, they re-appear. If I use #Hydrangea suggestion, I can have it fade out and immediately made invisible. This gives me the desired effect, but then the ViewGroup is unclickable and the user cannot get the controls to come back (or go away, depending on what we decide to do first).
I hope this makes sense.
You'll want to use a alpha animation to fade things in and out. This will maintain your touch events for your layouts. Here's an example
public class Main extends Activity {
/** Called when the activity is first created. */
private boolean mShowing = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.textview).setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
if(mShowing){
Animation animation = new AlphaAnimation(1.0f, 0.0f);
animation.setFillAfter(true);
arg0.startAnimation(animation);
} else {
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setFillAfter(true);
arg0.startAnimation(animation);
}
mShowing = !mShowing;
}
});
}
}
Here's the accompanying xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
android:clickable="true"
/>
</LinearLayout>
Unless you need levels of alpha between 0 and 1, I'd suggest, if you truly want to make this item invisible, to use setVisibility();
android:visibility="invisible"
I checked out the android:alpha line, and my ide doesn't find it either. I can't guess why, though... the documentation seems pretty clear.
The alpha property is new in Android 3.0, and it's not the most efficient way to hide a view. Use View.setVisibility() or android:visibility to achieve what you want.
You can set alpha by setting the (background) color i guess. Color values can be in the format of #aarrggbb (alpha, red, green, blue).
You can add to the right answer the following option:
animation.setDuration(xxx);
To each animation instance. In this way your animation will look better.
Based on your discription, you should be able to create a view that contains only the relative layout and have the onClickListener set to it. This way you can set the visibility of the relative layout to invisible, but still register a click.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/clickable_layout"
android:layout_height="match_parent"
android:layout_width="match_parent" >
<RelativeLayout
android:id="#+id/player_controls"
android:layout_height="match_parent"
android:layout_width="match_parent" >
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/player_controls_touch_me"
>
</RelativeLayout>
</RelativeLayout>
</FrameLayout>
Use onTouchEvent in Activity, and then you could get touch event to control to your RelativeLayout even if it is "invisible".