I was creating a simple calculator with android. I searched the google and found this fragment of code which worked perfectly for me. But I cannot understand this fragment of the code which was implemented on the onCreate() method. Can someone please explain me this part of code?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Welcome :)", Toast.LENGTH_SHORT).show();
int[]Btn_Id={ R.id.Btn0, R.id.Btn1, R.id.Btn2, R.id.Btn3,R.id.Btn4, R.id.Btn5, R.id.Btn6, R.id.Btn7, R.id.Btn8, R.id.Btn9, R.id.BtnClear, R.id.BtnDecimal, R.id.BtnDivide, R.id.BtnMultiply, R.id.BtnSubtract, R.id.BtnAdd, R.id.BtnEqual };
for(int i: Btn_Id) {
((Button)findViewById(i)).setOnClickListener(this);
}
}
int[]Btn_Id
it is a array of button which contain id of buttons defined in layout resource file
The below code is used to set ClickListener to all Button in your Btn_Id array
for(int i: Btn_Id) {
((Button)findViewById(i)).setOnClickListener(this);
}
The method onCreate is called when activity starts, its the entry point for the activity.
And activity is empty window, the setContentView is used to fill the resource of id R.layout.activity_main
super.onCreate(savedInstanceState);, you tell the Dalvik VM to run your code in addition to the existing code in the onCreate() of the parent class. If you leave out this line, then only your code is run. The existing code is ignored completely.
R.id.Btn0.... means its defined in resource file and used to show 0 and other buttons. int[]Btn_Id variable holds the resource id of the used buttons.
The following line assigns listener for button click for all the buttons:
for(int i: Btn_Id) {
((Button)findViewById(i)).setOnClickListener(this);
}
Hear is the solution of your problem hope you understand code till
Toast.makeText(this, "Welcome :)", Toast.LENGTH_SHORT).show();
which will create toast message 'welcome' when activity launch.
int[]Btn_Id={ R.id.Btn0, R.id.Btn1, R.id.Btn2, R.id.Btn3,R.id.Btn4, R.id.Btn5, R.id.Btn6, R.id.Btn7, R.id.Btn8, R.id.Btn9, R.id.BtnClear, R.id.BtnDecimal, R.id.BtnDivide, R.id.BtnMultiply, R.id.BtnSubtract, R.id.BtnAdd, R.id.BtnEqual };
Above the Btn_Id is an integer array that will store ID of the all button from btn0 to btnEqual
for(int i: Btn_Id) {
((Button)findViewById(i)).setOnClickListener(this);
}
this function called for each loop. It work like for every int ID in array Btn_Id and assign to int i. and for every i set Button.setOnClickListner(this)\ this is a context.
if you try to find a source code of android calculator then you can get from hear free.
Download Source code:https://www.youtube.com/playlist?list=PLdMmtAIsH0KYiKrdpbzat6t96Nb1_k3_1
Related
Consider you have a Button A and button B both of them when clicked it start Activity1 which contains only one TextView.
Now When I click on Button A it should start Activity1 and setTextView to "The click was from A"
and when clicked on B it should set the text to "The click was from B".
So I figure out that by making a global Boolean variable but I wanted to know is there any other way that is more efficient than making a global Boolean variable(the code become really messy with Boolean)
And this all is just an example in reality I want to add a lot of code instead of just setting the text.
TL;DR
Pass arguments with your Intent object that launches Activity2. Use putExtra methods. That is the default way of passing small pieces of data.
Explained
"making a global Boolean variable" is a bad solution (nothing personal, it just does not fit the given problem) in this situation as anyone has access to that variable and the value can be changed at any point in time making it unreliable.
When you launch activity with Intent you can use putExtra methods on it (example of such method in docs).
For example, there is a putExtra that accepts boolean as a value: link. Using that method you can remove the global variable, but the code still could be messy.
If this boolean variable is simply deciding which label to show you can pass the label itself using these putExtra methods. It would look like this:
// From Activity1 when you click Button A
buttonA.setOnClickListener {
Intent intent = new Intent(Activity1.this, Activity2.class);
intent.putExtra(Activity2.SOME_KEY, "This label is from buttonA.");
startActivity(intent);
}
// From Activity1 when you click Button B
buttonB.setOnClickListener {
Intent intent = new Intent(Activity1.this, Activity2.class);
intent.putExtra(Activity2.SOME_KEY, "This label is from buttonB. A slightly different one.");
startActivity(intent);
}
Activity2.SOME_KEY is some public static variable that you should declare to be sure that you use the same key for setting and getting back the value. You can name it differently. It must be of String type. There is no need to declare it in Activity2 class but since it is the key for passing arguments for Activity2 only I think that is the most fitting place.
And now in you can get that value back in Activity2:
class Activity2 extends Activity {
public static String SOME_KEY = "some string value";
private String labelValue = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
labelValue = getIntent().getStringExtra(SOME_KEY);
// ... other stuff here like setContentView
// use `labelValue` to set text into some TextView.
}
}
I have a function attached to a button that when pressed removes an item from an arraylist and then displays a toast saying "Item Removed!". If I press the remove button several times then ALL the toasts show up making it look like one really long toast display. I want to cancel the toast each time before displaying a new toast. I was displaying my toast as such
public void removeItem(View view)
{
Toast.makeText(getApplicationContext(),"Text",toast.LENGTH_LONG).show();
}
Now I am trying to make a toast object, cancel it, set the text, and then display it each time the button is pressed. This way the previous toast is cancelled. Not sure if this is the right way to do it.
public void removeItem(View view)
{
Toast toast = Toast.makeText(this,"",Toast.LENGTH_SHORT);
toast.cancel();
toast.setText("Text");
toast.show();
}
This ends up showing nothing at all. Any help?
Your given example does not work because you are calling cancel() on the newly created instance of your Toast object. You'll have to keep a reference to the currently shown Toast somehow, and cancel it before displaying it again.
Toast mMyToast // declared within the activity class
public void removeItem(View view)
{
if(mMyToast!=null) mMyToast.cancel() // Avoid null pointer exceptions!
mMyToast = Toast.makeText(this,"Text",Toast.LENGTH_SHORT);
mMyToast.show();
}
A couple of thoughts:
1: you could make the text more specific so that they can see which item was removed and they don't look like one long toast: "Removed Item: Bob", "Removed Item: Mary".
2: Make the toast display length short.
3: Consider skipping the toast all together. I assume they will see the items being removed from the list as you click.
I have an Android app that displays a list using a ListView, and there's an action bar button to clear said list. I decided to add a confirmation dialog so people don't accidentally delete all their entries, and I'm running into problems. If I use setListAdapter inside the onclick for the "yes" button within the dialog, it won't compile. If I use it outside that onclick, it'll work but not refresh the list until the user backs out of the activity and goes back into it, which for obvious reasons is not appropriate. Here's my method that gets called when the "clear list" action bar button is pressed, which contains the relevant onclick for the internal buttons.
I have a feeling I shouldn't be using "this" in setListAdapter since with the dialog, this no longer corresponds to the listview activity I think? But I'm not sure what to put instead.
public void clearTrigger(MenuItem item) {
//Set up a dialog with two buttons to verify that the user really wants to delete
everything
confirm = new Dialog(display.this);
confirm.setContentView(R.layout.conf);
confirm.setTitle("Confirm deletion");
yes = (Button)confirm.findViewById(R.id.yes);
//If the user says yes, then delete everything
yes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Remove everything from Hours.
Hours.clear();
String tempH = " ";
String tempW = " ";
//Then save it again in it's new, empty state so that it doesn't reappear the next time the app is run.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
SharedPreferences.Editor edit = prefs.edit();
edit.putString("SAVEDATA", TextUtils.join(",", Hours));
edit.remove("totalh");
edit.remove("totalw");
edit.commit();
//And finally... refresh the list view - doesn't work
setListAdapter(new ArrayAdapter<String>(this, R.layout.activity_list, R.id.listText, Hours));
confirm.dismiss();
}
});
confirm.show();
}
The first argument of ArrayAdapter constructor is a Context, so you need to pass the Activity to it, something like new ArrayAdapter<String>(MyActivity.this, ...). Right now you're passing it your instance of OnClickListener which is why it's giving compiler error.
But the best way to update a ListView is to make changes on the ArrayAdapter itself using methods like adapter.add and adapter.remove, and then call adapter.notifyDataSetChanged(). In your case, you would call adapter.clear().
I'm using Eclipse for windows 7 and I am making an informative application(just text and offline content).
In my app I have about 180 buttons. Each button will lead to another screen. I need to know how to make each button lead to a specific screen?
And also, is there a way to like duplicate the code and not spend hours copying and pasting the code 180 times?
Check my code below for the first two screens:
That's for the MainActivity.java:
public void addListenerOnButton() {
final Context context = this;
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(context, MainActivity2.class);
startActivity(intent);
}
});
}
I mean that code is only for one single button. Am I supposed to repeat this for every single button?
and also a question, how many classes should I do? 180 main activities, 180 fragment_main.xml and 180 activity_main.xml?
That's my idea, since your application is just a "informative application" you can create two activities:
Main activity with buttons
"Information page"
To do it i need info about how you get this informations:
In a SQLite Database.
In a string-array
Personally, i prefer a SQLite DB it allows you to improve it without problems in the future.
About the Information activity:
Example: in your layout you have a TextView where will be added the text which this activity should be passed.
To make it dynamic in your case we pass the string to show using Intents, in our onCreate we add something like this:
Intent intent = getIntents();
String stringToDisplay = null;
if (intent != null)
{
stringToDisplay = intent.getStringExtra (EXTRA_STRING_CONTENT);
}
getIntents will get the Intent object which is created and passed to it by our main activity. getStringExtra is a simple method which says to Android: i want to get the string which is saved with the key EXTRA_STRING_CONTENT (it's something like a Map)
EXTRA_STRING_CONTENT is a field which we used to make sure we don't make any error in passing data, since we need to use the same name when we pass it (in MainActivity) and when we read it (InformationActivity)
public static final String EXTRA_STRING_CONTENT = "EXTRA_STRING_CONTENT";
Ok, we are done.
We now only need to set the string to our TextView:
TextView infoTextView = (TextView) findViewById(R.id.infotextview);
infoTextView.setText (stringToDisplay);
Stop it.
Now we should go to our MainActivity code and modify our addListenerOnButton
final Context context = this;
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(context, MainActivity2.class);
startActivity(intent);
}
});
Well, i will focus on this two lines
Intent intent = new Intent(context, MainActivity2.class);
startActivity(intent);
We need to pass the string to display here, how?
Before we used getStringExtra now it's similar (note: it's the same Intent class) but now we need the putExtra method, the compiler will select the correct overload for us so we just need to do
String stringToDisplay = "Hello world";
intent.putExtra(InformativeActivity.EXTRA_STRING_CONTENT, stringToDisplay);
(Note: InformativeActivity.EXTRA_STRING_CONTENT)
With the current code we will always sent Hello world to the second activity but we need something of dynamic based on the button... well now this depends on how you get the data.
If it's a string-array, you can save the string-array in an array and then based on the button (if it's the first sent string index 0, etc.).
An example:
int buttonId = 1; // it will be a general variable, if it's button 1 it will be 0, if 2-1 etc.
String[] informations = getResources().getStringArray(R.array.infos); // in a real code you should move it outside the `onClick` code and put it in a static final field.
intent.putExtra(InformativeActivity.EXTRA_STRING_CONTENT, informations[buttonId]); // it's the same of above
If you understand the concept you will know how to adapt the code based on your needs.
There are some cases where you need more info or what you want to sent is something which is better if managed by the second activity (example: in a sqlite database you could sent only the id of the line and read lines in the second activity based on this id)
Some things which you could change:
Avoid to call it MainActivity2, it's not so helpful as name
You don't need really to save Context, you could just use MainActivity.this
Try to make your addListenerOnButton more general, example take as argument a Button and set the listener to it.. don't read it from XML you will end up with 180 methods for every button.
I've been looking for a way to have the blank detail side of my fragment layout host a welcome screen (or something - login perhaps) on start up. Afterwards, when a user presses one of the left side menu items, I'd like to eliminate the fragment for the remainder of the program run. I don't want to add it to the backstack, as that messes up my configuration changes. I've considered using shared prefs to host a boolean about whether the fragment has been displayed. The only concern with this method is where to safely reset the boolean value for the next run of the app. I'm of the impression that there's no gaurantee that the onStop, onDetach etc. will definitely get called upon closing of the app, so if the app got closed in the wrong state, it would be rendered useless ( the first fragment wouldn't display - crash )
Anyone have any ideas on how I could implement a filler for the right side of the app upon startup?
I've been trying to add something to the onCreate of my main activity thus far with no success.
Thanks in advance.
Ken
If your fragment can be part of its own Activity, you can use the android:noHistory="true" attribute to keep the Activity off of the backstack. If your user tries to navigate backwards, it'll hit the bottom of the backstack twice before exiting your application.
If you can't split your fragment into its own activity, noHistory may not work -- I can't say as I haven't tried it myself.
I was able to come up with a solution to creating a welcome or login screen which will display both fragments and activities from the main activity. Seems to be working fine as tested.
private boolean welcomeShown;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_list);
if (findViewById(R.id.item_detail_container) != null) {
mTwoPane = true;
((MainFragment) getSupportFragmentManager().findFragmentById(
R.id.item_list)).setActivateOnItemClick(true);
}
if (savedInstanceState != null){
welcomeShown = savedInstanceState.getBoolean("displayed");
}
if(!welcomeShown){
if (mTwoPane){
WelcomeFragment welcomeFragment = new WelcomeFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container, welcomeFragment)
.commit();
}
else{
Intent welcomeIntent = new Intent(this, WelcomeActivity.class);
startActivity(welcomeIntent);
welcomeShown = true;
}
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("displayed", true);
}