Set Background color of Surface View - android

I want to set a background color to the surface view to my camera surface view.
I am using this for implementing the same. But this example is not complete. Can anyone please help me with some other useful link.
Thanks

There's a workaround to do this.
add a parent viewgroup for the surfaceview, set the background color to this viewgroup instead of the surfaceview;
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_dark">
<com.example.surfacetest.MySurface
android:id="#+id/surface"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
add the following for the SurfaceView instance;
surfaceView.setZOrderOnTop(true);
surfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
Now you get the background color you want and the surfaceview is tanslucent.

use surfaceview_obj.setBackgroundColor (int color) to set background color..
to set white color as background use this code
surfaceview_obj.setBackgroundColor(0Xffffffff);
check this

just draw a Rect object with canvas.drawRect(). set the co ordinates to 0,0,screenX,screenY

you have to do a little hack-around to make any background work in SurfaceView, like this:
override the setBackground and setBackgroundDrawable methods
Drawable background
#Override
public void setBackgroundDrawable(Drawable background) {
this.background = background;
}
#Override
public void setBackground(Drawable background) {
this.background = background;
}
don't forget to call setBounds on the drawable
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
matrix = null;
if (background != null)
background.setBounds(left, top, right, bottom);
}
then on the code you're locking, drawing, unlocking and posting the canvas you add the background
Canvas c = holder.lockCanvas();
if (background != null)
background.draw(c);
// do your stuff here
holder.unlockCanvasAndPost(c);
works for both XML and Java backgrounds.

Use this
surfaceview.getHolder().setFormat(PixelFormat.TRANSLUCENT);

Just put ARGB value in your draw method before your drawing(e.g. rect, circle etc). I have set it white. The last parameter is transparency.
c.drawARGB(255, 255, 255, 255);

Related

Animating ActionBar's icon

I have an ActionBar icon (the main one on the left, not an action item) that I would like to animate.
I am setting my ActionBar's icon in my Activity like this:
getSupportActionBar().setIcon(icon)
where icon is a Drawable produced by a library that converts a custom XML view into a bitmap. This XML view is a RelativeLayout with a background image and a TextView on top.
Today, when I have to update the TextView I simply re-generate the icon and call setIcon again. Instead, I would like to get a hold of my TextView and apply some animation effect on it, like fade-out and then fade-in after updating it (maybe never having to call setIcon, just re-use the same one).
Not sure how to go about this. Can someone recommend an approach?
EDIT: trying this approach:
In MyActivity:
Drawable myDrawable = new MyDrawable();
supportActionBar.setIcon(myDrawable);
and:
public class MyDrawable extends Drawable {
private Paint paint;
private RectF rect;
public MyDrawable() {
this.paint = new Paint();
this.rect = new RectF();
}
#Override
public void draw(Canvas canvas) {
paint.setARGB(255, 0, 255, 0);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.FILL);
rect.right = 20f;
rect.bottom = 20f;
canvas.drawRoundRect(rect, 0.5f, 0.5f, paint);
}
#Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
}
#Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
}
Nothing shows up. I verified that onDraw gets called. Something suspicious to me is that canvas has both height & width set to 1.
A proper approach for it would be to forget the XML layout and create a custom Drawable.
An instance of this custom drawable will be set to the icon on the ActionBar and call invalidateSelf() whenever necessary to redraw (due to animation, for example).
The drawable can hold reference to other drawables (e.g. BitmapDrawable to have something from the /res/ folder or a Color or Gradient drawable for a background shade) and call (for example) bgDraw.draw(canvas) during the onDraw callback.
It can also draw stuff directly on the canvas that is given to it during onDraw callback. With the canvas you can draw circle, lines, areas, path and text directly on it.
edit:
very simple animation example (didn't check the code, likely typos):
private long animationTime;
public void doAnimation(){
animationTime = System.currentTimeMilis() + 3000; // 3 seconds
invalidateSelf();
}
public void onDraw(Canvas canvas){
// do your drawing.
// You can use difference between
// currentTimeMilis and animationTime for status/position
...
// at the end
if(animationTime > System.currentTimeMilis())
invalidateSelf();
}

How can add selector to custom view?

I create a custom view and add selector to my custom view. Selector works, but background stretches full width and height. And background must displays what I draw.
Full code http://pastebin.com/dmF6DiP8
#Override
protected void onDraw(Canvas canvas)
{
Log.d(TAG, "init onDraw");
if (canvas != null && mDrawable != null)
{
mDrawable.setState(getDrawableState());
canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mBackgroundPaint);
mDrawable.draw(canvas);
}
}
Now normal state:
Now pressed state:
Must be:
What you are doing is drawing the circle first and then drawing a your drawable on top of it. The circle is underneath the drawable so you can't see it. The circle is also being drawn with the same color every time and it is not taking it from the drawable at all.
What you need to do is apply the color to the circle depending on the selector state and remove the call to draw the drawable on the canvas.

Create a layer with black transparent over an activity

I want to create a layer with transparent layer over an activity and I need to make visible only a particular view, say for an example "Login Button". It something mean that making hole on layer exactly the size of the button. Please anyone help me out of this.
Thanks In advance.
Programatically, you can use Canvas to create a layer. Fill the whole thing with your color and cut out a hole.
public class DrawView extends View {
Paint paint = new Paint();
Paint transparentPaint = new Paint;
public DrawView(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
//first fill everything with your covering color
paint.setColor(yourTransparentColor);
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
//now clear out the area you want to see through
transparentPaint.setAlpha(0xFF);
transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
Rect rect=new Rect(left, top, right, bottom);//make this your rect!
canvas.drawRect(rect,transparentPaint);
}
}
If I understand your question correctly
Your parent Layout of the Activity will be a RelativeLayout. In your parent layout at the bottom add another child RelativeLayout that implments the match_parent parameters for both width and height. You can then set a color like this #99000000 to it's background. This will give you a black transparent layer over your parent.
Something like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<!-- here you add your activities views ect... -->
<RelativeLayout
android:id="#+id/childLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99000000">
<!-- This will be your overlay so here you can add your login button ect -->
</RelativeLayout>
</RelativeLayout>
I didn't test this but it should solve your issue
On following "HalR" Steps , I was able to achieve the transparent background Thanks to him and found some of you are getting pitch black on the cut made over transparent layer is due to Graphic rendering . that can be enabled using below code inside onDraw method
` #Override
public void onDraw(Canvas canvas) {
if (android.os.Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
.....
..... // your draw rect creation and other stuff `
which will let you have the transparent area by eliminating the Pitch black color
If i understood your question then this is what you wanted:
You tried to overlay a transparent view on your activity and cut out holes to see few stuffs.
here i found an useful example which shows how can you cut out bitmaps and combine them. i would suggest for your problem just take the part of cutting the bitmap and remember to set the imageview backgroung with opacity as shown here
android:background="#00ffffff"
here is the layout i created
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/ic_launcher"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"/>"
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ffffff"
android:scaleType="centerCrop" >
</ImageView>
</RelativeLayout>
and this is my maniactivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView iv = (ImageView) findViewById(R.id.img);
Bitmap foreground = BitmapFactory.decodeResource(getResources(), R.drawable.android_cat_wanted);
foreground = punchAHoleInABitmap(foreground);
iv.setImageBitmap(foreground);
}
private Bitmap punchAHoleInABitmap(Bitmap foreground) {
Bitmap bitmap = Bitmap.createBitmap(foreground.getWidth(), foreground.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
canvas.drawBitmap(foreground, 0, 0, paint);
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
float radius = (float)(getScreenSize().x *.35);
float x = (float) ((getScreenSize().x*.5));
float y = (float) ((getScreenSize().y*.5));
canvas.drawCircle(x, y, radius, paint);
return bitmap;
}
#SuppressLint("NewApi")
private Point getScreenSize() {
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
}
hope you find it useful

How to apply a color filter to a view with all children

How do I grey out a view uniformly which contains many different items - ImageViews, TextViews, background image. Do I have to grey out each thing individually? Or is there a way to apply the same color filter to all?
Unless somebody else has a better answer, my current method is greying out each item separatedly.
PorterDuffColorFilter greyFilter = new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
myLayout.getBackground().setColorFilter(greyFilter);
myImageView.setColorFilter(greyFilter);
myTextView.setTextColor(0xff777777);
For more or nested children probably a loop with instanceof would be suitable but I don't need it.
Edit: This filter isn't actually grey, a better filter is here: Drawable => grayscale
Which can be used in the same way.
It's easy to do that by defining a custom view group as follows:
public class MyViewContainer extends XXXLayout {
//XXLayout could be LinearLayout, RelativeLayout or others
private Paint m_paint;
//define constructors here and call _Init() at the end of constructor function
private void
_Init()
{
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
m_paint = new Paint();
m_paint.setColorFilter(new ColorMatrixColorFilter(cm));
}
#Override protected void
dispatchDraw(Canvas canvas)
{
canvas.saveLayer(null, m_paint, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
canvas.restore();
}
}
All children views of MyViewContainer will be shown in grey. :-)
Sam Lu's answer is a good start, but I had performance problems and decided to switch to hardware layers. With hardware layers, you can do it like this:
private final Paint grayscalePaint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
grayscalePaint.setColorFilter(new ColorMatrixColorFilter(cm));
public void setGrayedOut(boolean grayedOut) {
if (grayedOut) {
setLayerType(View.LAYER_TYPE_HARDWARE, grayscalePaint);
} else {
setLayerType(View.LAYER_TYPE_NONE, null);
}
}
Be careful not to do the layers in dispatchDraw() itself as that will crash the app.
It depends entirely on the method you are using to "gray out" items. If you are doing so by calling setEnabled(false) on the parent ViewGroup, by default state flags (like disabled) do not trickle down to the child views. However, there are two simple ways you can customize this:
One option is to add the attribute android:duplicateParentState="true" to each child view in your XML. This will tell the children to get their state flags from the parent. This will mirror ALL flags however, including pressed, checked, etc...not just enabled.
Another option is to create a custom subclass of your ViewGroup and override setEnabled() to call all the child views as well, i.e.
#Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
for(int i=0; i < getChildCount(); i++) {
getChildAt(i).setEnabled(enabled);
}
}
What I like to do is create a view which overlaps the view you are trying to tint and set its background to a transparent color. Then you can turn the tint on and off by setting that views visibility
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewYouWantToTint
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<View
android:id="#+id/disabled_tint_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/darkTint"
android:visibility="invisible"/>
</FrameLayout>
Then in your controller:
m_DisabledBlackTintOverlay = (View) view.findViewById(R.id.login_disabled_black_tint_overlay);
m_DisabledBlackTintOverlay.setVisibility(View.VISIBLE);
If all you need to do is fade out or lighten the View colors the solution can be
View.setAlpha(#FloatRange(from=0.0, to=1.0) float alpha)
Which changes the transparency of the entire view

Drawing line under view in android

I am using the onDispatchDraw(Canvas canvas) method to draw lines in my view. When I call canvas.drawLine() it always draws the line on top of all my views. Is there any way to draw the line under a button but on top of another view in my layout using canvas.drawLine()?
I have tried the following but it still draws the line over the button.
Button b;
RelativeLayout r;
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
Paint p = new Paint();
p.setColor(Color.Black);
canvas.drawLine(0,0,100,100,p);
r.removeView(b);
r.addView(b);
}
You're trying to reinvent the wheel. Z-ordering is already implemented in the window management subsystem and you can use it.
Create a custom view you want to draw on.
Make it non-clickable using android:clickable="false" or setClickable(false).
Make its background transparent and implement dispatchDraw().
Put all the views you don't want to draw on above this view in the view hierarchy.
Call super.dispatchDraw() after drawing the line. The dispatchDraw is called by viewgroup for drawing its children, so in your case, calling super.dispatchDraw() will draw the button first then you are drawing the line over it. Do dispatchDraw this way :
Updated code
class myListViewWithLine extends ListView {
....
#Override
protected void dispatchDraw(Canvas canvas) {
Paint p = new Paint();
p.setColor(Color.Black);
canvas.drawLine(0,0,100,100,p);
super.dispatchDraw(canvas);
}
....
}
Another method will be to just add a view with 1 dip as height and background color whatever you like under the button. It should look like like a line.
View v = new View(this);
ViewGroup.LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT,1);
v.setLayoutParams(lp);
v.setBackgroundColor(Color.WHITE);
addView(v,INDEX NUMBER AFTER THE BUTTON);

Categories

Resources