Viewgroup draw not called again after background manipulation - android

I have a custom ViewGroup that overrides draw() to draw some stuff over its children. It calls setWillNotDraw(false) on the constructor appropriately, and under normal conditions, works as intended.
My problems start when, in the layout XML, on such view I assign a background drawable ("splash screen") and later on in the application I remove this background (setBackgroundDrawable(null)). This happens only once, while application is initializing.
<com.regaliz.gui.layouts.FunqRootLayout xmlns:android="..."
.
android:background="#drawable/a_filmnew_cover_play_splash">
From that point, onDraw / draw is never called again whenever I invalidate the ViewGroup.
I've checked the View.java's setBackgroundDrawable source code and saw a lot of logic to manipulate the View Flags to add or remove WillNotDraw-related internal flags (but all the methods are private). I suspect this is what's happening: The call to setBackgroundDrawable(null) sets the willNotDraw flag), however I am not able to enable it again.
Subsequent calls to
setWillNotDraw(false)
are ignored.
To make things funnier, if I don't assign any background in the XML, the setBackgroundDrawable(null) call doesn't seem to touch the flags, so I don't have this problem.
What can be happening?
This is the splash drawable:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:src="#drawable/a_filmnew_cover_play" />

try overriding dispatchDraw(Canvas) method

Related

Nesting custom views

I have a custom view that, on a high level, takes whatever drawable one might pass into it and draws a ring around it, the ring is animated, and comes with a whole set of parameters; things such as ringWidth, gradient colors, etc.
Currently, to show/specify this view in my XML, my markup looks a lot like this:
<RingedImageView
android:id="#+id/ringedImageView"
android:layout_height="#dimen/image_gigantic"
android:layout_width="#dimen/image_gigantic"
app:source="#drawable/ic_icon_1"
app:ringWidth="2dp" />
This is all well and good. However, instead of passing in a drawable as the image in the middle, what I would like is to be able to pass in a whole view, entirely seperate from #id/ringedImageView.
Ideally, I'd like this to look as follows in my XML:
<RingedImageView
android:id="#+id/ringedImageView"
android:layout_height="#dimen/image_gigantic"
android:layout_width="#dimen/image_gigantic" ...>
<ImageView
android:id="#+id/imageView" .../>
</RingedImageView>
My question then is, can I access that nested ImageView in my RingedImageView.java class? How can I specify how to handle this situation?
Some answers point to having to extend ViewGroup instead of View, but as this isn't a layout manager per se, and the component comes with its own rules for displaying content, a View seems more appropriate. Would appreciate a pointer.
Thanks all

Extending LinearLayout

I want to extend the linear layout class, and alter some of its properties.
One of the properties that i want to alter, is the background.
The attribute background would be set to something, and if this background is shorter than the view's height, i want it to be vertically repeated.
if in the constructor i use getBackground() i get the background that was set to the view.
However, when i try to tile it, it shows great once, but all the locations it should repeat in, it is just smudged.
How do i get the view's ResourceID background instead of the background image, so i can work on it without the "super." methods being called on it first?
If your only reason to extend LinearLayout is to set a repeating background or a non-repeating background then there's no need to extende LinearLayout.
You can create a repeating background from a excisting Drawable using a drawable xml file:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:tileMode="repeat"
android:src="#drawable/your_drawable"/>
Depending on your 'state' you can set the background of the LinearLayout to your choice.

Change background of a custom view when touched

I want to change the background color of a customView when it's pressed and slightly "remove" this background color when the view losses the "pressed-state". However, I googled this question and found a solution using a StateListDrawable. I've tried this within my customView (which is added to a ListView programmatically), but just the "normal color" was set to my view. When I touched the view nothing happens. What's going wrong?
the selector xml-file:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#color/bckgr" />
<item
android:drawable="#color/transparent" />
</selector>
within the constructor of my custom view:
this.setBackgroundResource(R.drawable.list_item_bckgr);
you have to apply your background to the View the Adapter fills up (the view your getView implementation is returning) not to the ListView self
Try setting android:descendantFocusability to true on the ListView.
Hey Are you making the view focussable and clickable, use in the constructor:
setClickable(true);
setFocusable(true);
May be your view isn't getting focus.
You need to set the OnTouchListener to handle touch events. When the view is touched, change the background, and when the view is 'untouched', change the background back to the original.
To set the listener, call the View.setOnTouchListener() function of your custom view with the OnTouchListener you create to handle these events.
Here is the reference to OnTouchListener:
http://developer.android.com/reference/android/view/View.OnTouchListener.html
I imagine that you have an override method to the OnTouch() method, what I would do is create an instance variable (class var) that would hold the image that you want to have as a background, and set it in your OnTouch() method. Then, Override your OnDraw() method which would give you a reference to the canvas, and use the canvas.DrawBitmap() to draw your background.
This answer shows you more details on how to draw the bitmap
Setting background image in a custom view

Is it possible to set event listener in XML?

When I using XML to design layout, I am using findViewById() in java code to load views and set listeners to them.
Is this correct what I am doing? May be it is possible to set listeners in XML or something?
Most people set their listeners in code. It's sometimes easier to do it in code because you often times will need to add or remove listeners based on some action or state.
However, Android also gives you the option of setting a OnClickListener for any View in XML. Here's an example:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onActionClick"
android:text="Action" />
Using the onClick attribute, you assign the name of the method that will handle the click. This method must exist in the same Context as the View, so in the same Activity. So for example, I would have to implement this method:
public void onActionClick(View v) {
// Do stuff for my "Action" button...
}
I believe it has to have a View parameter, just like implementing OnClickListener would. I also believe it must be public.
So as far as which way is "best"? That's up to you. Both routes are viable. It's worth noting though that this is only useful for click listeners and not other types of listeners.
There is an onClick attribute that you can use inside your xml.
You may specify android:onClick attribute when describe your View in XML. The value of this attribute is the name of the method which will be called at your View's onClick event. Then you should define this method as public in your code and you could pass there View object which will determine what View from those that you described at xml with the same android:onClick attributes has gotten touch event from user.
you can set an onClick but I think thats about it

Android: draw on a view inside an inflated xml (another view)

I have a small xml file called 'xmlview.xml' which is something like:
<tablelayout>
<tablerow>
<view id="view1" />
I created a class which extends view, and I inflated that xml file and now i have a view obtained due to inflation.
xmlView = layoutInflater.inflate(R.layout.xmlview, this);
I am wondering is there a way to draw on the view 'view1' inside the view 'xmlview'
I tried something like:
View view1 = (View)xmlview.findById(R.Id.view1);
and then I tried in the overriden onDraw to draw on view1 but nothing worked,
any ideas ??
Seems to me maybe you should try something like this:
<TableLayout>
<TableRow>
<com.yourdomain.yourproject.ViewClassName>
Then you can create a class ViewClassName that extends View and, on that class, override the onDraw method. This is explained in detail here: http://developer.android.com/guide/topics/ui/custom-components.html. You can go directly the topic Modifying an Existing View Type
See, you don't need to inflate the view if the only reason to do this is to try and manipulate the view's drawing. And if it is the only reason, you really shouldn't.
hope I helped
I'm not sure what exactly you mean by "draw on the view", but it sounds like you should be looking into the Canvas. You should not arbitrarily override the onDraw method, this is what causes your widgets to appear on the screen.

Categories

Resources