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.
Related
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.
I am just learning about android development, and I am having some issues with getting this to work.
I have an activity that uses a relatively layout. I need it to have 2 buttons along the bottom, and then right above the bottoms, I want my custom view to take up the rest of the space.
viewer.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/viewerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<sketchViewer.AnimationPanelView
android:id="#+id/animationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/homeFromViewerButton"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<Button
android:id="#+id/homeFromViewerButton"
android:layout_width="640dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="Replay" />
<Button
android:id="#+id/replayButton"
android:layout_width="640dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Home" />
</RelativeLayout>
The issue I am having is I that when I run my program, I need to pass a number of parameters into my custom view constructor so that my custom view decides what it should draw. So after creating an instance of my custom view (AnimationPanelView), I am not sure how I set this object into the space I provided for the view.
This is my activity class:
Viewer.java
public class Viewer extends Activity {
AnimationPanelView animationPanelView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewer);
animationPanelView = new AnimationPanelView(this, true /*, more parameters here */);
animationPanelView.setBackgroundColor(Color.GREEN);
RelativeLayout v = (RelativeLayout) findViewById(R.id.viewerLayout);
v.addView(animationPanelView);
}
Right now, with my v.addView command, the view takes up the entire page, covering up the buttons at the bottom. Can anyone shed some light on this? I feel like I am close, but I've been playing around with it for a while, and I just seem stuck.
Check out the implementing a custom view section here. You need to override onLayout and onMeasure so you can tell your container how big you are.
You are adding another custom view to your layout instead you should use
animationPanelView = (AnimationPanelView) findViewById(R.id.animationView);
animationPanelView.setBackgroundColor(Color.GREEN);
I've got three views in my activity in a linear vertical layout. The top and bottom views have fixed heights and the middle view takes whatever height is left available. This is how I set the sizes for the views:
void resize(int clientHeight)
{
int heightMiddle = clientHeight - heightTop - heightBottom;
topView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, heightTop));
middleView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, heightMiddle));
bottomView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
}
In order to obtain the clientHeight, I overrode the onMeasure() function and call resize() inside my overridden onMeasure() function. This works well in onCreate(). However when the phone orientation changes, it does not work. What I observed is that after onCreate(), onMeasure() is called twice. After onConfigurationChanged(), onMeasure() is only called once and my resizing code does not get a chance to take effect. My kluge solution is to setup a timer to call resize() 20ms later:
timer.schedule(new TimerTask()
{
#Override
public void run()
{
activity.runOnUiThread(new UiTask());
}
}, 20);
where UiTask will simply call resize(). This works for me, but I feel that there's got to be a better solution. Can someone shed some light on this?
Why not let LinearLayout do the layouting with the help of the android:layout_weight attribute? That way, you don't need any extra code at all, everything will just work. Here's what your res/layout/main.xml could look like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Top"
android:layout_weight="0"
android:background="#ff0000"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Middle"
android:layout_weight="1"
android:background="#00ff00"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="25dp"
android:text="Bottom"
android:layout_weight="0"
android:background="#0000ff"
/>
</LinearLayout>
And with no more code other than the regular
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
it would look like this in portrait:
and like this in landscape (automatically relayouted and redrawn):
This works both with and without android:configChanges="orientation" for the activity in the manifest. You'll also be able to setup the above layout using Java code if you need to.
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
I want to place a common banner and menu on each Activity with footer too.
Can anyone guide me how can I implement master and child page like asp.net in Android???
Any help would be appreciated.
You could have each of your Activities extend a common base class which has a onCreateOptionsMenu method which inflates the menu from the same XML each time. Though as you can't have multiple inheritance, this may be tricky when you want to have plain activities and list activities, for example.
Another way would be to have a Util class where you have a method like setupMenu(Menu) which each of your Activities can call if you're doing some more complex menu setup.
In terms of the XML UI layout for each of your Activities, you can include a common banner by using the <include/> tag.
The solution was pretty easy.
You need to extends "Activity" Class,in onCreate function SetContentView to your base xml layout and also need to override setContentView in base Activity Class
For Example:
1.Create "base_layout.xml" with the below code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#000000"
android:padding="15dp" >
<LinearLayout android:orientation="horizontal" android:background="#000000"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:minHeight="50dp" android:paddingLeft="10dp">
<ImageView android:layout_width="wrap_content" android:id="#+id/ImageView01"
android:adjustViewBounds="true" android:layout_height="wrap_content"
android:scaleType="fitCenter" android:maxHeight="50dp" />
</LinearLayout>
<LinearLayout android:id="#+id/linBase"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</LinearLayout>
</LinearLayout>
2.Create "BaseActivity.java"
public class BaseActivity extends Activity {
ImageView image;
LinearLayout linBase;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.base_layout);
linBase = (LinearLayout)findViewById(R.id.linBase);
}
#Override
public void setContentView(int id) {
LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(id, linBase);
}
}
and
public class SomeActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.some_layout);
//rest of code
}
}
The only thing I noticed so far was that when requesting a progress bar (requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) this needs to be done before calling super.onCreate. I think this is because nothing can be drawn yet before calling this function.
This worked great for me and hopefully you will find this useful in your own coding.
I've had the same problem and solved it using ActivityGroup.
I suppose that menu items will move user to another activity, so with the same menu in every activity closing application with BACK button can be almost impossible (after some time user will have to go back through all activities he had ever seen).
I haven't found any good tutorials in english so have written mine some time ago (it's somewhat too short and in polish only, but Google Tranlslated version should be understandable) check this
You can also check how the TabHost works
ViewStub is the solution
activity_masterpage.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ViewStub android:id="#+id/stub_content"
android:inflatedId="#+id/subTree"
android:layout_width="match_parent"
android:layout_height="match_parent" />
stub = (ViewStub) findViewById(R.id.stub_content);
stub.setLayoutResource(R.layout.content_layout);
stub.inflate();