Motion Layout: How to change view visibility on last frame - android-studio

I am using motion layout in android studio to make a page that scrolls and looks kind of like Twitter. I want to set the visibility of the layout that contains the name to GONE at the very end of the animation.
Normally, if you set it to gone at the end it gradually disappears through the animation. But I want it to dissaper suddenly.
I am using motion layout and kind of understand key frames, but how do you do it with visibility?
Thanks.

I would like to leave an answer here, in case anybody encounter this like me:
Animating alpha and controlling its frames does the job, but the case when you want a view to be actually gone from the layout, I needed to make use of visibility for that.
I wrote it in another post, but keep it here for ease of read:
A background view, that should be gone when alpha is 0, and once alpha is getting greater than 0 just stay visible all the time, but motion shouldn't animate the visibility all.
Configure KeyFrameSet for visibility, so at frame 0 visibility is gone, and starting from frame 1 visibility is visible.
Set required visibility of the background view in both #id/start and #id/end constraint sets.
Set visibiltyMode as ignore for the background view in both #id/start and #id/end constraint sets, so motion will ignore animating this attribute for the background view.
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
android:id="#+id/transition"
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#id/start"
motion:duration="#integer/standard_duration">
<KeyFrameSet>
<KeyAttribute
motion:framePosition="0"
motion:motionTarget="#id/background">
<CustomAttribute
motion:attributeName="visibility"
motion:customIntegerValue="8" />
</KeyAttribute>
<KeyAttribute
motion:framePosition="1"
motion:motionTarget="#id/background">
<CustomAttribute
motion:attributeName="visibility"
motion:customIntegerValue="0" />
</KeyAttribute>
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/start">
...
<Constraint
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:visibility="gone"
motion:visibilityMode="ignore"
/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
...
<Constraint
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:visibility="visible"
motion:visibilityMode="ignore"
/>
</ConstraintSet>
</MotionScene>
Btw, the corresponding integer values for visibility are:
Visible = 0
Invisible = 4
Gone = 8

You can set the alpha value for the 0,99 and 100th frame positions as shown below.
<KeyFrameSet>
<KeyAttribute
android:alpha="1"
motion:framePosition="0"
motion:motionTarget="#id/textView" />
<KeyAttribute
android:alpha="1"
motion:framePosition="99"
motion:motionTarget="#id/textView" />
<KeyAttribute
android:alpha="0"
motion:framePosition="100"
motion:motionTarget="#id/textView" />
</KeyFrameSet>
By this way, the textview will fade out from 99 to 100th frame, but it will look as it disappeared almost suddenly.

Related

Is there a good way to make a button in Android do different things depending on if you click on the left half or right half of the button?

In an android app I am making, I would like to make a button that does different things depending on whether the user presses the left half of the button or the right half of the button. Right now I'm trying to figure out what would be the best way to accomplish this.
Some other specific requirements:
1. I'm planning on using the button 1 to 4 times per Activity.
2. It would be very helpful if I could be able to rotate the button (e.g. 90 degrees, 180 degrees so it's upside-down)
One idea I have had is putting two buttons side by side and putting a text-view on the top to make it look like one button. I found this doesn't really work well. It requires lots of effort to get it to show up properly and gets messed up when even small changes are made.
Another idea I had was making a custom button by extending the view class. Problem is I have no experience doing something like that and most of the tutorials I've seen use it to make paint programs.
What would be the best way to create something like this??
Edit: When I say rotate the button, I don't mean that the button needs to rotate when clicked or when some other action is performed. Just that it is facing in the direction I need it to be when the app loads. Also it only needs to be facing in the standard 4 directions (i.e. Down, Up, Left, Right). Sorry I wasn't more clear on that.
i created the first approach using framelayout as follow:
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="70dp"
android:onClick="rotate">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="#+id/view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView2">
<Button
android:id="#+id/button"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#color/colorPrimary" />
<Button
android:id="#+id/button2"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#color/colorAccent" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="Button text"
android:textAppearance="#style/TextAppearance.AppCompat.Display1"
android:textColor="#android:color/white" />
</FrameLayout>
for rotating any view create your anim.xml file inside anim folder in res
right click on res -> new android res dir-> choose anim then create anim file right click on anim folder you just created and new anim res file and the past the code in side it , this will rotate your framelayout in this certain code by 180 degeree
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<rotate
android:duration="500"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="180" />
</set>
use it as follow on kotlin
fun rotate(view: View) {
val rotate = AnimationUtils.loadAnimation(
applicationContext,
R.anim.rotate
)
frame.startAnimation(rotate)
}

How can I replicate a colored separator in Android Layout XML?

I need to replicate a legacy form that looks like this:
What is the Android equivalent for the "colored separators" setting off the UserName and Password portion of the screen? An ImageView? A TextView? Is something in the drawable folder in my future? Or...?
UPDATE
Der Golam's first example was perfect, except I needed some space, so I added the Space element after the top separator and before the bottom separator:
<Space
android:layout_width="wrap_content"
android:layout_height="6dip" />
UPDATE 2
On third thought, it's better to 86 the Space and just use one of the View element's margin properties, such as layout_marginTop or layout_marginBottom:
android:layout_marginTop="6dip"
It's just as simple as laying a generic View:
<!-- A horizontal line - play with the color and with the height -->
<!-- Play with margins, too -->
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#f800"
/>
<!-- A vertical line - play with the color and with the width -->
<!-- This can be nice as a ListView Item "bullet" -->
<View
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="#f008"
/>
You might want to use a more complex fill, such as a gradient...
Curious? wanna try?
Here's a simple tutorial, just in case: http://envyandroid.com/archives/242/drawable-gradient-lines-android

`VideoView.start()` cause other views to break

When my activity receives a new intent via onNewIntent, it updates the data of three Views, an ImageView, a TextView, and a VideoView. The problem is, the two other views just flash, then disappear when my VideoView comes on. After scattering a few breakpoints, I discovered that they appear when their content is set, but disappear when VideoView.onStart() is called in my MediaPlayer.onPrepared() method. I also have an AlertDialog show up when the menu button is pressed. After pressing the menu button, it shows up. I'm on Android API 9, as this is the API on the device I'm working on. I really need help, so I'd appreciate any advice.
Here's the layout. I don't think it's the issue though:
<?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:keepScreenOn="true" >
<TextView
android:id="#+id/marquee"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:ellipsize="marquee"
android:focusable="false"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#android:color/white" >
</TextView>
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_above="#id/marquee"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical" />
<VideoView
android:id="#+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/marquee"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_toLeftOf="#+id/image" />
</RelativeLayout>
Take note that the TextView is meant to be a marquee; it's supposed to keep scrolling sideways, until it is disposed of. I discovered that when the text is too short for it to start the marquee, the TextView AND the ImageView disappear (as stated earlier, they appear for a split second, then disappear). However, when the text causes the marquee feature to activate, everything works.
CURRENTLY:
I got it to work by calling postInvalidateDelayed(500) on my ImageView and TextView after calling VideoView.start(). I think the start() method is causing the problem, and requires that other views call invalidate(). Also, for some reason, there needs to be a small delay in-between the call to start() and the call to invalidate().
The layout is the issue.
Your VideoView is declared as match_parent, match_parent, allowing it to consume the whole width and height of the screen. Since you declared it last on the xml file (You used RelativeLayout. Ordering matters), the TextView and the ImageView would be covered by the VideoView.
If you're confused,
match_parent is basically the same as fill_parent. It's just another name for fill_parent in android 2.3+
Now what can you do about it?
Reorder your views in such a way that the largest is declared first. In this case, VideoView, then ImageView, then TextView.
Also note that your ImageView has height set to fill_parent - you may not want that.
I created a method, but it seems very bad:
private void startVideo() {
this.videoView.start();
if (this.imageView != null)
this.imageView.postInvalidateDelay(500);
if (this.textView != null)
this.textView.postInvalidateDelay(500);
}
It works, but it makes me feel dirty.

Android - ListViews inside tableLayout

I'm trying to build and app that shows organized data so I'm thinking that basically a TableLayout would be a good idea, just to keep them in rows, so I'm wondering whats the correct way to do it? I have this in my 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:orientation="vertical" >
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableRow>
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/hello" >
</TextView>
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="233dp"
android:layout_marginTop="44dp" >
</ListView>
</TableRow>
</TableLayout>
</LinearLayout>
then it's just that the TableLayout tag and TableRow tag displays a warning that says:
"This TableLayout layout or its LinearLayout parent is possibly useless"
so what I understand is that is not picking up the TableLayout. how can I fix this? is there another way to do this easly?
so what i understand is that is not picking up the tablelayout. how can i fix this? is there another way to do this easly?
Not quite, the renderer is taking account of the TableLayout but because the lint tool has detected that you have two views when you only need one (A LinearLayout and TableLayout) it is warning you that you should remove one of these layouts as it will boost performance while not effecting the functionality of the page.
I will add, you have a TableLayout with just a single row. TableLayout's are designed to allow their contents to format their columns based upon all of their rows. With a single Row the TableLayout & Row together are acting as a LinearLayout:
<LinearLayout>
<LinearLayout>
<ListView>
<TextView>
Since your TableLayout isn't adding any addition layout in that case it becomes obsolete and you will gain a resource boost from removing it and changing the orientation of LinearLayout to horizontal.
If you're planning to add more TableRow's later, then you should instead remove the LinearLayout for the same reason - it will then become the view which is not adding extra information: your table layout will be entirely responsible for the layout so you might as well make it the parent of the layout file (remember to add xmlns:android="http://schemas.android.com/apk/res/android" attribute to it if you do.)
In general I've seen the stronger warning:
This LinearLayout layout or its RelativeLayout parent is useless
when this is not the case. For example, this can happen if I've nested a linear layout inside a relative layout. The relative layout positions the linear layout exactly where I want it, the linear layout takes up space. Both are non-useless uses to me.
1) it says possibly so avoid drawing conclusions, trust yourself young padawan! But yes, the parent looks useless to me too :)
2) Using Table layout outside of your ListView wont change the rows' layout in the list, in case this is what you want to achieve.
You might have seen this but the Developers page offers a really good tutorial that can help you create a good base for your ListView (this example uses a ListActivity). Then on you can modify the rows' layouts using TableLayout ...etc.

Where is a reference to the android XML UI layout?

I am looking for a spec or reference of all the possible options for the various XML layout attribute settings that typically come with an android UI. Google seem to be good at burying it. This is similar to this question but remains in-effectively answered.
Such as what are my options available to me for the TextView layout_width definition ? There must be a complete definition published ... somehwere....
layout_* attributes aren't directly part of the view they appear on, which is why you won't find them in TextView's documentation. (TextView is not a ViewGroup.) They are arguments to the parent view, also known as LayoutParams. Take a look at the "Known Subclasses" sections at the top of the linked page for a list of them. They're instructions about how a ViewGroup should arrange each child view, and each parent type can recognize different ones depending on what kinds of layout options it supports.
For example, LinearLayout.LayoutParams supports the android:layout_weight parameter. Children of a LinearLayout can specify weight to request a proportion of the remaining space after all children have been measured. You can give equal weight to two sibling TextViews with a base width of 0 to give them each half of the available space within the parent.
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Hello" />
<TextView android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="World" />
</LinearLayout>
Normally developer.android.com is your site. Maybe this helps:
http://developer.android.com/reference/android/view/View.html
If you use Eclipse, then the autocomplete suggestions may help you as well in adding the right parameter.
...and the options you have for layout_width are
wrap_content (as large as the content of the View)
fill_parent (extends to the whole size - width or height - of its parent)
Layout parameters are pretty well described in the documentation for ViewGroup.LayoutParams and its subclasses. For the truly strong of heart, you can always browse the source for attr.xml.

Resources