I create an alert dialog that has a basic checkbox list in it when I press a button. If the items have been checked before, I want to be able to check the checkboxes for the user. I have accomplished this by manipulating "onPrepareDialog" like so:
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
Log.v("dialog", "On prepare dialog");
ListView lv = ((AlertDialog) dialog).getListView();
if (lv == null){
return;
}
String[] names = Utility.convertStringToArr(currentTravelers, ", ");
for(int i = 0;i < lv.getChildCount();i++){
for(int j = 0;j< names.length;j++){
String tn = lv.getItemAtPosition(i).toString();
if(tn.equalsIgnoreCase(names[j])){
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
lv.setItemChecked(i, true);
}
}
}
}
This works fine, EXCEPT for the very first time I select the button. It will just show me the checklist with nothing selected. If I cancel out and hit it again, I will then see the correct names checked. I've tried tracing out the ListView child count, and it comes up as 0 the first time.
Is there anyway around this so that the very first time the alert dialog comes up it actually populates the listview so I can check the correct names?
Is there something I am not overriding or adapting? I am at a loss here.
Thanks!
Well I was able to get around this by putting a post delay before it populates the listview:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() { //code to manipulate goes here
}}, 100);
This basically makes it wait 100 milliseconds, which seems to be enough time for the dialog information to load into the listview. Does anyone know a more efficient way of doing this?
Related
I want to display three ListView in loop one by one, with different data after 30 sec interval change to next list view and auto scroll in each and every list view.
Any help regarding this would be really appriciated!
You firstly need to loop statement in which you'll loop through the handler. Then you'll set a delay using the handler (note I've set the delay for 30000ms which is equivalent to 30 seconds; therefore, adjust the figure to your requirement).
for (int i = 0; i < 3; i++) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(i == 0){
//This will be the first loop
}else if(i == 1){
//This will be your second loop
} else{
//This will be the third and final loop
}
}, 30000);
}
You should write a method to set your listview and trigger that method within the run() function. But you can customize that functionality based on your own requirements/how you best understand it. Additionally, because you are going to use different parameters for the listview, you'll have to go through if statements to determine at which part of the loop you are as this will determine which listview is going to be set now.
For multiple view types you can use RecyclerView with multiple view types.
Recycler view has more uses over ListView.
Please check example https://www.journaldev.com/12372/android-recyclerview-example
I'm having some trouble with the logic behind storing an ImageView into an ArrayList.
The application I'm developing keeps track of player statuses in a game. The user first adds Player objects (which keeps track of a status string and a status image to go with it) to an ArrayList (to keep track of them all). Then, after submitting all of the players, a screen pops up inflating a TableRow for each player, containing a button (to view the Player's profile), an ImageView (an icon representing the status), and a TextView (containing the player's status string value).
I don't have a problem with the buttons and loading each player's profile. The problem occurs with loading the "select status" GUI from dialog_select_icon.xml, particularly the ImageView ArrayList. I get a NullPointerException, which doesn't make sense to me because I'm doing it essentially the same way as I did the buttons.
//this code runs when user clicks a player's status icon
public void playerStatusIconClicked(View v)
{
//loop through buttons to determine which player's button was clicked
for (int i = 0; i < playerList.size(); i++)
{
if (v.getId() == playerStatusIVList.get(i).getId())
{
calledPlayer = i; //instance variable
loadStatusIconGUI();
}//if
}//for
}//method playerStatusIconClicked
//showStatusIconGUI inflates the "select status icon" GUI
//and handles the user selecting an icon
private void loadStatusIconGUI()
{
//inflate the GUI for the showStatusIcon dialog (inflater is an instance variable)
View view = inflater.inflate(R.layout.dialog_select_icon, null);
//if the list has something in it, start from fresh
if (!selectStatusIVList.isEmpty())
{
selectStatusIVList.clear();
}
//list of icons in the "select status icon" dialog
selectStatusIVList.add((ImageView) statusIconGUI.findViewById(R.id.statusIV0));
selectStatusIVList.add((ImageView) statusIconGUI.findViewById(R.id.statusIV1));
selectStatusIVList.add((ImageView) statusIconGUI.findViewById(R.id.statusIV2));
selectStatusIVList.add((ImageView) statusIconGUI.findViewById(R.id.statusIV3));
selectStatusIVList.add((ImageView) statusIconGUI.findViewById(R.id.statusIV4));
selectStatusIVList.add((ImageView) statusIconGUI.findViewById(R.id.statusIV5));
selectStatusIVList.add((ImageView) statusIconGUI.findViewById(R.id.statusIV6));
//create a dialog so user can select an icon
AlertDialog.Builder selectIconDialog = new AlertDialog.Builder(this);
selectIconDialog.setView(view); //set the Dialog's custom view
selectIconDialog.setTitle(R.string.title_select_icon);
selectIconDialog.setNegativeButton(R.string.close, null);
selectIconDialog.show();
}//showStatusIconGUI
//Handle clicks in the "select status icon" dialog
//Assigns a new status to the player
public void statusIconClicked(View v)
{
Toast message;
for (int i = 0; i < selectStatusIVList.size(); i++)
{
if (v.getId() == selectStatusIVList.get(i).getId())
{
message = Toast.makeText(
MafiaTracker.this, "new status: " statusID[i], Toast.LENGTH_SHORT);
message.show();
playerList.get(calledPlayer).setImage(imageID[i]);
playerList.get(calledPlayer).setStatus(statusID[i]);
}
}
updateViewPlayerGUI();
}
Note that imageID[i] and statusID[i] are referring to int arrays containing the IDs for each status string and status image.
I can post the xml file but since it's 124 lines long I'd prefer not to. Just know that each ImageView in the xml file DOES have an ID, so I can't figure out why I'm getting these NullPointerExceptions, starting with the "if (!selectStatusIVList.isEmpty())" part, and continuing on with every other call after.
Please help!
statusIconGUI seems to be the main layout xml you used in setContenView().
Consider the line :
selectStatusIVList.add((ImageView) statusIconGUI.findViewById(R.id.statusIV0));
you are using findViewbyID on statusIconGUI. Do that instead on the view instance of R.layout.dialog_select_icon which you inflated.
so, change the above line to :
selectStatusIVList.add((ImageView) view.findViewById(R.id.statusIV0));
Initially selectStatusIVList is null. In loadStatusIconGUI check it for null
if(selectStatusIVList != null){
if (!selectStatusIVList.isEmpty())
{
selectStatusIVList.clear();
}
}else{
selectStatusIVList = new ArrrayList<Integer>();
}
I have a button on an activity which when pressed loops through a list of items, adds them to a database and then closes the activity.
My problem is that sometimes on slow phones and a lot of list items the user can press the button again before the activity closes, causing a duplicate insertion.
What is the recommended way of stopping this from happening, I've tried disabling the button on press but it does not get refreshed on the screen.
buttonAddChecked.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
SparseBooleanArray CheckedItemIDs = listViewFavorites.getCheckedItemPositions();
for (int i = 0; i < CheckedItemIDs.size(); i++) {
View element = listViewFavorites.getAdapter().getView(CheckedItemIDs.keyAt(i),
null, null);
ShoppingListItem sli;
sli = (ShoppingListItem) element.getTag();
db.insertItem(sli.itemName, 0, sli.itemNotes,
sli.categoryID);
} // looped round all checked items
finish();
}
});
use progressDialog
to stop user interaction once it presses the button.
I have a simple calculator that has six EditText views where users will enter numbers to perform a simple math function. This app will satisfy a repetitive task wherein the users will enter the information, press the submit button and the answer is displayed in a separate textView.
I want to add a simple 'clear' button that will reset the form so the users can begin a new calculation and the EditText views will show their hints for user input once again.
Is there a 'reset' type function that will clear all of the form data and reload the hints or do I have to kill the app and start it again? If so, whats a good starting place for how to do this?
Thanks!
The most basic way to do this would be to simply reset your EditText views. If you have logic that drives the update of these fields, then resetting them to an empty String and requesting a "recalculation" to update the hints.
Something like this:
private void onClear()
{
EditText firstField = (EditText)this.findById(R.id.firstField);
EditText secondField = (EditText)this.findById(R.id.secondField);
//...etc...
if (firstField != null) firstField.setText("");
if (secondField != null) secondField.setText("");
updateHints();
}
private void updateHints()
{
//Logic for your "hints"
}
No, you have to implement it yourself. I suggest you create an int array with the IDs of all your EditTexts you want to reset (R.id.xyz). Then create a loop to .setText() to each of the EditTexts from the array, which you can call every time you want the fields to be cleared. Something like:
private void resetFields() {
EditText temp;
for (int i = 0; i < myEditTexts.length; i++) {
temp = (EditText) findViewById(textViews[i]);
temp.setText("");
}
}
My answer is just a better way but it still a kind of hard code. Anyone could find another way faster, please share.
protected void clearForm() {
Button btnClear = (Button) findViewById(R.id.btn_clear_text);
btnClear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText temp;
final int[] txtId = new int[] {
R.id.txt_s_free_word,
R.id.txt_s_property_name,
R.id.txt_s_ad_expense_from,
R.id.txt_s_ad_expense_to,
R.id.txt_s_station
};
for (int i = 0; i < txtId.length; i++) {
temp = (EditText) findViewById(txtId[i]);
temp.setText(null);
}
}
});
}
A fairly normal scenario: an Android application has a preferences activity, and selecting an option from a ListPreference triggers code to change that ListPreference's summary text. ie: Selecting "Green" from a color ListPreference would change the ListPreference's summary text to "Green" through a onPreferenceChange callback.
I'd like to be able to use the Android JUnit testing to confirm that these summary changes are all being performed correctly. However, there seems to be very little information out there on how to do this.
I've tried variations of using setValue() on ListPreference, both in the test thread and through runOnUiThread(), with no success - this doesn't trigger the call to onPreferenceChange(). I've also tried getInstrumentation().waitForIdleSync() after calling setValue(), but that's also with no success.
So, my question is: how is this done?
Thanks!
A few more hours of work produced this working solution, but I'm curious if anyone else has a better solution. This code was inspired by this solution to a similar question, but this case is different in two ways:
It's intended for use by Android JUnit, which means it needs to call the ListPreference UI clicks via runOnUiThread().
It expects there to be preference categories in use, which complicate finding the position (relative to the entire preferences list) to click. The above mentioned solution only works in cases without preference categories.
This method will accept the key for a particular ListPreference item, along with the position of the item in the list to be clicked. It will then perform that list item click, and other code would do the checking I'm looking for.
Note that this requires setActivityInitialTouchMode(true); to be set before the getActivity() call in the setUp() method.
private void clickListPreference(String _listPreferenceKey, int _listItemPos){
final String listPreferenceKey = _listPreferenceKey;
final int listItemPos = _listItemPos;
mActivity.runOnUiThread(
new Runnable() {
public void run() {
// get a handle to the particular ListPreference
ListPreference listPreference= (ListPreference) mActivity.findPreference(listPreferenceKey);
// bring up the dialog box
mActivity.getPreferenceScreen().onItemClick( null, null, getPreferencePosition(), 0 );
// click the requested item
AlertDialog listDialog = (AlertDialog) listPreference.getDialog();
ListView listView = listDialog.getListView();
listView.performItemClick(listView, listItemPos, 0);
}
/***
* Finding a ListPreference is difficult when Preference Categories are involved,
* as the category header itself counts as a position in the preferences screen
* list.
*
* This method iterates over the preference items inside preference categories
* to find the ListPreference that is wanted.
*
* #return The position of the ListPreference relative to the entire preferences screen list
*/
private int getPreferencePosition(){
int counter = 0;
PreferenceScreen screen = mActivity.getPreferenceScreen();
// loop over categories
for (int i = 0; i < screen.getPreferenceCount(); i++){
PreferenceCategory cat = (PreferenceCategory) screen.getPreference(i);
counter++;
// loop over category items
for (int j = 0; j < cat.getPreferenceCount(); j++){
if (cat.getPreference(j).getKey().contentEquals(listPreferenceKey)){
return counter;
}
counter++;
}
}
return 0; // did not match
}
}
);
getInstrumentation().waitForIdleSync();
}