Is this a bad habit, and why if it is? So in every activity adding this right after onCreate...
mContext = this;
and then use it in all other cases where context is required? For example
Toast.makeText(mContext, mContext.getString(R.string.someString), Toast.LENGTH_LONG);
EDIT: What if I have something like this...how the context should be passed? Because this cannot be applied (because of the View.OnClickListener()).
someButton = (Button) findViewById(R.id.someButton);
someButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, mContext.getString(R.string.warning), Toast.LENGTH_LONG).show();
}
});
Is this a bad habit, and why if it is?
Yes, it is a bad habit. It is a waste of code. this is shorter than mContext, and you have an extra line of code for setting the data member.
I disagree with Mr. Damiean's suggestion of always using getApplication(). Use getApplication() when you specifically need the Application object. You neither need nor want the Application object for creating a Toast -- your Activity is a perfectly suitable Context to use there. The Application object fails to work in many places, particularly when dealing with things involving the UI.
You can use this instead. Even in an OnClickListener or other subclasses you use ActivityName.this like this:
someButton = (Button) findViewById(R.id.someButton);
someButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(ActivityName.this, ActivityName.this.getString(R.string.warning), Toast.LENGTH_LONG).show();
}
});
Related
I have GridLayout with a CardView inside. I want to create an Intent to 4 different activities. I only can execute one Intent. I do not know if I should use Else If or case. Thanks for your help. Here is my code.
GridLayout mainGrid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dashboard);
mainGrid = (GridLayout)findViewById(R.id.grid);
setSingleEvent(mainGrid);
}
private void setSingleEvent(GridLayout mainGrid) {
for (int i=0;i<mainGrid.getChildCount();1++)
{
CardView cardView = (CardView)mainGrid.getChildAt(i);
final int final1= i;
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i=new Intent(DashboardActivity.this,MapsActivity.class);
startActivity(i);
}
});
}
}
I think your problem comes from a lack of understanding how the order of execution of the program works. If you insert a cycle for and then you put inside an anonymous class as it is the case of View.onViewClickListener is normal that you will have only one result, because you break the for cycle.
The way to go should be to not use a for cycle, but assigning different Explicit Intents depending by what you want to obtain.
EDIT. On the base of your use case you need to trigger the Intent from the Adapter. Please see here and mainly here, basically you need to use the Android SDK functionality that tells you which card has been clicked mRecyclerView.getChildLayoutPosition(view); then depending from your needs you may (or not) pass a switch case for educational purposes, although possibly is not the most elegant and efficient way to solve.
If you want a different Activity to be started depending on what CardView is clicked try something like the following:
private void setSingleEvent(GridLayout mainGrid) {
mainGrid.getChildAt(0).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(i);
}
});
mainGrid.getChildAt(1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(i);
}
});
//do this for all 4 cardViews.
}
In short: set all Intents separately.
I already made some Apps in Android and noticed that I am often using static methods.
For example I have an Class which extends PreferenceFragment. In this PreferenceFragment I set an onClick event on a Button.
Button btn = new Button(getActivity().getApplicationContext());
btn.setText("Save");
v.addView(btn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
SettingsActivity.finishActivityWithResultOkey();
}
});
Then I'm calling a static method in my SettingsActivity which finishes this Activity. Is this a good way of doing what I want to do? Or is there a better solution?
In Android (in memory managed programming languages like Java, more precisely), static methods can lead to "memory leaks" if not used correctly. I've quoted "memory leaks" as they are not the pure definition of memory leaks, like in C++ where you forget to remove some items from memory and lose the reference to them (and thus cannot clear them later on - at least not easily), but more like keeping on to references when you no longer need them and preventing the GC from doing its job in clearing that memory for you. There are a lot of articles on the web that cover this (search for "Android static memory leak") and a lot of other questions on SO that have been asked about this (see [static][Android][memory-leaks] tags), so I won't go into this.
For your particular case, in order to avoid possible memory leaks, you can get the Activity from the Fragment object that your anonymous OnClickListener object is tied to by using MyFragmentClass.this.getActivity(), cast it to, say, SettingsActivity (as is the case here) and call .finishActivityWithResultOkey() on it. It's best that you guard your cast too.
Here's an example of how the code could look like:
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final Activity activity = MyFragmentClass.this.getActivity();
if(activity instanceof SettingsActivity)
((SettingsActivity)activity).finishActivityWithResultOkey();
else
throw new IllegalStateException("This OnClickListener requires a SettingsActivity to start the fragment containig it"); //helps with debugging
}
});
As a note: MyFragmentClass refers to the class of the fragment that you're putting this code in :)
You can use a Java property known as mirroring.
Below I use the property to finish the activity.
Button btn = new Button(getActivity().getApplicationContext());
btn.setText("Save");
v.addView(btn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
SettingsFragment.this.getActivity().finish();
}
});
public class Menu extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
//myIntent.setClassName("hello.World", "hello.World.mybuttonclick");
// myIntent.putExtra("com.android.samples.SpecialValue", "Hello, Joe!"); // key/value pair, where key needs current package prefix.
//startActivity(myIntent);
//Button myButton = (Button) findViewById(R.id.my_button);
super.onCreate(icicle);
setContentView(R.layout.main);
}
public void updateLayout(){
Intent myIntent = new Intent(Menu.this, mybuttonclick.class);
startActivity(myIntent);
// TextView sayHello = (TextView) findViewById(R.id.Hello);
}
}
Hey guys, I am a new android java student and we have to develop a simple hello world app.. I am finding some difficulty getting my onClick() activity to work, using android:Onclick in xml.. what i am trying to do is change the content view do display a simply a different layout and saying hello.. i am using setContentLayout to do this, every time i click said button tho the android app crashes out.. am i doing something wrong?
regards,
Stefan
When you set a click listener in xml you must have the method defined inside the activity you are clicking in. Lets say you set the onClick in xml to be "buttonClicked", you must create a method looking exactly like the one below.
public void buttonClicked(View view)
{
//Your code here
}
The thing to notice is that the method is a public void with only a single parameter of type View. XML defined click listeners must be like this to work. The view object in the example above is the view that was clicked.
You update layout function needs to read
public void updateLayout(View view)
In response to your question, there are a number of things that are issues causing the complication that you described. Let it first be said, that you don't have to do anything any particular way, provided that you make concessions for certain things. Android is a very flexible platform and Java, as an OOP language allows you to do things that many non OOP languages do not.
Whenever you create a "clickable" item, like a Button, if you want to have your program respond, you must have something "listen" to it. This is known as a Listener. In your case, you are looking for an OnClickListener. The OnClickListener does not have to be a part of the Activity necessarily. It just has to be a class that implements View.OnClickListener. Then, you have tell the setOnClickListener() method of the Button who its listener is. The following example shows what is necessary without your declaration in XML (but it is important).
class Menu extends Activity implements View.OnClickListener
{
public void onCreate(Bundle icicle)
{ setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML);
btn.setOnClickListener(this);
}
public void onClick(View view)
{ int id = view.getId();
if (id == R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML)
updateLayout()//Do your Click event here
}
public void updateLayout()
{ //updateLayout code...
}
}
Something that needs to be noted is the OnClick() above. Every OnClickListener must use the same signature as theOnClick() That means itmust have the same return and same arguments even if it has a different name. For what you are trying to do (in XML), you have set your android:OnClick to updateLayout. This means that `updateLayout() must be declared as follows:
public void updateLayout(View view)
Now, getting the update method to actually work: While you provide your code, we don't actually know what errors you are getting. It is always much easier to solve a problem if we have a copy of the Logcat output that includes the error you are receiving. Once, we have that we can target your error specifically and I can edit my answer to include what you may additionally need.
FuzzicalLogic
Here i wrote some code, and i want to call a method of other class from onClick() and getting NPE in "new Start().moreApplication(feedsId);" line..
final TextView feeds=(TextView)findViewById(R.id.more_feeds);
feeds.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Log.e("MoreChoices","onclick---------");
final int feedsId= feeds.getId();
Log.e("MoreChoices","onclick----After initialization of id--------");
new Start().moreApplication(feedsId);
Log.e("MoreChoices","onclick----------------After calling--------");
}
});
Start.java is my an other Activity class, and i have one in Start.java, and i want to call that method from other class with using this code..
Please tell why i am getting NPE in
"new Start().moreApplication(feedsId);"
line...
Thanks in Advance please guide me....
Please, take some time reading anddev book, a very good place to start android development.
Read pages 50+ and you will understand that your not doing the right thing to create activities and pass data from one to another.
You should
startActivity by using either an intent or the class of this activity
pass data from your activity to the new one using intent's extra parameters.
Regards,
Stéphane
replace this line
final TextView feeds=(TextView)findViewById(R.id.more_feeds);
by
final TextView feeds=(TextView)this.findViewById(R.id.more_feeds);
I hope you got solution .
I think u need to get the View ID which u have clicked the enhanced code look like
final TextView feeds=(TextView)findViewById(R.id.more_feeds);
feeds.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Log.e("MoreChoices","onclick---------");
final int feedsId= arg0.getId();
Log.e("MoreChoices","onclick----After initialization of id--------");
new Start().moreApplication(feedsId);
Log.e("MoreChoices","onclick----------------After calling--------");
}
});
So, I am again, asking a very basic question. I apologize for my ineptness but I guess I read the given tutorials on these topics poorly. My question is as follows:
I would like to use a "listener" pattern to handle button presses on my GUI. I believe an onClickListener is what I need to use to handle these button presses. However, I'm not sure if I should be creating and handling events that occur after the GUI is created within an onCreate method. The following code is within my onCreate method for one of my Activities:
View.OnClickListener upDownListener = new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if(v == (upOneButton))
{
Log.d("OptionSelect", "Up One Button Pressed.");
ops.getOptionList().get(0).incrementProbability(4);
} . . .
This method being called updates some GUI text with a different number. It is being called, but the GUI isn't responding. I imagine this has to do with my attempt to use it within the onCreate method.
In short, what is a good and simple way to deal with user events within a GUI and where should this occur?
Thank you so much.
EDIT: Log.d() does in fact get called. Also, ops is an object of type OptionSelect which happens to be the type of the class in which the onCreate() call is made. Will that become an issue? Also, here is the method for incrementProbability():
public void incrementProbability(int numberOfOptions)
{
probability += (numberOfOptions - 1);
if(probability > 100)
{
Log.i("OptionSelect", "Exceeded Maximum by " + (probability - 100));
probability = 100;
}
}
Also, here is relevant code I should've included that is updating my GUI at the end of the onClick() method:
private void refreshDisplay(TextView a, TextView b, TextView c, TextView d)
{
a.setText(getOptionList().get(0).getProbability() + "");
b.setText(getOptionList().get(1).getProbability() + "");
c.setText(getOptionList().get(2).getProbability() + "");
d.setText(getOptionList().get(3).getProbability() + "");
a.invalidate();
b.invalidate();
c.invalidate();
d.invalidate();
}
Thanks for the help so far!
I personally prefer to have my Activities implement listener interfaces and add an onClick method to the Activity itself such as...
public class MyActivity extends Activity
implements View.OnClickListener {
...
#Override
public void onClick(View v) {
...
}
}
I then just use...
myGuiObject.setOnClickListener(this);
...whenever I want to set that method as the listener for any GUI object.