I've searched for this question (the title) and I've got this:
A Rect created in a view class and passed into a fragment, but unfortunately it didn't work, I don't see the rectangle in fragment 1 when i run it.
what am i doing wrong, and Thank You in advance
public class Rectangle extends View {
public Rectangle(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas ) {
Rect rectangle = new Rect(200, 200, 200, 200);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
canvas.drawRect(rectangle, paint);
super.onDraw(canvas);
}
}
public class FragmentOne extends Fragment {
RelativeLayout relativeLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View myInflatedView= inflater.inflate(R.layout.fragment_one_layout,container,false);
relativeLayout = (RelativeLayout) myInflatedView.findViewById(R.id.Frag1);
relativeLayout.addView(new Rectangle(getActivity()));
return myInflatedView;
}
}
XML for fragment 1:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="#+id/Frag1"
android:layout_height="match_parent"
android:background="#000">
<com.redot.puzzle1.Rectangle
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
You problem is Rect rectangle = new Rect(200, 200, 200, 200);
The left-top coordinate is the same as the right-bottom coordinate .So it will not display in the layout.
Just change it in your code and try it .
Try this in your code .
public class Rectangle extends View {
public Rectangle(Context context) {
super(context);
}
public Rectangle(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public Rectangle(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
canvas.drawRect(400,200,800,600,paint);
}
}
Then
<com.redot.puzzle1.Rectangle
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Related
I want to have a simple animation on my custom view.
I used the objectanimator but the custom view did not move.
When I try this with another object (like a textview) it works.
Below is my code. z1 is the custom view that I'd like to move.
public class FinalActivity extends Activity {
MyViewX z1;
TextView t1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_final);
z1 = (MyViewX) findViewById(R.id.xview);
t1 = (TextView) findViewById(R.id.textView1);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if(hasFocus){
ObjectAnimator animation = ObjectAnimator.ofFloat(z1, "translationX", 100f);
animation.setDuration(5000);
animation.start();
}
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5sp"
tools:context=".FrmActivity" >
<com.test.game.myviewx
android:id="#+id/xview"
android:layout_width="200dp"
android:layout_height="200dp"
/>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="72dp"
android:layout_marginTop="173dp"
android:text="TextView" />
</RelativeLayout>
public class MyViewX extends View
{
public MyViewX(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyViewX(Context context, AttributeSet attributeset) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.base1);
int x=80;
int y=80;
int radius=40;
Paint paint=new Paint();
// Use Color.parseColor to define HTML colors
paint.setColor(Color.parseColor("#CD5C5C"));
canvas.drawCircle(x,x, radius, paint);
canvas.drawBitmap(bitmap, 0, 0, paint);
}
}
the code does not crash and seems to run but the circle and the bitmap in the custom view does not move.
what am I missing ?
I see one issue when you create constructor of your myviewx
please edit it
public class myviewx extends View {
public myviewx(Context context) {
super(context);
}
public myviewx(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public myviewx(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.base1);
int x = 80;
int y = 80;
int radius = 40;
Paint paint = new Paint();
// Use Color.parseColor to define HTML colors
paint.setColor(Color.parseColor("#CD5C5C"));
canvas.drawCircle(x, x, radius, paint);
canvas.drawBitmap(bitmap, 0, 0, paint);
}
}
I'm trying to create a fragment in activity which houses a custom image view and the sequence of view should be button, fragment, progress bar but right now I get the progress bar right after the button and nothing where fragment should be.I have posted the layout for the activity,fragment and the java code for fragment and customView. If i set the view with CustomView in onCreate method of activity using setContent() method, I just get the imageview, so the custom imageview works.Please help.
public class IFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.article_view, container, false);
}
}
CustomView.java
public class CustomView extends ImageView
{
private Canvas pcanvas;
private Bitmap bitmap;
Paint mPaint;
private int x = 0;
private int y = 0;
private static final String TAG="adsa";
private int r=0;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
Bitmap bmrot=BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
Paint alphaPaint = new Paint();
alphaPaint.setAlpha(128);
pcanvas = new Canvas();
Log.e(TAG,"The bitmap width is "+bmrot.getWidth() +" and the height is "+bmrot.getHeight());
bitmap = bmrot.createBitmap(bmrot.getWidth(), bmrot.getHeight(), Bitmap.Config.ARGB_8888);
setBackgroundColor(Color.parseColor("#4d4d4d"));
pcanvas.setBitmap(bitmap);
pcanvas.drawBitmap(bmrot, 0, 0, alphaPaint);
}
#Override
protected void onDraw(Canvas canvas) {
pcanvas.drawCircle(x, y, r, mPaint);
canvas.drawBitmap(bitmap, 0, 0, null);
super.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
r = blurSeek.getProgress();
invalidate();
return true;
}
}
article_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.example.android.proj.CustomView
android:id="#+id/signature_canvas"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Activity xml file
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/dsa"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.imagegallery.UploadImageActivity"
android:orientation="vertical">
<LinearLayout
android:id="#+id/thedd"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:text="Upload"
android:id="#+id/Btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
<fragment android:name="com.example.android.imagegallery.ImageFragment"
android:id="#+id/article_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Showing in Logcat (Log Level - ERROR) -
03-07 15:57:32.597 5996-5996/com.example.android.imagegallery E/SELinux: [DEBUG] seapp_context_lookup: seinfoCategory = default
03-07 15:57:32.597 5996-5996/com.example.android.imagegallery E/dalvikvm: >>>>> Normal User
03-07 15:57:32.597 5996-5996/com.example.android.imagegallery E/dalvikvm: >>>>> com.example.android.imagegallery [ userId:0 | appId:10035 ]
03-07 15:57:32.607 5996-5996/com.example.android.imagegallery E/SELinux: [DEBUG] seapp_context_lookup: seinfoCategory = default
03-07 15:57:33.407 5996-5996/com.example.android.imagegallery E/adsa: The bitmap width is 540 and the height is 374
You should add default constructors for Custom ImageView.
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
Bitmap bmrot=BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
Paint alphaPaint = new Paint();
alphaPaint.setAlpha(128);
pcanvas = new Canvas();
Log.e(TAG,"The bitmap width is "+bmrot.getWidth() +" and the height is "+bmrot.getHeight());
bitmap = bmrot.createBitmap(bmrot.getWidth(), bmrot.getHeight(), Bitmap.Config.ARGB_8888);
setBackgroundColor(Color.parseColor("#4d4d4d"));
pcanvas.setBitmap(bitmap);
pcanvas.drawBitmap(bmrot, 0, 0, alphaPaint);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
Hope this will help you.
How can i make a layout look like following snap in the case i don't want to use background image.
Create a nine patch image of a single image. Following link is helpful to you for generate nine patch image.
https://romannurik.github.io/AndroidAssetStudio/nine-patches.html
You can create an ImageView like that triangle and put it in the place you need.
Have a look how you can create triangle using xml: Android triangle (arrow) defined as an XML shape
Or even you can create a TextView:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="▼"/>
and put it in the place.
Unicode for the triangle: link
Use below code in Relative Layout. Hope it helps you.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableRight="#drawable/triangleImage"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"/>
You can also draw custom view:
public class MyBackground extends View{
private Path path = new Path();
private Paint paint = new Paint();
public MyBackground(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyBackground(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
}
public MyBackground(Context context) {
this(context, null);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.GRAY);
int triangleSide = getWidth() / 10; // triangle is 1/10-th of side
int offsetFromRightSide = triangleSide;
int startX = getWidth() - triangleSide - offsetFromRightSide;
path.reset();
path.moveTo(startX, 0);
path.lineTo(startX + triangleSide/2, triangleSide/2);
path.lineTo(startX + triangleSide, 0);
canvas.drawPath(path, paint);
}
}
and use it like this
<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:background="#drawable/background"
tools:context=".MainActivity">
<your.package.name.MyBackground
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Or there is one more "code way". Create custom background Drawable
public class Background extends Drawable {
private Path path = new Path();
private Paint paint = new Paint();
public Background(){
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
}
#Override
public void draw(Canvas canvas) {
int triangleSide = getBounds().width() / 10; // triangle is 1/10-th of side
int offsetFromRightSide = triangleSide;
int startX = getBounds().width() - triangleSide - offsetFromRightSide;
path.reset();
path.moveTo(startX, 0);
path.lineTo(startX + triangleSide/2, triangleSide/2);
path.lineTo(startX + triangleSide, 0);
canvas.drawColor(Color.GRAY);
canvas.drawPath(path, paint);
}
#Override public void setAlpha(int alpha) {}
#Override public void setColorFilter(ColorFilter cf) {}
#Override public int getOpacity() {return 0;}
}
And use it like this:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.root);
layout.setBackgroundDrawable(new Background());
its my first time to ask a question here. I have this problem with my android app.
I would like to create different draw methods inside my custom view class. There are three buttons corresponding to 3 different shapes. When a button is pressed it will draw its shape. But the app crashes when I try to call the custom draw from the MainActivity for me to test it.
MainActivity
import com.example.shapes.view.ShapesView;
public class MainActivity extends Activity {
ShapesView shapesview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
shapesview = (ShapesView) findViewById(R.id.ShapesViewID);
shapesview.DrawRectangle();
}
ShapesView
public class ShapesView extends View{
Canvas canvas;
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
this.canvas = canvas;
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
My XML layout file
<com.example.shapes.view.ShapesView
android:id="#+id/ShapesViewID"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />`
Please do help! Thank you very much!
If I understand your question you need a custom view (a button) which will draw itself differently based on some event. If that is the case then you need to respect the android's guidelines about the view drawing take a look here.
Now one possible solution for your case is to set some kind of flag about the state of your view and then use that flag when you are ready to draw. For example you can do this:
public class ShapesView extends View{
public int state = 0;
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
if (state == 1) {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
and then whenever you need to draw your view from an activity you can use the following:
myview.state = 1;
myview.invalidate();
In your code what you are doing is that you call a views function during the onCreate of your activity which in turn tries to use a null canvas because the onDraw method of your view has not be called during that time. Furthermore as others have pointed out you must not use a canvas object outside the onDraw method.
Hope this helps...
I changed your code with following.
public class ShapesView extends View {
Paint mypaint;
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
mypaint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
When you want to draw, call shapesview.invalidate();
Look at method's name its onDraw() and not getCanvas(). The documentation also doesn't makes any claims about the Canvas provided.
After onDraw() is done, that canvas may be disposed, its bitmap/buffer may be re-cycled, who knows.
So, it is not safe to use the Canvas outside of this method. Draw what you want, but only inside onDraw() method.
If you want to trigger the View to re-draw, at some other time, call invalidate().
Example:
View class to render any shape:
public class ShapeView extends View {
private Paint mPaint;
private ShapeRenderer mRenderer;
public ShapeView(Context context) {
super(context);
init();
}
public ShapeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ShapeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
mPaint = new Paint();
}
public void setPaintColor(int color){
mPaint.setColor(color);
}
public void setPaintStrokeWidth(float width){
mPaint.setStrokeWidth(width);
}
public void setRenderer(ShapeRenderer renderer) {
mRenderer = renderer;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(mRenderer != null){
mRenderer.drawShape(canvas,mPaint);
}
}
public static interface ShapeRenderer{
public void drawShape(Canvas canvas, Paint paint);
}
}
A Class that draws a rectangle:
public class RectRenderer implements ShapeView.ShapeRenderer {
#Override
public void drawShape(Canvas canvas, Paint paint) {
canvas.drawRect(0,0,100,100,paint);
}
}
Draw a shape at runtime:
myShapeView.setPaintColor(Color.GREEN);
myShapeView.setPaintStroke(5f);
myShapeView.setRenderer(new RectRenderer());
myShapeView.invalidate();
I think you must redesign your component, so it can draw itself in onDraw method. If you need some class that must contain Canvas, you can try to do something like this.
class Drawer {
private Canvas canvas;
public Drawer(Canvas canvas) {
this.canvas = canvas;
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
On yours custom view you can do something like this.
public class ShapesView extends View{
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Drawer drawer = new Drawer(canvas);
drawer.DrawRectangle();
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
I am trying to make a simple custom view which is not working. I refereed the custom view class from layout resource file. But its not working. Can anybody tell me where the problem is.
public class WriteOnScreenActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
public class CustomView extends View {
private Paint paint;
public TouchEventView(Context context) {
super(context);
paint = new Paint();
paint.setColor(Color.RED);
paint.setTextSize(25);
paint.setAntiAlias(true);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText("Hello World", 5, 30, paint);
}
}
<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" >
<com.example.touch.CustomView
android:id="#+id/TouchEventView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
Move the definition of your class TouchEventView into a new file.
And here's the fix.
public class TouchEventView extends View {
private Paint paint;
public TouchEventView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup(context, attrs, defStyle);
}
public TouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
setup(context, attrs, 0);
}
public TouchEventView(Context context) {
super(context);
setup(context, null, 0);
}
private void setup(Context context, AttributeSet attrs, int defStyle)
{
paint = new Paint();
paint.setColor(Color.RED);
paint.setTextSize(25);
paint.setAntiAlias(true);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText("Hello World", 5, 30, paint);
}
}