I want to create by code an array of objects that are subclasses of Button.
public class MyButton extends Button {
private Context ctx;
private int status;
public MyButton(Context context) {
super(context);
ctx = context;
status = 0;
}
private click() {
status = 1;
// OTHER CODE THAT NEEDS TO STAY HERE
}
}
In the main activity I do this:
public class myActivity extends Activity {
private MyButton[] myButtons = new MyButton[100];
#Override
public onCreate(Bundle si) {
super.onCreate(si);
createButtons();
}
private void createButtons() {
for (int w=0; w<100; w++) {
myButtons[w] = new MyButton(myActivity.this);
myButtons[w].setOnClickListener(new View.onClickListener() {
public void onClick(View v) {
// ... (A)
}
});
}
}
}
Now I want the click() method inside MyButton to be run each time the button is clicked.
Seems obvious but it is not at my eyes.
If I make the click() method public and run it directly from (A), I get an error because myButtons[w].click() is not static and cannot be run from there.
In the meantime, I an not able to understand where to put the code in the MyButton class to intercept a click and run click() from there. Should I override onClick? Or should I override onClickListener? Or what else should I do?
How can I run click() whenever one of myButtons[] object is clicked?
Thanks for the help.
You can cast View v you got in listener to MyButton and call click on it:
private void createButtons() {
View.OnClickListener listener = new View.onClickListener() {
public void onClick(View v) {
((MyButton) v).click();
}
};
for (int w=0; w<100; w++) {
myButtons[w] = new MyButton(myActivity.this);
myButtons[w].setOnClickListener(listener);
}
}
you can add:
View.onClickListener onclick = new View.onClickListener() {
public void onClick(View v) {
((MyButton)v).click();
//since v should be instance of MyButton
}
};
to your Activity
then use:
myButtons[w].setOnClickListener(onclick);
//one instance of onclick is enough, there is no need to create it for every button
in createButtons()
but ... why, oh why array of buttons we have ListView in android ...
Related
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();
}
});
}
}
I have that code:
public class GeolocationActivity extends ActionBarActivity implements SensorEventListener {
{
//...
private void setUpCompass()
{
isCompass = true;
setContentView(R.layout.subactivity_compass);
//...
}
private void setUpMain()
{
//...
btn2 = (Button)findViewById(R.id.geoloc_compass);
btn2.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// here I want to call method setUpCompass();
}
});
//...
}
}
I want to call setUpCompass() method from onClick() function in setUpMain().
I tried:
Context c = getBaseContext();
((GeolocationActivity)c).setUpCompass();
but I get:
java.lang.ClassCastException: android.app.ContextImpl cannot be cast to com.myname.myapp.GeolocationActivity
What am I doing wrong?
Instead simply use GeolocationActivity.this.
Example:
GeolocationActivity.this.setUpCompass();
I have an ArrayList of Buttons where my OCL needs to know which index I has been pressed.
The plan is something like this:
MyOnClickListener onClickListener = new MyOnClickListener() {
#Override
public void onClick(View v) {
Intent returnIntent = new Intent();
returnIntent.putExtra("deleteAtIndex",idx);
setResult(RESULT_OK, returnIntent);
finish();
}
};
for (int i =0;i<buttonList.size();i++) {
buttonList.get(i).setText("Remove");
buttonList.get(i).setOnClickListener(onClickListener);
}
How does my implementation of the OCL need to look like ?
Currently I have this:
public class MyOnClickListener implements OnClickListener{
int index;
public MyOnClickListener(int index)
{
this.index = index;
}
#Override
public void onClick(View arg0) {
}
}
However, I am unsure of what I need to do within the constructor of my OCL, aswell as the overriden onClick function.
set setOnClickListener to Button as :
buttonList.get(i).setOnClickListener(new MyOnClickListener(i));
EDIT :
I need to finish an activity in myOCL, how would I do that?
for finishing Activity on Button Click from non Activity class you will need to pass Activity Context to your custom OnClickListener as :
buttonList.get(i).setOnClickListener(new MyOnClickListener(i, Your_Current_Activity.this));
and change the Constructor of your custom OnClickListener class to :
int index;
Context context;
public MyOnClickListener(int index,Context context)
{
this.index = index;
this.context=context;
}
#Override
public void onClick(View arg0) {
// now finish Activity as\
context.finish();
// OR
// ((Activity)context).finish();
}
View.OnClickListener myListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Button",v.getText().tostring);
}
});
you will get your button value in view so, you will find it which index is.
change your for loop and create new Object every time and pass the index in constructor.
for (int i =0;i<buttonList.size();i++) {
buttonList.get(i).setText("Remove");
buttonList.get(i).setOnClickListener(new MyOnClickListener(i));
}
You can get index in your onClick Method.
I'm not sure this applies specifically to your case, but I had the desire to create a custom listener for clickable elements to prevent them being clicked twice (if the user taps quickly).
My solution was to create a listener class that I pass a custom Runnable to and then handle that Runnable if the button is being clicked the first time, but obviously you can pass any custom behavior in, this is just one very simple illustration of how to use it...
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.view.View;
public class MyCustomOnClickListener implements View.OnClickListener {
public static final String TAG = MyCustomOnClickListener.class.getSimpleName();
private Runnable doOnClick;
private Context mContext;
private int isClicked = 0;
public MyCustomOnClickListener(Context c, Runnable doOnClick) throws Exception{
if(!(c instanceof Context) || !(doOnClick instanceof Runnable))
throw new Exception("MyCustomOnClickListener needs to be invoked with Context and Runnable params");
this.doOnClick = doOnClick;
this.mContext = c;
}
#Override
public void onClick(View view) {
Log.v(TAG,"onClick() - detected");
if(isClicked++ > 0)return; //this prevents multiple clicks
Log.d(TAG, String.format("onClick() - being processed. View.Tag = \"%s\"", view.getTag().toString()));
new Handler(mContext.getMainLooper()).post(doOnClick);
}
}
and then to use it (assuming you're in an Activity for the this context)...
try{
Button aButton = findViewById(R.id.someButton);
aButton.setOnClickListener(new MyCustomOnClickListener(/*context*/this, new Runnable(){
public void run(){
//here you would put whatever you would have otherwise put in the onClick handler. If you need the View that's being clicked you can replace the Runnable with a custom Runnable that passes the view along
}
}));
}catch(...){
}
Hi guys I can't figure out why I cant get it to work, to check the CheckBox of an activity from within another class.
In the onCreate method of the activity I'm passing a reference of itself to another class
public MainActivity()
...
dbi = new DBPrefsInterface(this);
...
}
public DBPrefsInterface(Context ctx)
{
MainActivity pma = (MainActivity)ctx;
this.ma = pma;
}
Now I try to Check a checkbox which is placed on the activity
this.ma.cbx.setChecked(true);
but it isn't working.
It seems I didn't pass a reference, only a Copy of MainActivity.
Thanks in adcance
Try passing a handler and a reference to the checkbox in the constructor of the other class
and make the handler send a message to the checkbox's original context
hanlder.post(new Runnable() {
#override
void run {
checkbox.setChecked(true);
}
});
Why don't you pass in the CheckBox itself? So your constructor becomes public DBPrefsInterface(CheckBox cbx) and you manipulate that reference.
Here is an example of a simple activity to demonstrate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.checkbox);
CheckBox cbx = (CheckBox) findViewById(R.id.box);
Button button = (Button) findViewById(R.id.button);
final DBPrefsInterface iface = new DBPrefsInterface(cbx);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
iface.toggle();
}
});
}
private class DBPrefsInterface {
CheckBox cbx = null;
public DBPrefsInterface(CheckBox cbx) {
this.cbx = cbx;
}
public void toggle() {
cbx.setChecked(cbx.isChecked());
}
}
I don't see why you would want to do this, but I think using the following constructor would do the work:
private MainActivity ma;
public DBPrefsInterface(MainActivity a){
ma = a;
}
Then to set the checkbox (but checkbox needs to be public in order to work):
ma.cbx.setChecked(true);
I have made a custom component like Mybutton.java
and I have set an onclick listener in Mybutton.java.
Now, in my new activity, I have to call a Mybutton
and add content in onclick listener.
However, if I use OnClickListener mClickListener = new OnClickListener(){......
it will replace the old content.
I hope it can do the old and new listener together.
I have searched for some information, found out i can implement this method.
After many attempts, I'm still getting errors.
Can anyone give me a simple example
that i can learn to modify it?
I don't think there's an API in the Android API that allows multiple onClick listeners. You'd need some custom class that handles a single onClick() and pass in handlers for it to call. Something like this:
private class CompositeOnClickListener implements View.OnClickListener{
List<View.OnClickListener> listeners;
public CompositeOnClickListener(){
listeners = new ArrayList<View.OnClickListener>();
}
public void addOnClickListener(View.OnClickListener listener){
listeners.add(listener);
}
#Override
public void onClick(View v){
for(View.OnClickListener listener : listeners){
listener.onClick(v);
}
}
}
When your setting your buttons, do:
CompositeOnClickListener groupListener = new CompositeOnClickListener();
myButton.setOnClickListener(groupListener);
Then, whenever you want to add another listener, just call
groupListener.addOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
**** Custom implementation ****
}
});
You could create your custom Button class something like this :
public class MyButton extends Button {
private CustomOnClickListener mCustomOnClickListener;
public interface CustomOnClickListener {
void onClick(View v);
}
public MyButton(Context context) {
super(context);
// Set your own onClickListener
View.OnClickListener ocl = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do whatever you want to do
// Invoke the other added onclick listener
if(mCustomOnClickListener != null) {
mCustomOnClickListener.onClick(v);
}
}
};
setOnClickListener(ocl);
}
// use this function to set the other onclick listener
public void setCustomOnClickListener(CustomOnClickListener cl) {
mCustomOnClickListener = cl;
}
}
and, use it like this :
// create your button
MyButton button = new MyButton(context);
// add your custom onClickListener
button.setCustomOnClickListener(new MyButton.CustomOnClickListener() {
#Override
public void onClick(View v) {
// Do whatever you intend to do after the actual onClickListener
// from MyButton class has been invoked.
}
});
If you want to execute some internal logic in your custom view's onClick and want to execute the externally set up OnClickListener's logic, I think a simple way is overriding setOnClickListener as below.
In Kotlin:
override fun setOnClickListener(externalOnClickListener: View.OnClickListener?) {
val internalOnClickListener = View.OnClickListener { view ->
//Your awesome internal logic
externalOnClickListener?.onClick(view)
}
super.setOnClickListener(internalOnClickListener)
}
Same in Java:
#Override
public void setOnClickListener(#Nullable final View.OnClickListener externalOnClickListener) {
View.OnClickListener internalOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
//Your awesome internal logic
if (externalOnClickListener != null) {
externalOnClickListener.onClick(view);
}
}
};
super.setOnClickListener(internalOnClickListener);
}