Android - drawing cache - when is it useful? - android

I am reading about setDrawingCacheEnabled and getDrawingCache and I was wondering when is it good to use it or when its not good.
Basically in my case I have an HorizontalScrollView with many things inside it so its scrolls left/right and most of the things are not visible.
If I use setDrawingCacheEnabled(true) on the views, does it help? or this is only when I use custom views and I call getDrawingCache()?
Is there any other 'cache' way to use in a HorizontalScrollView?

TouchInterceptor.java - This is class responsible for reordering your playlist in the default music player. It uses setDrawingCacheEnabled when you start dragging the current view. Basically, it creates a bitmap from the ListView item and drag it. Take a closer look at onInterceptTouchEvent method.

It's definitely useful for screenshots as Marcel said. It is also very useful performance-wise, as that is what it was created for. It does use up more memory, as you render the view into a bitmap first.
What you do is, you setDrawingCacheEnabled to true, call getDrawingCache which returns a bitmap and store this bitmap. In onDraw, you do draw the bitmap you got if the cache is on, or the view otherwise. This can be very nice when scrolling.

Related

Update view's canvas outside of onDraw on Android

I need update a small portion of a custom view in order to display a small animation. The rest portion of the view has only static image. The most straightforward would be to obtain the canvas of the view and update only that particular portion directly. But I can't really find anyway to get the view's canvas object outside of the view::onDraw method.
The only alternative I know is this: call view::invalidate() with a specified rectangle to minimize the drawing flicker. I have the code to update the entire view within onDraw. So the best thing to do is to detect the clipping rect and only run the code to update the specified area, in order to minimize CPU usage as well?
I guess I will try to answer this question myself to the best my knowledge so far.
There is no direct access to the canvas outside of the onDraw method.
Although we can detect the clipping rect with the function Canvas.getClipBounds(), the getClipBounds function always return the entire view area if GPU is enabled. When GPU is not used, getClipBounds() returns the actual dirty area. Since there is a GPU in most phones, it makes the function getClipBounds pretty much useless.

android - Slide ListView with setX, setPadding, or tween animation?

Without going into too much detail, I want to be able to 'slide' elements in a ListView similar to the 'slide to archive' feature in GMail. I'm fine with the onTouchListener and all that, my question is regarding the slide animation.
The first two things that come to mind are..
view.setPadding(slideOffset, 0, 0, 0);
and..
view.setX(slideOffset);
The former is very buttery, even on the emulator.
The latter is a bit janky on my Galaxy Nexus.
My questions:
* Regardless of what I've tried, what's the correct way to do this?
Why is setX less smooth than setPadding?
Does one approach conform to Android best practices more than the other?
Are tweened translation animations an option? If so, can you provide a brief example to point me in the right direction please?
Edit:
To be clear, I am attaching an image of the effect I am trying to emulate.
I'm pretty sure the setX() is slower because it affects its parents. When changing the X of a view, it calls the onLayout/onMeasure of the parent every time you update the value. That's because the X value of the child may cause other items on the parent to move, therefor the parent needs to redraw itself.
You can test this easily by extending the ViewGroup and writing to the log on those methods. Then, you can use both approaches, padding vs. setX, and see what happens.
Are you trying to animate the item? Or do you want the user to move it like on Gmail? You can use the ObjectAnimator to handle the "X" value of your item. Combined with a "hardware layer" for your item, it will create a smoother experience. You can find more details about how to do that here: http://developer.android.com/guide/topics/graphics/hardware-accel.html
Yeah, if you're targeting higher APIs, ViewPropertyAnimator is probably a great solution. If you have to support lower APIs, my thought process for implementation would be (and I haven't implemented this myself personally, but this should be good for performance) to:
In your touch handler, once you've determined that the user is "sliding", set the View's visibility to INVISIBLE, and store the drawing cache into a separate bitmap (Bitmap bmp = myView.getDrawingCache();)
Draw that bitmap in the same place as the view, and use the Canvas translate methods to shift the position according to the x-position of the user's touch point.
After the user lets go, translate back (preferably smoothly with an animation), recycle the bitmap, and set the view back to VISIBLE.
Check out the 3 devBytes posted on AndroidDev:
https://www.youtube.com/watch?v=8MIfSxgsHIs&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=12
https://www.youtube.com/watch?v=NewCSg2JKLk&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=11
https://www.youtube.com/watch?v=NewCSg2JKLk&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=11
https://www.youtube.com/watch?v=YCHNAi9kJI4&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=4
https://www.youtube.com/watch?v=PeuVuoa13S8&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=3

Android Custom View Performance

This is the situation
- My root layout is scrollview
- A custom view with multiple drawing operations is embedded in the layout
My problem is that if the layout is scrolled then customview.ondraw() is being called multiple times. Since there are many operations in the ondraw() I am getting a performance hit.
What is the best strategy out of this?
See the docs on View.setDrawingCacheEnabled(). Note you have to call getDrawingCache() in your onDraw implementation, and draw the returned bitmap if getDrawingCache() returns a non-null value. I'm not sure whether ScrollView will take care of calling setDrawingCacheEnabled automatically. You'll have to try it and find out. I think it does; but you still need to call getDrawingCache() in your onDraw routine.
That takes care of the non-hardware accelerated cases.
For hardware accelerated views, see the docs for setLayerType. It's far from a given that caching hardware accelerated views actually provides a performance improvement, so do this cautiously.
Forgot the name of the methods in Android, but there is a Swing demo with a split pane.
If there is a flag set to true ( update continuously) than the split panel is drawing wile you move the spit components. The same effect is at scroll too. You can use a draw, continuously and another only when the scrolling finished. The same thing is at iOS too.
You need to find which are those methods and embed your custom view drawing when is needed.

Draw View before displaying during animation

I have two views in a ViewFlipper and have a fast/complex animation between them. The second view contains a list, so at the moment that view become visibile half way through the animation, getView() is called a bunch of times and causes a very noticeable stutter (usually stalling for the entire second half of the animation)
Ideally I would like to pre-render (measure, layout, draw) the second view before starting the animation, but I have not found a simple way to do this.
I have also explored using the drawing cache, off-screen canvases, etc - but I cannot find a simple way to achieve this either. Seems to be a problem anyone animating between two views would have. Any help?
You can do that by specifying a layer type and calling buildLayer() before you start your animation, which forces rendering the view.
newView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
newView.buildLayer();
You could also use LAYER_TYPE_SOFTWARE. The default value is LAYER_TYPE_NONE, which prevents buildLayer() to do anything.

Making a draw/paint app

I'd like to include a simple draw feature on my app. A friend told me I can't use canvas because I need to control the frame buffer and not redraw the entire screen every for every frame. He suggested I find a openGL 2d engine. I've searched around and I've only found Rokon which doesn't have any documentation and the examples aren't quite what I need.
Any suggestions?
I don't really understand what the problem is?
If you simply wish to redraw some portion of the canvas you can use invalidate(rect).
http://developer.android.com/reference/android/view/View.html#invalidate()
Just create a custom veiw by extending the view class. in this custome view override the onDraw method. Android itself takes care of the pixels that have been changed and calling invalidate only refreshes the pixels that have been marked dirty

Categories

Resources