I have the next issue:
I have an Activity, where I want to try to add Buttons, this is my onCreate method
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
DrawView drawView = new DrawView(this);
setContentView(drawView);
context = this;
drawView.requestFocus();
}
This is the DrawView class
public class DrawView extends View implements OnTouchListener {
public static final String TAG = "DrawView";
private List<List<Point>> listaPuntos = null;
private List<Paint> listaPaints = null;
private int paintActual = 0;
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
listaPaints = new ArrayList<Paint>();
listaPuntos = new ArrayList<List<Point>>();
this.setOnTouchListener(this);
this.setBackgroundColor(Color.WHITE);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.BLACK);
listaPaints.add(paint);
}
#Override
public void onDraw(Canvas canvas) {
for(int i=0; i<listaPaints.size(); i++){
Paint paint = listaPaints.get(i);
Point punto = null;
if(listaPuntos.size()!=0 && listaPuntos.size()>i){
List<Point> puntos = listaPuntos.get(i);
for (Point point : puntos) {
if(punto == null){
punto = point;
}
canvas.drawLine(point.x, point.y, punto.x, punto.y, paint);
punto = point;
}
}
}
}
#Override
public boolean onTouch(View view, MotionEvent event) {
if(event.getAction() != MotionEvent.ACTION_UP){
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
point.paintPunto = paintActual;
if(listaPuntos.size()<=paintActual){
listaPuntos.add(new ArrayList<Point>());
}
listaPuntos.get(paintActual).add(point);
invalidate();
return true;
}else{
paintActual++;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.BLACK);
listaPaints.add(paint);
}
return super.onTouchEvent(event);
}
Anybody knows how can I add Buttons to this Activity?? I would like to add a Button to be able to make an action and I completely can´t!!
Thanks a lot for your help.
Only ViewGroup(LinearLayout,RelativeLayout) can have children.What you are doing is that you are making the DrawView as the content view of your activity which is not a container(ViewGroup) hence, you cannot add any other view(child) to it.
The solution to you problem is:
Create a xml layout file with a ViewGroup as the parent(LinearLayout, RelativeLayout,etc) containing other views or empty.
Create an instance of the DrawView.
Add this instance to the ViewGroup
Similarly create instance of other views and add them to the parent if you want to add views dynamically.
here is sample code for this:
Suppose LinearLayout with id as parent is the parent of the xml layout then:
LinearLayout parent = (LinearLayout)findViewById(R.id.parent);
//creating instance of custom view
DrawView drawView = new DrawView(this);
//adding custom view as the first child
parent.addView(drawView,0);
//adding button dynamically
Button btn = new Button(this);
btn.setText("Ok");
parent.addView(btn,1);
you should make a xml file and must use it like setContentView (R.layout.filename) and because you are trying to merge your other page contents to this xml you should include layout by now you can use this page id and can implement your any functions. So better would be if you add button in other xml and then include it in your new desired xml. this is a proper way... hope you understood what i mean. otherwise you can search in developer.android.com
You should create an XML layout file, that you will associate with your activity with the setContentView() call in onCreate().
Your layout will contain your own view, buttons, and whatever you like.
Related
I will be very grateful is somebody can help.
I have created a grid of views with a TableLayout in my xml file.
In the corresponding java file, I retrieve the id of all views in an array view.
I have another class which receive in its constructor a reference to an above created view, in order to draw on its canvas.
public class Mosaique extends Activity {
Box [][]box = new Box[NL][NC];
View [][] boxMosaique = new View[NL][NC];
//...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mosaique);
boxMosaique[0][0] = findViewById(R.id.b_00);
boxMosaique[0][1] = findViewById(R.id.b_01);
boxMosaique[0][2] = findViewById(R.id.b_02);
//…
for (int lig=0;lig<NL;lig++)
for(int col=0;col<NC;col++)
box[lig][col] = new Box(boxMosaique[lig][col], bckgrnd_color, lig,col);
}
//...
}
// The constructor of the another class which access the views for drawing
public Box(View aView, int backGroundColor, int lig, int col){
this.aView = aView;
this.lig = lig;
this.col = col;
this.backGroundColor = backGroundColor;
// How to access the canvas of aView for drawing ?
}
I would recommend writing Box class as View.
Box extends View{
float lig;
float col;
Clolr backGroundColor;
...
#Override
protected void onDraw(Canvas canvas) {
//draw here on canvas
...
}
public drawBox(int backGroundColor, int lig, int col){
this.aView = aView;
this.lig = lig;
this.col = col;
this.backGroundColor = backGroundColor;
invalidate()
}
instead of adding constructors, add a method to set box values and call invalidate() once the values are set.
i want to call the start method defined in Gameview class from the NewGame activity.basically i want to add onclicklistener and want to perform task specified inthe start() method whenever the button is clicked
activity:
public class NewGame extends Activity implements OnClickListener {
GameView gameview;
#Override
public void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//gameview=new GameView(this);
setContentView(R.layout.activity_new_game);
View startbutton=findViewById(R.id.start_button);
startbutton.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_button:
gameview.start(this);
}
}
view:
public class GameView extends View {
Path circle;
Paint cPaint;
Paint tPaint;
String z;
GameView a;
int i=65,strt,arc,leftx,topy,rightx,bottomy,maxx,maxy,minx,miny;
boolean flag1,flag2,flag3;
double n1,n2;
int n,n3=180,n4,n5=90;
float f1=180,f2=90;
int width;
int height;
Random r=new Random();
RectF oval;
public GameView(Context context,AttributeSet attrs ) {
super(context,attrs);
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);
this.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// 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 start(Context context)
{
if (flag2==false)
new DrawThread(this);
}
Your gameView object is currently null. If you have it in your XML layout file, you should instantiate it in onCreate with a line like this:
gameView = (GameView) findViewById(R.id.gameView);//where gameView is the id specified in your layout file (R.layout.main, or something)
If it is not in your layout file, you need to instantiate it and add it to your layout:
gameView = new GameView(this);
gameView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
ViewGroup content = (ViewGroup) findViewById(android.R.id.content).getRootView();
content.addView(gameView);
now you will not get null pointer exceptions, and your gameview will fill the screen.
I have a custom view and want to add one more custom view on that custom view. This is my custom view class:
public class CustomCircle extends View{
float radius;
Paint paint = new Paint();
String message = "";
public CustomCircle(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(getWidth()/2, getHeight()/2,radius, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean isClickInCircle = false;
float x = event.getX();
float y = event.getY();
double check = Math.sqrt((x-getWidth()/2)*(x-getWidth()/2) + (y-getHeight()/2)*(y-getHeight()/2));
if (check<=radius) {
isClickInCircle= true;
}
if (isClickInCircle) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(getContext(),message, Toast.LENGTH_LONG).show();
return true;
case MotionEvent.ACTION_UP:
Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
return true;
default:
break;
}
}
return false;
}
and am using another class that extends LinearLayout:
public class B extends LinearLayout {
private Paint paint;
public B(Context context) {
super(context);
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Style.FILL);
}
public void addCircle() {
CustomCircle circleBlue = new CustomCircle(getContext(), null);
circleBlue.paint.setColor(Color.WHITE);
circleBlue.paint.setAntiAlias(true);
circleBlue.radius = 160;
circleBlue.message = "Clicked";
addView(circleBlue);
CustomCircle circleRed = new CustomCircle(getContext(), null);
circleRed.paint.setColor(Color.RED);
circleRed.paint.setAntiAlias(true);
circleRed.radius = 80;
circleRed.message = "Clicked";
addView(circleRed);
}
and I'm calling the B class from the main activity class using :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
B root = new B(this);
root.addCircle();
setContentView(root);
}
The output is showing me only one circle instead of a circle inside another circle. What's wrong with my code?
And the Output is showing me only One circle instead of circle inside
circle.
You picked the wrong layout if you want to overlap children, a RelativeLayout or FrameLayout is the way to go. Also, regarding your code:
public class B extends RelativeLayout {
//...
public void addCircle() {
// the constructor that uses the AttributeSet should be added if you use the
// custom component in the xml layout
CustomCircle circleBlue = new CustomCircle(getContext());
// ...
// add it with LayoutParams
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rlp.addRule(RelativeLayout.CENTER_IN_PARENT);
addView(circleBlue, rlp);
// the same for the other view
}
Also your two circle will have the same dimensions so they will overlap perfectly(and you'll not be able to see them), you would need to give them different dimensions, through the LayoutParams, for example:
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(200, 200);
for the first one and:
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(100, 100);
for the second one.
Is it possible that there are 2 circles in the layout but you can see only one
because it has the same color as the first circle and they are laying on top of each other?
change circleRed.paint.setColor(Color.WHITE);
to circleRed.paint.setColor(Color.BLACK);
and see what it gives
I have a relative layout inside a scrollview, then i created a new view with this code:
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.BLACK);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(5, 5, 140, 140, paint);
}
}
Then i try to use layout.addView(DrawView) to add the new view to the relative layout, so it can be scrollable with the rest of the content, but is doesn't work, nothing shows up..
Am i missing something ?
Edit:
DrawView formas;
GifMovieView gif;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final RelativeLayout layout = new RelativeLayout(this);
final ScrollView scrollView = new ScrollView(this);
//gif = new GifMovieView(this, t_img);
formas = new DrawView(this);
layout.addView(formas);
scrollView.addView(layout);
this.setContentView(scrollView);
inicializar();
load(layout);
}
You will probably want to override onMeasure() in your DrawView. Otherwise your view will have size of 0x0 pixels.
You can start with something as simple as
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(200, 200);
}
just to prove it works, but you will need to do some more meaningful, based on what are contents of your view.
Start from this article to see help on overriding onDraw() and onMeasure()
I have an activity which is dynamically created from the main Activity using setContentView(new SingleTouchEventView(this, null,x) , i have written this code
public class SingleTouchEventView extends View {
private Paint paint = new Paint();
private Path path = new Path();
public SingleTouchEventView(Context context, AttributeSet attrs,int x) {
super(context, attrs);
LinearLayout ll=new LinearLayout(getContext());
ll.setOrientation(LinearLayout.VERTICAL);
Button b=new Button(getContext());
b.setText("Back");
ll.addView(b);
setContentView(ll);
paint.setAntiAlias(true);
}
}
But i am getting an error on the line "setContentView(ll);" saying "The method setContentView(LinearLayout) is undefined for the type SingleTouchEventView "
I have to place a button on this activity so that a person can go back to previous activity.
Don't add a button. Just let the built-in Back button do its thing, or override it if you need custom functionality. For purposes of displaying your View, you probably need to start with a new Activity, Dialog or Fragment, not a view.
try it like this:
public class SingleTouchEventView extends LinearLayout {
private Paint paint = new Paint();
private Path path = new Path();
public SingleTouchEventView(Context context) {
super(context);
this.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams
(MATCH_PARENT, WRAP_CONTENT);
setLayoutParams(parms);
Button b=new Button(getContext());
b.setText("Back"); // better: getContext().getString(R.string.someString);
this.addView(b);
b.setLayoutParams(parms);
paint.setAntiAlias(true);
}
}
and then inside your Activity, set Your Content View like this:
public void onCreate(Bundle icicle){
SingleTouchEventView v = new SingleTouchEventView(this);
setContentView(v);
}
There is no method called setContentView() in the class view.. so you get such error...
in order to remove that error, create the instance of your mainactivity and invoke this method with thatone..
Example if your main activity is HomeActivity then
public class SingleTouchEventView extends View {
private Paint paint = new Paint();
Private HomeActivity custom_view=null;
private Path path = new Path();
public SingleTouchEventView(Context context, AttributeSet attrs,int x)
{
super(context, attrs);
LinearLayout ll=new LinearLayout(getContext());
ll.setOrientation(LinearLayout.VERTICAL);
Button b=new Button(getContext());
b.setText("Back");
ll.addView(b); custom_view.setContentView(ll);
paint.setAntiAlias(true);}}