Recently I started proggraming from scratch and I'm learning from thenewboston's tutorials and I dont really get how it works and I cant find any answers. Thats the code Im struggling with, it works but i dont really get why there is beetwen () brackets an new Button.OnClick listener and then OnLongClickListener where does the View v come from in these methods ?? Ye my knowledge about object programming may be a bit smaller than its required but I dont really like learning other way than using this.
Button przycisk = (Button) findViewById(R.id.mojprzycisk);
przycisk.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) { WHERE THIS V IS FROM ?
TextView mojtekst = (TextView) findViewById(R.id.mojtekst);
mojtekst.setText("Good job Boss");
}
}
);
przycisk.setOnLongClickListener(
new Button.OnLongClickListener() {
public boolean onLongClick(View v){ <-----WHERE IS IT FROM?
TextView mojtekst = (TextView) findViewById(R.id.mojtekst);
mojtekst.setText("HOLY CARP THAT WAS A LONG ONE");
return true;}}
);
You should look into interfaces for java. A great tutorial for the same is also given here. Once you understand the concepts of interfaces, you can see that OnClickListener and OnLongClickListener are interfaces, and they have methods like onClick(View v) and onLongClick(View v), that are invoked when a particular view has been clicked or long clicked. They return back the view that was clicked and held.
When you say
przycisk.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) { WHERE THIS V IS FROM ?
TextView mojtekst = (TextView) findViewById(R.id.mojtekst);
mojtekst.setText("Good job Boss");
}
}
);
You are creating a new instance of the interface. The above code for easy readability can be also be written as follows.
Button.OnClickListener onClickListener = new Button.OnClickListener() {
#Override
public void onClick(View v) {
TextView mojtekst = (TextView) findViewById(R.id.mojtekst);
mojtekst.setText("Good job Boss");
}
};
przycisk.setOnClickListener(onClickListener);
So basically you're creating an instance of the interface, and since its an interface you need to override the method onClick() and give its definition.
In short to whichever view you set the onClickListener or the onLongClickListener, that view would be returned in the onClick(View v) and onLongClick(View v) methods. That view would be the v.
Related
I was filling inside a getView() of an adapter while defining the click listeners, this got me wondering:
Performance-wise, is there a difference between these two implementations:
Defining onClickListener separately:
View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) { //... }
};
mView.setOnClickListener(mClickListener);
and
Defining onClickListener as the argument:
mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) { //... }
});
As getView() is frequently called, my though is that even small differences in its implementation would have big effect in app's performance. But I'm not sure.
So, which of the above is recommended regarding the performance/memory? Or aren't they that different to matter?
Well that actually depends on how many OnClickListeners do you have as anonymous classes.
it would be better to implement one click listener and set it to all of the views on which you want to get click event and sort the clicks out with view id's in OnClick(View v)
public void onClick(View v) {
switch (v.getId()) {
case R.id.some_view_id:
doSomething();
break;
}
}
I have seen lots of example to which one use a if condition or a case statement to programmatically change the conditions of elements...yadda yadda. I need to change the value of a button based on what the user clicks. Below is the code that I currently have.
Button btnOpenPopup = (Button)findViewById(R.id.polarity);
btnOpenPopup = (Button) findViewById(R.id.color);
final Button finalBtnOpenPopup = btnOpenPopup;
btnOpenPopup.setOnClickListener(new Button.OnClickListener(){CONTINUES TO OTHER FUNCTIONS }
I basically need to know what button was pressed. Then dynamically populate it into findViewById() function. i.e.
btnOpenPopup = (Button) findViewById(R.id.DYNAMTICVALUEOFBUTTONUSERHASPRESSED);
This way by the time it gets to the final Button part of the code it will have the value to which the user clicked on. Code works if I only want to have one button or a page mile deep in different configuration (not ideal).
All the examples I have seen so far are after the user clicks the button (which is what I want) but they name the buttons name statically like above code shows but very much static.
Hope that all makes sense.
UPDATE:
I think I may have confused the situation. Below is the remaining code. Hopefully this will provide context. The btnOpenPopup needs to remain the same as it's used in the call to execute the command for a new window to actually popup. Hopefully this will provide a bit more context for what I'm trying to achieve.
final Button finalBtnOpenPopup = btnOpenPopup;
btnOpenPopup.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View arg0) {LayoutInflater layoutInflater = (LayoutInflater)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.meditationpopup, null);
//set the title of the popup
TextView titletext = (TextView) popupView.findViewById(R.id.chakratitle);
titletext.setText(activityName);
if (activityName.equals("Root"))
{
switch (arg0.getId())
{
case R.id.color:
//Rename the string so to get the value from the string xml
String stringName = activityName.toLowerCase().replaceAll(" ","")+"color";
TextView desctext = (TextView) popupView.findViewById(R.id.popupDesc);
desctext.setText(getString(getStringResource(getApplicationContext(),stringName)));
break;
case R.id.polarity:
//Rename the string so to get the value from the string xml
String polarityString = activityName.toLowerCase().replaceAll(" ","")+"polarity";
TextView polarityDesc = (TextView) popupView.findViewById(R.id.popupDesc);
//polarityDesc.setText(activityName);
polarityDesc.setText(getString(getStringResource(getApplicationContext(),polarityString)));
break;
}
}
I think
Button btnOpenPopup = (Button)findViewById(R.id.polarity);
btnOpenPopup = (Button) findViewById(R.id.color);
should be
Button btnOpenPopupFirst = (Button)findViewById(R.id.polarity);
Button btnOpenPopupSecond = (Button) findViewById(R.id.color);
you should declare different different button for diffrerent findviewbyid
also in my eclipse it is not accepting
btnOpenPopup.setOnClickListener(new Button.OnClickListener()
instead it works with
btnOpenPopup.setOnClickListener(new View.OnClickListener() {}
and you need to provide more clear view of what you want to perform
new thoughts,try doing this:
btnOpenPopupFirst.setOnClickListener(this);
btnOpenPopupSecond.setOnClickListener(this);
then option will come on both the above code lines
The method setOnClickListener(View.OnClickListener) in the type View is not applicable for the arguments (MainActivity)
choose this
let MainActivity implement OnClickListener
then this option will come
The type MainActivity must implement the inherited abstract method View.OnClickListener.onClick(View)
choose
add unimplemented method
now
#Override
public void onClick(View v)
will be created
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.polarity:
Toast.makeText(getApplicationContext(), "btnOpenPopupFirst(polarity) is pressed", Toast.LENGTH_SHORT).show();
//other code to be performed regarding this button
break;
case R.id.color:
Toast.makeText(getApplicationContext(), "btnOpenPopupSecond(color) is pressed", Toast.LENGTH_SHORT).show();
//other code to be performed regarding this button
default:
break;
}
}
And post your views after implementing this way.
int[] id={R.id.button1,R.id.button2};
Button b=(Button)findViewById(id[i]);
The onClick method in Button.OnClickListener has a View parameter... you can call getId() on that view to get the id of that button that was clicked on.
It doesn't make too much sense to me. If what you really want is this:
btnOpenPopup = (Button) findViewById(R.id.DYNAMTICVALUEOFBUTTONUSERHASPRESSED);
All you need to do is set your value in the onClick(View view) method of your OnClickListener
public void onClick(View view) {
btnOpenPopup = (Button)view;
}
I've always wanted to create an Android activity which uses zoombutton not the zoomcontroller in a view. But I don't know how to get started. I appreciate any help you would give me. If you could give me some piece of code to get started. Thanks
I don't really understand what you actually want to zoom, just want to give you the idea of Zooming a text for a TextView here the code for it.
ImageView increaseTextBtn = (ImageView)findViewById(R.id.increaseTextBtn);
final TextView txtTitle = (TextView) findViewById(R.id.txt_desc);
increaseTextBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
txtTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX,(txtTitle.getTextSize()+1f));
}
});
ImageView decreaseTextBtn = (ImageView)findViewById(R.id.decreaseTextBtn);
decreaseTextBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
txtTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX,(txtTitle.getTextSize()-1f));
}
});
in this code there are two buttons (increaseTextBtn , decreaseTextBtn ) to adjust the zoom level of TextView
Update
For image view you can find an examle here
I create a whole layout setup in XML then attempt to attach listeners to the buttons using findViewById(). The problem I am having now is that the View parameter I receive in the method does not contain the ID of the view I clicked: 830009633920 vs 2131099657.
Button btnNext = (Button)findViewById(R.id.btnNext);
btnNext.setOnClickListener(this);
#Override
public void onClick(View view) {
if (view.getId() == R.id.btnNext) {
...
}
}
How about this:
Button btnNext = (Button)findViewById(R.id.btnNext);
btnNext.setOnClickListener(this);
#Override
public void onClick(View view)
{
switch (view.getId())
{
case R.id.btnNext:
...
break;
case R.id.foo:
...
break;
}
}
That should be working, so my only guess without seeing the rest of the code or layout is that you have set click handlers on two items that overlap.
If you plan on making an Android Library project switch like this will not work due to a recent change in the tool chain.
http://tools.android.com/tips/non-constant-fields
In general I find it is much simpler to use an anonymous class the handle clicks rather than a large single handler.
btnNext.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View view)
{
...
}
});
You might try this approach just to debug that the item you expect to get the click is what you are pressing, to make sure you don't have layout issues.
Try skipping the IDs, and just compare the actually view object. so something like this:
#Override
public void onClick(View view) {
if (view.equals(btnNext)) {
...
}
}
I am kinda new to Android and it would improve my application a lof if I coul keep several OnClickListenres in one class. What I am thiking of is something like this :
Public class OnClickListeners {
public Button.OnClickListener open;
public Button.OnClickListener doSomethingElse;
public Button.OnClickListener etc;
public OnClickListeners() {
open = new Button.OnClickListener()
{
public void onClick(View view)
{
DetailList.SetId(view.getId());
Intent intent = new Intent(view.getContext(), DetailList.class);
startActivityForResult(intent, 100);
}
};
}
}
So I can then reference it in other class B like this
button1.setOnClickListener(OnClickListeners.open);
Any though how to do it?
Android SDK seems to be against me as I can figure it out now for about 2 days now...
Thanks for any advices and help
There is a sleek way to consolidate all your anonymous classes into one and switch on the view. This works best if you know ahead of time which buttons will be using the clicklistener :
public class AndroidTestClickListenerActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new MyClickListener());
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new MyClickListener());
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new MyClickListener());
}
}
class MyClickListener implements View.OnClickListener {
#Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.button1:
// do soemthign for button1
break;
case R.id.button2:
// do something for button2
break;
case R.id.button3:
// do something for button3
break;
default:
// do something for any other button
}
}
}
You can write
button1.setOnClickListener(new OnClickListeners().open);
instead, but this seems an odd architecture for me. I'd suggest you to keep 1 listener in 1 file, having all of them in 1 package, and use like
button1.setOnClickListener(new OpenListener());
The problem of you approach is that usually listeners have to manipulate some data that is part of the class where UI elements are.
If you take listeners out and put them in a separate class, you will also have to provide a lot of references to objects where data to be manipulated is. This will create a lot of interdependent classes, which will not be nice.
IMHO the cleanest way is to use anonymous inner classes.
You can, but you have to declare the OnClickListener as static if you would like to use it in this manner.
public static Button.OnClickListener openListener = new Button.OnClickListener() {
public void onClick(View view) {
}
};
Then you can use:
button1.setOnClickListener(OnClickListeners.openListener);
As noted by other user - this approach is most like bad. You should handle view listeners on the same view and then maybe call another method like openActivity(). I would not do this - you are also openning an activity from another activity, this will probably don't work at all or will mess up the activity history stack
As none of the solutions actually did what I wanted to achieve - I needed a second (or multiple) onClickListener that did not override the onClickListeners that were already assigned to the control.
Here is the java class that I wrote for that purpose:
https://gist.github.com/kosiara/c090dcd684ec6fb2ac42#file-doubleclicklistenerimagebutton-java
public class DoubleClickListenerImageButton extends ImageButton {
View.OnClickListener mSecondOnClickListener;
public DoubleClickListenerImageButton(Context context) {
super(context);
}
[...]
public void setSecondOnClickListener(View.OnClickListener l) {
mSecondOnClickListener = l;
}
#Override
public boolean performClick() {
if (mSecondOnClickListener != null)
mSecondOnClickListener.onClick(this);
return super.performClick();
}
#Override
public boolean performContextClick() {
if (mSecondOnClickListener != null)
mSecondOnClickListener.onClick(this);
return super.performContextClick();
}
}