I have a two RelativeLayout where I have set their visibility to gone using,
android:visibility="gone"
And then on the root element of the activity which is also a RelativeLayout, I have added this attribute
android:animateLayoutChanges="true"
Here's my activity java code
RelativeLayout rellay1, rellay2;
Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
rellay1 = findViewById(R.id.rellay1);
rellay2 = findViewById(R.id.rellay2);
handler.postDelayed(new Runnable() {
#Override
public void run() {
rellay1.setVisibility(View.VISIBLE);
rellay2.setVisibility(View.VISIBLE);
}
}, 2000);
}
When I run the app, the views get displayed immediately without any wait. If I increase the time to 5s, still same results.
I've looked at the logs when starting the activity and nothing suspicious.
NOTE
When answering questions on SO, I sometimes find it hard to understand the users problem when it's cluttered with XML, so I tried hard to keep my question clean. But that might not be enough to diagnose what's wrong with my code so I'm adding a minimal version of the xml for the parent and two child RelativeLayouts without their contents, just the attributes. If more detail is needed I'd be happy to provide.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:background="#drawable/grad_bg"
tools:context=".LoginActivity">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginRight="40dp"
android:layout_marginLeft="40dp">
<ImageView
android:id="#+id/img_view_logo"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="#drawable/ic_android_black_24dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"/>
<RelativeLayout
android:id="#+id/rellay1"
android:layout_below="#+id/img_view_logo"
android:layout_width="wrap_content"
android:visibility="gone"
android:layout_height="wrap_content">
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/rellay2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:visibility="gone"
android:layout_alignParentBottom="true">
</RelativeLayout>
</RelativeLayout>
From the XML above, you'll see that my intention is to have only the ImageView visible initially and the rest should become visible after 2s.
I have looked similar questions about Handler#postDelayed but the problems are not exactly like mine so the solutions where not applicable.
UPDATE
The only problem here seems to be my lack of proper understanding of the android lifecycle(I'm a beginner here). I carried out an experiment by killing all running apps and tried launching my app again and I saw the animation.
So I guess what was happening here was that, the view had already been created and since my activity was still alive even though I had exited the app, subsequent launches of the App loaded a previously saved instance of the activity and that is why it seemed as if the animation wasn't working.
Related
I'm building a simple Whack a Mole clone and I'm having trouble figuring out how to do my layout. I haven't played with Android dev since Gingerbread was new, and I've never tried to write a game before, so forgive me if these are newb questions but I've been stuck and Googling for hours now and I'm not getting answers.
I've basically got a 3x4 GridLayout, with 12 invisible mole ImageView declared in a layout.xml file, and I'm having trouble figuring out how I can create object references in my code from what I've created in XML so I can make them randomly appear and disappear and handle user touch events.
I'm seeing a lot of info about GridViews and Adapter objects being used to create references from xml and handle touch events, but I'm not sure how to do this using GridLayout. Should I switch to using a GridView in a LinearLayout, or is there some incredibly simple thing that I'm missing?
Also, would it be better practice to implement the onItemClickedListener() in my Activity subclass or my View subclass? I'm a little confused about how my View subclass relates to the XML layout. Maybe I'm just over-complicating this?
Thanks for any help, guys. Here's my layout.xml if that helps.
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="3"
android:rowCount="4"
android:useDefaultMargins="true"
android:background="#drawable/grass_bg"
android:id="#+id/wam_view_layout">
<ImageView
android:id="#+id/mole1"
android:visibility="invisible"
android:layout_width="120dip"
android:layout_height="140dip"
android:contentDescription="#string/mole_description"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="#drawable/mole" />
<ImageView
android:id="#+id/mole2"
android:visibility="invisible"
android:layout_width="120dip"
android:layout_height="140dip"
android:contentDescription="#string/mole_description"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="#drawable/mole" />
<!--pattern continues until mole12-->
</GridLayout>
Do something like that in your activity:
private ImageView imageMole1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
imageMole1 = (ImageView) findViewById(R.id.mole1);
imageMole1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// handle click here e.g. call a method
// void onMoleClicked(int moleId)
}
});
}
To change the displayed image use e.g.:
imageMole1.setImageResource(R.drawable.mole_gone);
I want to create a title screen for an Android app. The screen is a simple XML file with an image in it. Basically the screen will show until some other stuff finishes loading, upon which the screen will change to the app content. The problem is, many time the image in the XML doesn't appear at all - all I get is a blank xml page, and afterwards the app loads. I assumeit's because loading the image is done async or something. I tried to use Thread.sleep, which proved to be a bad idea.
Anyone has an idea how to get this to work?
Thanks!
The main xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_marginTop="128dp"
android:src="#drawable/icon" />
The main activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
<do some stuff>
start_other_activity_with_different_xml();
Ok, got found the answer faster than I expected. For my purposes, what I'm looking for is a splash screen, and a good explanation of how to create one can be found here: http://www.androidhive.info/2013/07/how-to-implement-android-splash-screen-2/
I've replaced in my fragment simple ProgressBar with ContentLoadingProgressBar.
Now fragment layout looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/simple_match_parent_style">
<android.support.v4.widget.ContentLoadingProgressBar
android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<TextView
android:id="#+id/txt_no_songs"
android:text="#string/txt_no_songs"
android:layout_centerInParent="true"
style="#style/txt_no_songs"/>
<ListView
android:id="#+id/list"
android:fastScrollEnabled="true"
android:divider="#null"
style="#style/simple_match_parent_style"/>
</RelativeLayout>
I show this ProgressBar in onViewCreated:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
progressBar = (ContentLoadingProgressBar) view.findViewById(R.id.progress);
progressBar.show();
...
}
For test purpose I've removed progressBar.hide() call to make ProgressBar appear in any case. But the problem is that my ContentLoadingProgressBar is never really shown.
Should I do something else to show ContentLoadingProgressBar? I didn't manage to find any relevant examples of using ContentLoadingProgressBar so any useful examples are also desirable. Thanks in advance.
Seems you need a style, for example...
style="?android:attr/android:progressBarStyleHorizontal"
Works for me if I put that anyway, without I never see anything.
Also consider putting it above your content (ie below in the xml)
I had tried this :
<android.support.v4.widget.ContentLoadingProgressBar
android:id="#+id/address_looking_up"
style="?android:attr/android:progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:visibility="visible" />
But, it didn't work at Android 5.0. Some more details about ContentLoadingProgressbar should be here.
PS: Alright, the attribute of 'style' matters here. Change the style to "?android:attr/progressBarStyleLarge" and it works.
Meanwhile, the display effect of this widget depends on the Theme of your app.
You should add style to ContentLoadingProgressBar.
<androidx.core.widget.ContentLoadingProgressBar
android:id="#+id/progress"
android:layout_width="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:layout_height="wrap_content"/>
1.SDK said that “Show the progress view after waiting for a minimum delay. If
during that time, hide() is called, the view is never made visible.”
2. I think your layout should modify like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/simple_match_parent_style">
<TextView
android:id="#+id/txt_no_songs"
android:text="#string/txt_no_songs"
android:layout_centerInParent="true"
style="#style/txt_no_songs"/>
<ListView
android:id="#+id/list"
android:fastScrollEnabled="true"
android:divider="#null"
style="#style/simple_match_parent_style"/>
<android.support.v4.widget.ContentLoadingProgressBar
android:id="#+id/progress"
android:layout_width="wrap_content"
style="?android:attr/progressBarStyleLarge"
android:visibility="gone"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
Check the ContentLoadingProgressBar.onAttachedToWindow() or ContentLoadingProgressBar.onDetachedToWindow() if you are creating multiple views at the same time, it might causing the private removeCallBacks() being called in onAttachedToWindow() or onDetachedToWindow(). Thus causing the runnable to not run, which means nothing will be displayed.
You can, for example:
Simply remove private removeCallBacks() calls in onAttachedToWindow() or onDetachedToWindow(). To prevent this from happening. Don't forget to make private removeCallBacks() to public and call it in onDestroyView() for proper cleanup.
Update:
I ended up separating out the video player into a separate activity and layout. I then started this activity using the code below.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startActivityForResult(new Intent(MainActivity.this, VideoActivity.class), VIDEO_PID); //load video
//etc.
}
When the app is loaded, I call this function to kill the Video Activity and bring the main activity to the front:
public void doneLoading() {
finishActivity(VIDEO_PID);
}
I don't know if this is the best way, but it worked.
=======================
What's the easiest way of showing a centered VideoView and then switching to a WebView after the application is fully loaded? I verified that both these views work when included individually in the app. I just want to only show the VideoView when loading, then hide it until the application is closed.
I was looking into ViewPager and ViewFlipper, but I haven't gotten anything working yet. I was going to avoid including them in separate activities. PageViewer seemed to manage the views (meaning allow them to run and init themselves), but not actually display them (all I saw was a black screen). I'm probably missing something.
Would it be easier to start the loading video then start off another activity that initializes the webview, which requests focus and sends a message for the loading video activity to quit after initialization is finished?
My layout is below to give an idea of what I'm using.
Thanks.
P.S. I'm avoiding the use of Fragments for Gingerbread support.
<?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"
>
<android.support.v4.view.ViewPager android:id="#+id/view_pager"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1" >
<VideoView
android:id="#+id/videoview_component"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_gravity="center"
/>
<WebView
android:id="#+id/webview_component"
android:layout_width="fill_parent"
android:layout_height="0dip"
/>
</android.support.v4.view.ViewPager>
</LinearLayout>
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