Android development question:
I have a Vector that stores Strings of "tips" to display to users. I want to generate a random tip whenever the user clicks a button. However, I want it to be a different tip from the last one displayed. The method I've implemented below works perfectly fine for achieving the task until the application is switched. Upon re-entry of the application, a random tip is still displayed each time a user clicks the button, but the method for ensuring the tip is different no longer works. Any clues as to why?
Thanks!
public void but_healthTip_Click(View view)
{
TextView tipHolder;
tipHolder = (TextView) findViewById(R.id.textView_tips);
Random genHealthTip = new Random();
Integer curTip = tips.lastIndexOf(tipHolder.getText());
Integer randTip = genHealthTip.nextInt(tips.size());
while(randTip==curTip){
randTip = genHealthTip.nextInt(tips.size());
}
tipHolder.setText(tips.elementAt(randTip));
}
Well, problem solved. I still add to the vector onCreate(), but I created a static boolean variable to detect if this is the first time onCreate() has been run. I only add to the vector the first time onCreate() is called now.
Related
Ok, I was complaining about this a few days ago, now I have some code in from following a few tutorials/lessons.
I have a RecyclerView that contains an ArrayList with cards, those have an image, title and description.
I have OnItemClick for those cards, using Parcelable when a card is clicked a second activity opens and shows the full details from the cards - that image, title and description, with a new layout.
I've added a previous and a next button bellow that.
Edit to clarify Struggling with:
I need to have a button in the second activity, the one that opens when clicking on a specific card, and clicking on that button should bring the details from the next card from the first activity. Currently a user would have to go back from the second activity to the recyclerview and click on the next card to see the full details from it
I tried implementing a couple of things I found in older questions here but since they're mostly just code based on somebody else's specific situation I can't seem to edit them in order to get them to work.
I'm adding the link to the repository, it's a bit messy since I'm testing a bunch of things in it, but I'm leaving it for reference: https://github.com/simplydikka/traffic.git
The activities I'm working with currently are those:
Details from list gist
The only walk-around I could find based on my level was to set the click of each card to lead with an if statement to a specific tab from a tabbed activity, but that would mean I will have a very very long list of fragment layouts with different information in them by hand, and that just can't be the answer for something like that. I got that to work but it makes no sense to put that much content by hand when I've already got it to show based on position
EDIT: I got to here:
Intent intent = getIntent();
final ExampleItem exampleItem = intent.getParcelableExtra("Example Item");
position = intent.getExtras().getInt("Position");
final int imageRes = exampleItem.getImageResource();
final String line1 = exampleItem.getTextTitle();
final String line2 = exampleItem.getmTextDescription();
final ImageView imageView = findViewById(R.id.image_activity2);
imageView.setImageResource(imageRes);
final TextView textView1 = findViewById(R.id.text1_activity2);
textView1.setText(line1);
final TextView textView2 = findViewById(R.id.text2_activity2);
textView2.setText(line2);
Button next = (Button) findViewById(R.id.next);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
position = position +1;
imageView.setImageResource(imageRes);
textView1.setText(line1);
textView2.setText(line2);
}
});
This is in my second activity class, the one that is showing the details and buttons. I got the button to work. I just don't get how to attach a position to the resources. I did the dumbest thing just to see if it would work at all, and when I wrote (imgRes+1) on click the image becomes a black square, so it does affect it finally. I just need to find a way to actually bring the next position. I'm still looking, testing and searching, definitely not sitting around and waiting for somebody to solve it for me, but it would be reeeally cool if anybody passing by could hind me :D
Currently im making a soundboard like app. Becouse i have around 60 sounds it would take ages to create function for every single one. So I ran into idea, is it possible to detect press of any of these buttons and then get its id? It will be very helpful, becouse the buttons ids are also corresponding music file names. Thanks for any help.
From the question, it was not immediately clear that you are seeking a way to retrieve information encoded in your choice of ID string names rather than to simply use a single handler for all of your buttons, for which getId alone is typically sufficient.
The resource name for a View ID can be extracted from an ID using View.getResources().getResourceName(id). (1)
The result is a reusable listener that obtains the file names by extracting the view ID and looking up the resource name:
View.OnClickListener mSoundClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
String resourceName = view.getResources().getResourceName(view.getId());
mySoundHandler(resourceName);
}
};
You can then attach the handler to each button.
button1.setOnClickListener(mSoundClickListener);
button2.setOnClickListener(mSoundClickListener);
//....
Our app has several fragments. In one of them user fills several TextEdit fields. When he finishes he presses a button in the ActionBar to save the data. The Action just calls a private method named "saveData" that fetches all data from the fields and submit it to our server.
We have many stack traces from our users showing that getView() returns null in method saveData, but for just a small part of them. For most of them there is no problem at all. We cant reproduce the problem and we cant understand what might be causing it. The code is pretty simple:
View vw = this.getView();
EditText et;
et = (EditText)vw.findViewById(R.id.editEmail);
String email = et.getText().toString().trim();
et = (EditText)vw.findViewById(R.id.editPassword);
String password = et.getText().toString().trim();
The action is added in osResume, see below:
public void onResume() {
super.onResume();
MainActivity act = (MainActivity)this.getActivity();
act.bar.removeAllActions();
act.bar.addAction(new SaveAction());
}
Any ideas? How can we reproduce it?
Can you tell from your logs whether the problem is always for the same users / devices ?
I see from the code that you have submitted that the view is in the same fragment - is that actually the case ?
It's POSSIBLE that a fragment no longer in view can have their view destroyed in order to free up resources. e.g.
getView() returns null
If I suspected that this might be the case then I would attempt to recreate the problem on a phone / tablet / emulator with limited resources.
Good luck !
OK, so I'm playing around with an android app.
The 90% use case is that users want to go straight to the primary list screen to find what they're looking for. That's what I want as my default screen.
The first time a user loads the app however, some configuration is required before their list screen is of any value to them.
So my question, is how I can go about displaying the configuration activity the first time the app is opened up, and then the list screen for future openings.
I also want to put a demo button on the configuration screen, so I suppose more than just detecting that it's the first time, I specifically want to detect whether the user has performed certain configurations within the first screen.
After the first time the user has loaded the app you could store the details of whether user has performed the configurations in SharedPreferences.
protected void storeSharedPrefs(String value) {
/*
* Storing in Shared Preferences
*/
editor.putString("first", value);
editor.commit(); //Commiting changes
}
Check each on time application is loaded, whether its the first time and configuration details has been entered correctly by checking SharedPreferences
private boolean first_time_check() {
/*
* Checking Shared Preferences if the user had pressed
* the remember me button last time he logged in
* */
String first = uPreferences.getString("first", null);
if((first == null)){
return false;
}
else
return true;
}
i like dweebsonduty's method. a similar way to do this is to save their configuration information in files on the SD card. your app could start out by checking for those files and loading the information. if the load is successful, it moves on to the next activity, if not it starts the appropriate activity to prompt the user for input.
I have done this same thing, but instead of swiching activities i just switch views until i have all the info i need, and then move on.
Many applications actually store the current version in SharedPreferences, and check against it for if an update has been installed. Its a clever way of achieving a "what's changed" popup, or making sure that some settings get set (I would be wary of just having a boolean flag because if you ever want to add an additional setting, you will need a second flag and it gets messy after the third, etc.).
String VersionValue = "v.1.0";
final String PREFS_NAME = "MyPrefsFile";
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
if (settings.getBoolean(VersionValue, true)) {
//the app is being launched for first time, do something
NewDialogFragment newFragment = new NewDialogFragment();
newFragment.show(getFragmentManager(), "New");
// record the fact that the app has been started at least once
settings.edit().putBoolean(VersionValue, false).commit();
}
You could do it this way and still get the same result I tried it its a small workaround if u do not fully understand how to check if the app is updated. Instead with this code you can just simply change the String VersoinValue to your current app version and android will think the app is a new first time app and will only display the code u wrote once until you change VersionValue on your next update. (:
How will you be storing the configuration?
If it is in SQLlite you could just create a table called firstuse and put a field in there called hasbeenused and make it null. Then when the app is used you can put a 1 in there. Then you can read it each time your app loads and if that field = 1 then go to your next activity.
I'm trying to port one of my iPhone apps over to the Android. It was all going along swimmingly until I came to AlertDialogs. In the iPhone app, sometimes there will be more than one alert to pass to the user. When this happens, the first alert dialog will come up, and when they click it away the next one will come up.
I can't seem to get more than one dialog box to come up like that in Android. Is it possible to display back to back AlertDialogs where a second one pops up as soon as the first is finished?
You execute 2 consecutive call to 'showDialog()' after eachother and the second will show after the 1st was dismissed:
showDialog(FIRST_DIALOG_ID);
showDialog(SECOND_DIALOG_ID);
Ofcourse you also have to implement onCreateDialog().
If you feel that you will be having multiple dialogs, one after another, you could create a custom class that holds all of the information for the alert, such as the title, text, icon, etc. From there, create an arraylist to store the custom class objects. When you are done with your first dialog, remove it from the arraylist, then check to see if there are any remaining dialogs that need to be presented.
The only issue you'll run into is that it will be much more difficult if you want to have different conditions in your Confirm and Cancel options.
public class DialogObject(){
String title;
String body;
String iconName; // or just an Image asset
}
ArrayList<DialogObject> dialogList = new ArrayList<>();
When a dialog is required, add it to the list if there is a dialog already on screen
dialogList.add(new DialogObject(param1, param2, param3));
This may not be the best way, but it is an option. The ArrayList will need to be in a separate class itself so you don't lose the data when moving from screen to screen.
For example - Note the "static" keyword.
public class DialogHolder(){
public static ArrayList<DialogObject> = new ArrayList<>();
}