onClickListener set on Activity - android

I have a class SomeView that extends View and that is displayed in a class Controls that extends linear layout.
The linear layout is instantiated onCreate of an activity.
I would like to call a method in the activity every time I click on this view SomeView.
I have tried to set an onClickListener in the activity like this
public class MainActivity extends AppCompatActivity implements
SomeView.OnClickListener {
private Controls menu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
menu = new Controls(this);
menu.getSomeView().setOnClickListener(this);
setContentView(menu);
}
#Override
public void onClick(View view) {
System.out.println("Hello");
}
}
The controls class looks like this
public class Controls extends LinearLayout {
private SomeView aview;
public Controls(Context context) {
super(context);
this.setOrientation(LinearLayout.HORIZONTAL);
aview = new SomeView(context);
this.addView(aview, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
public SomeView getSomeView() {
return aview;
}
}
and the SomeView class looks like this (it just draws an oval)
public class SomeView extends View {
public SomeView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF aRect = new RectF();
aRect.left = getPaddingLeft();
aRect.top = getPaddingTop();
aRect.right = getWidth() - getPaddingRight();
aRect.bottom = getHeight() - getPaddingBottom();
Paint aPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
aPaint.setColor(Color.GREEN);
canvas.drawOval(aRect, aPaint);
}
}
But I am missing something because clicks are not calling the onClick method.
What else do I need to set up?

it seems like you did only mistake in your MainActivity class, where you forgot to call the super method. Try doing this, hope it will work, since it works from here in my mobile.
Main Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
menu = new Controls(this);
menu.getSomeView().setOnClickListener(this);
setContentView(menu);
}
And in your callback method, instead using System.out.println(), use Log.d() as below:
#Override
public void onClick(View view) {
Log.d(TAG, "Hello");
}
and it is working from here, look at the image below as well.

Related

How to call on activity method from view?

I have done I game in which I want to call on a method I have in a view from another view. I figured I would somehow have to send the "first view" into the "second view" through the my MainActivity in order for the second view to be able to call on the first view methods. However, I couldn't come up with any way of sending in the first view to the second view through my MainAcitivity, so I decided to change tactics. I now tried to have a function in my MainActivity to handle the interection between the views, but once again I was not able to call on the method from the second View.
Therefore my question is how do you send a view into another view through an Activity, or If that's not possible how do you call on an activity method through a view?
Here is the code (I added some comments to better show the problem I'm having):
public class MainActivity extends AppCompatActivity {
private FishView gameView;
private SmallBall smallBall ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout screen = findViewById(R.id.gameScreen);
gameView = new FishView(this);
smallBall = new SmallBall(this);
screen.addView(gameView); // first view
screen.addView(smallBall); //second view
}
//this is the method I want to reach through the View
public void handleAvoidedBall(){
gameView.avoidedBall();
}
}
public class SmallBall extends View {
private final Bitmap sodaCan;
private final static long smallBallPeriod = 60;
private final Handler handler = new Handler();
public SmallBall(Context context) {
super(context);
Paint smallBall = new Paint();
smallBall.setColor(Color.GRAY);
smallBall.setAntiAlias(false);
resetBall();
sodaCan = BitmapFactory.decodeResource(getResources(),R.drawable.sodacan);
Timer movementTimer = new Timer();
movementTimer.scheduleAtFixedRate(smallBallTask, 0, smallBallPeriod);
}
private final TimerTask smallBallTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
invalidate();
if (isBallLanded()){
//Here I want to call on a handleAvoidedBall() in MainActivity
//OR simply have gameView here if possible
// gameView.avoidedBall();
//OR
//SomeMainAcitvityObject.handleAvoidedBall();
}
}
});
}
};
#Override
protected void onDraw(Canvas canvas) {
..... //Do stuff}
}
So as I hopefully have explained somewhat decent now, I'm wondering how to either send gameView into the SmallBall view OR how to call on handleAvoidedBall() in MainActivity from the SmallBall view?
Thank you for your time and hope you have a wonderful day!
Your best option would be to define a listener that you would set on the SmallBallView.
Define the listener:
public interface BallListener {
void onAvoided(SmallBall ball);
}
And then inside your SmallBall class, you would have this method:
public void setListener(BallListener listener){
this.listener = listener;
}
And then call this in your activity, after you've instantiated the SmallBall class:
smallBall.setListener(new SmallBallListener(){
#Override
public void onAvoided(SmallBall ball){
// Do stuff here
}
})
As #LukeWaggoner mentioned, you should consider using listeners instead of making view static in your activity.
You told us, that you'd like to add more than one SmallBall views, so I figure that you don't want to write a listener's code for each of them.
It is easily doable with MainActivity implementing SmallBallListener.
Listener:
public interface SmallBallListener {
void onAvoidedBall();
}
SmallBall class:
public void setListener(SmallBallListener listener){
this.listener = listener;
}
MainActivity:
public class MainActivity extends AppCompatActivity implements SmallBallListener {
private FishView gameView;
private SmallBall smallBall ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout screen = findViewById(R.id.gameScreen);
gameView = new FishView(this);
screen.addView(gameView); // first view
// Add 10 small ball views
for(int i = 0; i < 10; i++) {
SmallBall ball = new SmallBall(this);
ball.setListener(this); // MainActivity is a listener here, so each ball has the same listener code
screen.addView(ball);
}
}
//this is the method I want to reach through the View
public void handleAvoidedBall() {
gameView.avoidedBall();
}
#Override
public void onAvoidedBall() { // this is the SmallBallListener method
this.handleAvoidedBall();
}
}
So whichever SmallBall view call listener.onAvoidedBall(), it will fire onAvoidedBall() method in MainActivity class.
Turns out all I had to do was to set:
private FishView gameView;
to:
public static FishView gameView;
And then simply use "MainActivity.gameView" in the SmallBall view. This gave me no additional warings either, so that was good also.

A custom function structure for my customView.onclick

I have searched but could not find answer of my question.
This is what I have:
private class BoxView extends View {
private String caption;
private OnClickListener bvClickListener = null
public BoxView(Context context) {
super(context);
this.bvClickListener = new this.OnClickListener(){
public void onClick (View v){
/*v.setCaption("X"); view don't have this method */
}}
}
public void setCaption(String s){
this.caption=s;
invalidate();
}
}
This is what I want to have:
private class BoxView extends View {
private String caption;
private OnClickListener bvClickListener = null
public BoxView(Context context) {
super(context);
this.bvClickListener = new this.OnClickListener(){
public void onClick (BoxView bv){
bv.setCaption("X");
}}
}
public void setCaption(String s){
this.caption=s;
invalidate();
}
}
I may need custom methods for my custom views. And I want to be able to pass my custom view instead of view version of it when onclick is triggered so I can access to it directly.
Updated
And I want to have access to real object not a converted one. So I want to avoid this:
public void onClick (View v){
((BoxView)v).setCaption("X");
}
Call setCaption method as in onClick :
public void onClick (View v){
((BoxView)v).setCaption("X");
}
Try this
class Main extents Activity
{
BoxView boxView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// if view is used using layout then
boxView = (BoxView)findViewByID(id);
//else if directly used
boxView = new BoxView(this);
box.setOnClickListener(new onClickListener()
{
#Override
public void onClick(View view) {
boxView.setCaption("X");
boxView.invalidate();
}
});
}
}

A button in a window with graphics

I'd like to know how to create buttons, textViews etc. in an Activity, which doesn't use an xml file as ContentView.
What I mean:
Main Class:
protected void onCreate(Bundle savedInstanceState)
{
//...
puzzleView = new PuzzleView(this);
setContentView(puzzleView);
}
The PuzzleView class:
public class PuzzleView extends View
{
private final Game game;
public PuzzleView(Context context)
{
super(context);
this.game = (Game) context;
setFocusable(true);
setFocusableInTouchMode(true);
}
#Override
protected void onDraw(Canvas canvas)
{
// drawing some things here
}
}
You probably want to set your content view to a class that extends ViewGroup, then add views to that class. Layouts are probably what you're after, in particular. Here are some tutorials:
http://blogspot.arcintechnologies.com/android/generate-android-layout-programmatically/
http://mainerrors.blogspot.ca/2011/02/programmatically-creating-layout-part-1.html

Restarting activity inside onClick method

I have an app which reads .txt file and displays contents in table layout.
here is my MainActivity.java file:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new TableLayout(this,0));
}
}
Inside TableLayout class when adding first row (headers), i also add on click listeners.
Here is the code that gets executed when click happens:
public class MyOnClickListener extends MainActivity implements OnClickListener {
int rowNumber;
public MyOnClickListener(int rowNumber) {
this.rowNumber = rowNumber;
}
#Override
public void onClick(View v) {
setContentView(new TableLayout(context,rowNumber));
}
};
context is saved from when activity is first started, but i get nullpointexception error with this as an argument.
What i would like to do when header is clicked is to recreate table with header number argument.
So my question is what should i do to restart table creation within onClick method?
Edit: this is how context is saved
Context context;
public TableLayout(Context context, int rowNr) {
super(context);
this.context = context;
I would probably do something like this
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new TableLayout(this, getRowNumber()));
}
protected int getRowNumber(){
return 0;
}
}
and then you do something like
public class MyOnClickListener extends MainActivity implements OnClickListener {
// here you initialize rowNumber
static int rowNumber = 0;
#Override
protected void getRowNumber(){
return rowNumber;
}
#Override
public void onClick(View v) {
// here you set your rowNumber
rowNumber = some_value;
recreate();
}
};
P.S: I haven't compiled this but you can get the idea

how to Apply the Click event on extends view class in android?

Hi i want create simple apps.i use the one customclass which name like a Drawcanvas which purpose to draw runtime canvas.so i use the ontouchListener and OnClicklistener onthis. but those event can`t working.my code is below.
this the class where i use the Custom class name like DrawCanvas
public class CanvasExample extends Activity
{
/** Called when the activity is first created. */
RelativeLayout relMainOperationLayout;
RelativeLayout relTabHeader;
RelativeLayout relMidalLayout;
RelativeLayout relBelowLayout;
Context myContext;
DrawCanvas drawCanvas;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
myContext=CanvasExample.this;
LayoutInflater layoutInflater=(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int layoutId = myContext.getResources().getIdentifier("main","layout",getPackageName());
relMainOperationLayout = (RelativeLayout) layoutInflater.inflate(layoutId,null);
relTabHeader=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relHeadLayout);
relMidalLayout=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relmidalLayout);
relBelowLayout=(RelativeLayout) relMainOperationLayout.findViewById(R.id.relBelowLayout);
drawCanvas=new DrawCanvas(CanvasExample.this,myContext);
drawCanvas.setBackgroundColor(Color.YELLOW);
RelativeLayout.LayoutParams drawParams=new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,400);
drawParams.addRule(RelativeLayout.BELOW, relTabHeader.getId());
//relMidalLayout.addView(drawCanvas,drawParams);
relMainOperationLayout.addView(drawCanvas,drawParams);
setContentView(relMainOperationLayout);
}
And This is my CustomClass code which extend View. Name DrawCanvas
public class DrawCanvas extends View implements View.OnTouchListener,View.OnClickListener
{
Context drawContext;
Activity drawActivity;
public DrawCanvas(Activity activity,Context context)
{
super(activity);
this.drawActivity=activity;
this.drawContext=context;
}
#Override
public void onClick(View v)
{
System.err.println("Click Here");
Toast.makeText(drawContext, "Click ", 1000).show();
}
#Override
public boolean onTouch(View v, MotionEvent event)
{
System.err.println("Touch Here");
return true;
}
}
i am new in canvas.
You have to use setOnTouchListener and setOnClickListener (though I don't think click events will help you) to register the click and touch events for your View.
public DrawCanvas(Activity activity,Context context) {
super(activity);
this.drawActivity=activity;
this.drawContext=context;
setOnTouchListener(this);
setOnClickListener(this);
}

Categories

Resources