I try to make drawing page with canvas and add floating button in corner for some actions. But it is not appearing.
This is my classes
DrawView.java
public class DrawView extends View implements View.OnTouchListener {
private List<Point> points = new ArrayList<>();
private Paint paint = new Paint();
public DrawView(Context c) {
super(c);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
for (Point point : points) {
canvas.drawCircle(point.x, point.y, 30, paint);
}
}
public boolean onTouch(View view, MotionEvent event) {
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
return true;
}}
And Main activity
public class DrawingPage extends AppCompatActivity {
private DrawView drawView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawing_page);
drawView = new DrawView(getApplicationContext());
drawView.setBackgroundColor(Color.WHITE);
setContentView(drawView);
drawView.requestFocus();
}}
XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="reminder.com.picsartdrawing.DrawingPage">
<android.support.design.widget.FloatingActionButton
android:id="#+id/myFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"
app:elevation="4dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
But floating button is not appearing, any solutions?
Screenshot
EDIT!!!
in Activity's onCreate method I have changed this, and now I have drawing canvas page with button.
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout);
drawView = new DrawView(getApplicationContext());
drawView.setBackgroundColor(Color.WHITE);
drawView.requestFocus();
assert layout != null;
layout.addView(drawView);
In onCreate() you replace 2 times with setContentView() the "main" view, so try with only this:
setContentView(R.layout.activity_drawing_page);
You need to add this in the onCreate method of your activity class:
FloatingActionButton fab = (FloatingActionButton) findViewById (R.id.fab);
fab.setOnClickListener (new View.OnClickListener () {
#Override
public void onClick (View view) {
Snackbar.make (view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction ("Action", null).show ();
}
});
Related
I have a custom view and want to display it, however if I call the method from the custom view (setOnClickListener,...) the application will automatically exit, I don't know why and hope everyone answers.
public class MotionEventActivity extends AppCompatActivity{
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//MyView myView = new MyView(this);
setContentView(R.layout.motion_view);
MyView myView = findViewById(R.id.main);
myView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
}
And here is the code of the custom view:
public class MyView extends View {
public Paint paint = null;
public int radius = 82;
public List<CoordinateButton> arrButton = new ArrayList<CoordinateButton>();
MyView(Context context){
this(context, null);
}
public MyView(Context context, AttributeSet attributeSet) {
super(context);
arrButton.add(new CoordinateButton("S",(float)46.0 , (float) 37.0, 1, "#F08080", "#DC143C", "#F08080"));
arrButton.add(new CoordinateButton("H",(float)1866.0 , (float) 699.0, 4, "#F0E68C", "#FFFF00", "#F0E68C"));
paint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(CoordinateButton button : arrButton){
paint.setColor(Color.parseColor(button.getColorButton()));
canvas.drawCircle(button.getXButton() + radius, button.getYButton() + radius, radius, paint);
paint.setColor(Color.BLACK);
paint.setTextSize(45);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(button.getTextButton(),button.getXButton() + radius, button.getYButton() + radius +15, paint);
}
}
}
And here is the code of the xml file:
<?xml version="1.0" encoding="utf-8"?>
<com.example.motionevent.MyView 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:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MotionEventActivity">
</com.example.motionevent.MyView>
I have an content_main.xml:
<LinearLayout
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:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/activity_main">
<com.example.CustomView
android:id="#+id/customView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout >
In MainActivity.java, in onCreate I call the CustomView:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
customView = new CustomView(this, attributeSet);
customView.init();
}
And in CustomView, I have an onDraw:
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLUE);
drawValidMoves(canvas, squareSize);
}
in MainActivity, the onTouch
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
int x = (int)event.getX();
int y = (int)event.getY();
String text = customView.isTouched(x, y, customView.getSquareSize());
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
return super.onTouchEvent(event);
}
is calling an method from CustomView.java - isTouched that change some things in a matrix of drawed elements and after that, I'm making some:
setWillNotDraw(false);
invalidate();
but my game doesn't reach onDraw again...
If I'm calling in onCreate directly the CustomView, the invalidate works:
customView = new CustomView(this, attributeSet);
customView.init();
setContentView(customView);
but I don't have the toolbar anymore, and I need that
LATER EDIT:
content_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:id="#+id/linearLayoutId"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/activity_main">
<com.example.clotz.CustomView
android:id="#+id/customView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout >
MainActivity.java - onCreate - I moved the data from init method into constructor and get rid of init.
public class MainActivity extends AppCompatActivity {
CustomView customView;
#SuppressLint("WrongViewCast")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
customView = findViewById(R.id.customView);
}
But customView is null now in onTouchEvent:
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
int x = (int)event.getX();
int y = (int)event.getY();
String text = customView.isTouched(x, y, customView.getSquareSize());
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
return super.onTouchEvent(event);
}
#Mike M helped me with this and I put in content_main.xml the id of the linearLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:id="#+id/linearLayoutId"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/activity_main">
<com.example.clotz.CustomView
android:id="#+id/customView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout >
in MainActivity.java - onCreate (I moved the data from init method into constructor and get rid of init) and I created the customview with findViewById(R.id.customView);
public class MainActivity extends AppCompatActivity {
CustomView customView;
#SuppressLint("WrongViewCast")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
customView = findViewById(R.id.customView);
}
And the problem was in CustomView.java, I forgot to pass attributeSet to the superclass:
public CustomView(Context context, AttributeSet attributeSet) {
super(context);
initializeMovedMatrix();
setInitialPositionForPieces();
// create the Paint to set its color
paint = new Paint();
piecesMoves = new PiecesMoves(this);
}
and putting it, combined with customView = findViewById(R.id.customView);
super(context, attributeSet);
Solved the problem.
Thanks again MikeM!
you cannot delete super.onDraw(canvas) in onDraw method.
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLUE);
drawValidMoves(canvas, squareSize);
}
This is my MainActivity:
public class MainActivity extends Activity {
PieMenu pieMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pieMenu = new PieMenu(getApplicationContext());
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
{
pieMenu.addPieMenu(x,y);
}
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
}
return false;
}
}
PieMenu:
public class PieMenu extends FrameLayout{
private Context _context;
public PieMenu(Context context) {
super(context);
_context = context;
// TODO Auto-generated constructor stub
}
public void addPieMenu(int x, int y){
Toast.makeText(_context, "text",Toast.LENGTH_LONG).show();
PieItem pieView = new PieItem(_context,x,y,2);
//FrameLayout.LayoutParams lyp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
//pieView.setLayoutParams(lyp);
addView(pieView);
invalidate();
}
}
PieItem.java:
public class PieItem extends View{
private final float x;
private final float y;
private final int r;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public PieItem(Context context, float x, float y, int r) {
super(context);
mPaint.setColor(0xFFFF0000);
this.x = x;
this.y = y;
this.r = r;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, r, mPaint);
}
}
MainActivity.xml:
<FrameLayout 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"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/hello_world" />
</FrameLayout>
Everytime I touch the scree, the toast is being called but the circle isn't being instantiated. Where am I going wrong?
easiest way to fix this, add view in onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pieMenu = new PieMenu(getApplicationContext());
FrameLayout fl = (FrameLayout)findViewById(R.id.layout);
fl.addView(pieMenu);
}
and add id to your main activity xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
You aren't adding pieMenu to any of the views in your layout (R.layout.activity_main)
What does your activity_main.xml look like?
You didn't add created PieMenu to activity layout. You need to call something like this in onCreate method:
view.addView(pieMenu);
Or add your PieMenu to you activity_main layout.
If I want to add a button in this class so that I can call the onclicklistener, how should I do it?
public class GameView extends View {
Path circle;
Paint cPaint;
Paint tPaint;
String z;
int i = 65, strt, arc, leftx, topy, rightx, bottomy, maxx, maxy;
boolean flag1, flag2, flag3;
double n1, n2;
int n, n3 = 180,n4,n5 = 90;
float f1 = 180, f2 = 90;
Button b1;
Random r = new Random();
RectF oval;
public GameView(Context context) {
super(context);
leftx = 0;
topy = 60;
rightx = 150;
bottomy = 120;
z = String.valueOf(Character.toChars(i));
cPaint = new Paint();
cPaint.setColor(Color.RED);
strt = 45;
arc = 315;
n1 = Math.random() * 600;
Log.d("random", z);
if (flag2 == false)
new DrawThread(this);
// cPaint.setStrokeWidth(2);
tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
tPaint.setStyle(Paint.Style.FILL_AND_STROKE);
tPaint.setColor(Color.BLACK);
float scale = getResources().getDisplayMetrics().scaledDensity;
tPaint.setTextSize(20 * scale);
}
public void onSizeChanged(int w,int h,int oldh,int oldw) {
maxx = oldw;
maxy = oldh;
}
//#Override
protected void onDraw(Canvas canvas) {
// Drawing commands go here
oval = new RectF(leftx,topy,rightx,bottomy);
canvas.drawArc(oval, strt, arc, true, cPaint);
while (i < 90) {
canvas.drawText(String.valueOf(Character.toChars(i)),f1,f2, tPaint);
break;
}
}
}
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
add the above below setContentView
setContentView(R.layout.activity_new_game);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
You need to set the layout using setContentView and then initialize views.
Note you can findViewById of the current view hierarchy set to the activity
Edit:
Example: This is an example. I don't see why it won't work if you do similar as below.
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".NewGame"
android:id="#+id/relative_layout"
>
<Button
android:id="#+id/prev_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/next_button"
android:layout_alignBottom="#+id/next_button"
android:layout_centerHorizontal="true"
android:text="stop_label" />
<Button
android:id="#+id/next_button"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginRight="20dp"
android:layout_toLeftOf="#+id/prev_button"
android:text="start_label" />
<RelativeLayout
android:layout_width="wrap_content"
android:id="#+id/rl"
android:layout_below="#+id/prev_button"
android:layout_height="wrap_content"
>
</RelativeLayout>
</RelativeLayout>
Activity
public class MainActivity extends Activity {
private Button btn1;
private EditText edt1, edt2, edt3, edt4 ,edt5, edt6;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView mv = new MyView(this);
setContentView(R.layout.activity_main);
RelativeLayout layout= (RelativeLayout) findViewById(R.id.rl);
layout.addView(mv);
}
class MyView extends View
{
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawColor(Color.RED);
}
}
}
snapshot
You need to inflate your view before trying to find your relative layout. Try :
RelativeLayout layout;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
gameview=new GameView(this);
setContentView(R.layout.activity_new_game);
layout = (RelativeLayout) findViewById(R.id.relative_layout);
//LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//view = mInflater.inflate(R.layout.activity_new_game, gameview, true);
layout.addView(gameview);
}
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
you can't call findViewById before setContentView. Move
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
after setContentView(R.layout.activity_new_game);
you didn't initialize layout in your code so First initialize layout after setContentView then add view to your layout
RelativeLayout layout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_game);
//Initialize game view
GameView gameview=new GameView(this);
//initialize layout
layout = (RelativeLayout) findViewById(R.id.relative_layout);
//adding game view to layout
layout.addView(gameview);
}
Edit:
initializing like this before setContentView
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relative_layout);
is wrong approach you must initialize views only after setContentView like the above code
I need to show a layout from xml file and draw some vector based image on top of that. If code below is executed then everything is shown but the layout. Why? What I'm doing wrong?
public class About extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.about);
setContentView(new GraphicsView(this));
}
public class GraphicsView extends View
{
public GraphicsView(Context context)
{
super(context);
}
#Override
protected void onDraw(Canvas canvas)
{
Context context;
context=getContext();
View aview;
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
aview = inflater.inflate(R.layout.about, null);
aview.draw(canvas);
Path circle = new Path();
Paint cPaint = new Paint();
cPaint.setColor(Color.LTGRAY);
circle.addCircle(150, 150, 100, Direction.CW);
canvas.drawPath(circle, cPaint);
cPaint.setColor(Color.RED);
canvas.drawTextOnPath("Some stupid text", circle, 0, 20, cPaint);
}
}
}
After inflating the View you need to measure it and lay it out to give it a size so it can be properly drawn. You should call aview.measure() and aview.layout() before calling aview.draw().
Note that you should NEVER inflate views from onDraw(). It is very expensive and wasteful. Similarly, you should NEVER create paints or paths inside onDraw().
There is an another answer from another forum:
FrameLayout:
public class About extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.about);
GraphicsView drawing = new GraphicsView(this);
FrameLayout container = (FrameLayout) findViewById(R.id.container);
container.addView(drawing);
}
public class GraphicsView extends View
{
public GraphicsView(Context context)
{
super(context);
}
#Override
protected void onDraw(Canvas canvas)
{
Path circle = new Path();
Paint cPaint = new Paint();
cPaint.setColor(Color.LTGRAY);
circle.addCircle(150, 150, 100, Direction.CW);
canvas.drawPath(circle, cPaint);
cPaint.setColor(Color.RED);
canvas.drawTextOnPath("Some stupid text", circle, 0, 20, cPaint);
}
}
}
And then here comes XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:id="#+id/container">
<TextView
android:id="#+id/about_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/about_text" />
</FrameLayout>