I have a small random number spinner that when you click gives a random number. I am having two problems. The first is when the main activity loads it displays a random number on the screen without the random number spinner being clicked. I am unsure what to set to false to keep it from opening with the main activity. The second problem is that when you select an option from the spinner it does not clear. Meaning that If you click on option D6 or D20 then you can not click on the same option again until selecting the other option first. Essentially the selection does not clear out of memory after the random number is selected. Here is the random number code
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
Random rand = new Random();
int roll = 0;
boolean firstRun = false;
// An item was selected.
if (!firstRun)
{
if (spinner1.getSelectedItemPosition()==0)
{
roll = rand.nextInt(6)+1;
}
else
{
roll = rand.nextInt(20)+1;
}
}
else
{ firstRun = false; }
// Put the result into a string.
String text = "You rolled a " + roll;
// Build a dialog box and with the result string and a single button
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(text).setCancelable(false)
.setPositiveButton("OK", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id)
{
// do things when the user clicks ok.
}
});
AlertDialog alert = builder.create();
// Show the dialog box.
alert.show();
}
...when the main activity loads it displays a random number on the screen without the random number spinner being clicked.
This is because onItemSelected() is called when the Activity is first created. To avoid running this code simply create a member variable (declared outside of a method, preferably before onCreate() for readability) like a boolean. And check that. For example
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id)
{
if (!firstRun) // where firstRun is the boolean variable you create
// and set to true
{
// run your code
}
else
{ firstRun = false; }
}
The second problem is that when you select an option from the spinner it does not clear.
I'm not exactly sure what you mean by this but you could set an empty value ("") for your first position then after each call to onItemSelected() call setSelection(0)
Related
I'm developing an application that allows user to add his own word, it's category. I start with a spinner that has the words available before in sqlite db and Add new word. When he clicks on Add new word, the spinner changes into EditText box that allows him to enter a new word. Whenever I try to save the text written in Edittext to string it shows that string is defined as "Add new word" and not the value entered by the user. What should I do?
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(parent.getId()==R.id.spinword)
{
editword=parent.getItemAtPosition(position).toString();
if(editword.equals("Add new word"))
{
spinwrd.setVisibility(spinwrd.INVISIBLE);
edtwrd.setVisibility(edtwrd.VISIBLE);
flag = 1;
}
if(flag == 1)
{
editword.replace(editword,edtcat.getText().toString());
}
}
if(parent.getId() == R.id.spincat) {
editcategory = parent.getItemAtPosition(position).toString();
if (editcategory.equals("Add new category")) {
spincat.setVisibility(spincat.INVISIBLE);
edtcat.setVisibility(edtcat.VISIBLE);
editcategory = edtcat.getText().toString();
}
}
}
I tried equals method and replace method but in vain.
Not sure of what you want to do but i think you should try changing
editword.replace(editword,edtcat.getText().toString()
for
editword.replace(editword,edtwrd.getText().toString())
The answer to this question is as follows: First, replacing, clearing, or any change depends on the position of the line meaning that: In the code above, I was trying to capture the text written by the user but at that point of execution when user chooses "Add new word" the text becomes it. The solution to this problem is to place the line of code editword.replace(editword,edtcat.getText().toString()); when this function is finished to be sure that the user has entered some text.
I've created an AccessibilityService in Android where I want to display an AlertDialog after focusing on an EditText on the page (Note: The EditText could be from another app, like a login screen, so I won't always know the ID). When you click on a 'confirm' button within the AlertDialog it populates that EditText with text.
I have all of the steps complete except for the last part...I cannot figure out how to populate the EditText with text. I'm guessing there is a way to cast a findViewByID() method somewhere, but I don't know how to find the ID of the EditText (see above, the EditText could be from another app). See code below, am I way off? The code below always errors out telling me about a sealed instance problem (Cannot perform this action on a not sealed instance.).
public void onAccessibilityEvent(final AccessibilityEvent event) {
final AccessibilityNodeInfo source = event.getSource();
if ((event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED || event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) && CLASS_NAME_EDIT_TEXT.equals(event.getClassName())) {
AlertDialog.Builder mSuspendDialog = new AlertDialog.Builder(getApplicationContext())
.setTitle(R.string.str_have_password_question)
.setPositiveButton(R.string.str_decision_use_password, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (event.getSource() != null & event.getClassName().equals("android.widget.EditView")) {
Bundle arguments = new Bundle();
arguments.putCharSequence(AccessibilityNodeInfo
.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "newtexttopopulateedittext");
event.getSource().performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
}
}
})
.setNegativeButton(R.string.str_decision_close, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
AlertDialog alert11 = mSuspendDialog.create();
// Ensure we can show the dialog from this service.
alert11.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alert11.show();
1) When any activity starts, create a List(or whatever) of ID's of all the EditText's on the screen.
2) While creating a list (or later on) iterate through the list again and check if a value is available for that view in your SQLite database.
3) If a value is available, use ACTION_PASTE to inject text in that EditText.
ArrayList<AccessibilityNodeInfo> inputViewsList = new ArrayList<AccessibilityNodeInfo>();
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
refreshChildViewsList(rootNode);
for(AccessibilityNodeInfo mNode : inputViewsList){
String viewId = mNode.getViewIdResourceName();
Cursor cr = db.rawQuery(-----your database parameters----);
if(cr.moveToFirst()){
//this means you have a value for that ET
ClipboardManager clipboardManager = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
ClipData clipData =ClipData.newPlainText("MyAppName", cr.getString(--Your column number--));
clipboardManager.setPrimaryClip(clipData);
mNode.performAction(AccessibilityNodeInfo.ACTION_PASTE);
}
}
Database has to be used so that you can remember the values permanently. The ID which i'm getting above is a fully qualified ID with App package name and view ID. So, it remains unique system-wide.
Now about refreshChildViews() method:
private void refreshChildViews(AccessibilityNodeInfo rootNode){
int childCount = rootNode.getChildCount();
for(int i=0; i<childCount ; i++){
AccessibilityNodeInfo tmpNode = rootNode.getChildAt(i);
int subChildCount = tmpNode.getChildCount();
if(subChildCount==0){
if(tmpNode.getClassName().toString().contentEquals("android.widget.EditText"){
inputViewsList.add(tmpNode);
}
return;
}
if(subChildCount>0){
refreshChildViews(tmpNode);
}
}
}
Don't forget to clear the inputViewsList on TYPE_WINDOW_STATE_CHANGED event!
Let me know if you need anything else.
Hi there. I dont know what is happening. I am trying to change the text of an EditText when creating a DialogFragment, but the EditText is not updating the text.
If I call getText().length() I notice that the content of the EditText changed. But, the visual keeps the same, just empty.
Why?
Thanks in advance people
Here is the code:
public class ItemNameDialog extends DialogFragment {
#Override
public Dialog onCreateDialog(final Bundle bundle) {
System.out.println("ON CREATE DIALOG WAS CALLED"); //This appears on LogCat, so this method is called.. the problem is not that
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Configure an item to count:");
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.itempick_layout, null);
builder.setView(view);
final CheckBox box = (CheckBox) view.findViewById(R.id.itemSenseCheckBox);
final EditText itemNameBox = (EditText) view.findViewById(R.id.itemNameText);
final Spinner spinner = (Spinner) view.findViewById(R.id.itemsDefault);
final int viewIDClicked = getArguments().getInt(clickableViewID);
final String actualName = getArguments().getString(actualNameItemView);
System.out.println("H - before: " + itemNameBox.getText().toString().length()); //it appears on logcat "H - before: 0"
itemNameBox.setText(actualName);
System.out.println("H - after: " + itemNameBox.getText().toString().length()); //it appears on logcat "H - before: 3" so why not changing ?
return builder.create();
}
}
My problem was that below that code, and before the method onCreateDialog ends, I had a few methods controlling a spinner.
The first item of that spinner has the purpose of "select nothing" and in that item choice I was just erasing the content of that edit text, like this:
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
if(pos == 0){
if(editText.length() != 0 )
editText.setText("");
}
And I didnt know that while creating the spinner, it does trigger the event "onItemSelected" and because of that, the edittext was everytime erased, even when I didnt click on that item of the spinner..
So I managed to overcome this by a simple boolean.
Every time the method onCreateDialog I put the boolean to true, and then my onItemSelected just operate when that bolean is false. Like the code below:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if(firstGoingSpinner){
firstGoingSpinner = false;
}else{
if(pos == 0){
if(editText.length() != 0 )
editText.setText("");
}else{
editText.setText(""+parent.getItemAtPosition(pos));
Editable etext = editText.getText();
Selection.setSelection(etext, editText.length());
}
}
}
I hope this helps someone in the future ;)
I am having trouble with a ListView based on a MatrixCursor resetting values on keyboard minimize and orientation change.
The matrix cursor is filled with data from a SQL database. This is done because I want the original database columns to be rows in the listview:
public void fillList(boolean rewrite, int rewrite pos, int) {
myCols = getColArray();
SQLiteDatabase myDB = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY);
myCursor = myDB.query("Scoring", statCols, null, null, null, null, null);
String[] menuCols = new String[] { "_id","Item","Value"};
int []to = new int[]{R.id.listitem, R.id.listitem_value};
mc = new MatrixCursor(menuCols);
for (int i = 0; i < (mChoices.size()); i++) {
statCursor.moveToPosition(draftId);
String item = mChoices.get(i);
String valueString = "";
int valueCol = statCursor.getColumnIndex(item);
int value = statCursor.getInt(valueCol);
valueString = (String.valueOf(value));
mc.addRow(new Object[] {
i,
item,
valueString
});
}
This fillList() method is called in my onCreate. This cursor is then used to populate the ListView by extending SimpleCursorAdapter. My goal for the fragement is to allow the user to click on one of the list items, causing Dialog with an EditText line to appear:
#Override
public void onListItemClick(ListView l, final View v, int position, long id) {
final TextView valueL = (TextView) v.findViewById(R.id.listitem_value);
String valueString = (String) valueL.getText();
int value = 100;
try {
value = Integer.parseInt(valueString);
} catch(NumberFormatException nfe) {
}
//Create dialog layout
View view = getActivity().getLayoutInflater().inflate(R.layout.numberpick_popup, null);
final EditText mInputText = (EditText) view.findViewById(R.id.myText);
//Create Dialog
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
builder.setTitle(title);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
valueL.setText(mInputText.getText().toString());
return;
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
});
builder.setView (view);
final AlertDialog dialog = builder.create ();
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
dialog.show();
}
The problem I am having is when the fragment layout regenerates on keyboard hidden or orientation change, causing fillData to be called and overwriting any of the values I had updated in the list. This happens if I choose OK on the dialog without first minimizing the keyboard, or on any orientation change.
My thinking is that there should be some way to overwrite the values in the MatrixCursor when new data is entered from the dialog. However I don't know if this is possible or if the cursor would even survive the state changes.
Any help would be greatly appreciated.
I worked around this by creating a HashMap of key value pairs in my list adaptor and adding the changed values there. So in bindView() I would check if the key existed there for the row being initialized and if so then use those values instead of from the cursor.
I simply did
HashMap<Long,String>
since I only needed one value that could change but you could easily create a custom class and make yours
HashMap<Long,CustomClass>
so you could change lots of values.
So when changing the values initially just remember to update that HashMap with the new values so on redraw of your List the correct values are shown. This works well because by nature a MatrixCursor alone is usually pretty small. This wouldn't be smart on a really large list because the HashMap would grow out of control and take up too much memory. Let me know if you have any questions.
I am currently using the AlertDialog.builder to create a multichoice list for the user (checkboxes). This works great, except we want one of the buttons to deselect all of the others in the list.
builder.setMultiChoiceItems(list, checked,
new DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog,
int item, boolean isChecked) {
if(item == ANY_ITEM_BUT_0)
{
((AlertDialog) dialog).getListView().setItemChecked(0, false);
}
}
});
When using "true" it will successfully check the box, but when using false it does not uncheck it (unless i have manually set it to true before hand.) Is there a separate listener I should be using to detect when a user clicks these? It seems to me that there are two checkmarks set, one by the "setItemChecked(0, true);", and one by actually selecting it.
This has been driving me nuts for a couple days now, any help would be greatly appreciated.
OH!!! I forget it to ensure deselect you must change checked to null ;), I had the same issue.
builder.setMultiChoiceItems(list, null, new DialogInterface.OnMultiChoiceClickListener() {
...
To deselect the other items it works fine::
if(item == ANY_ITEM_BUT_0){
for(int i=0; i<items.length;i++){
if (item != ANY_ITEM_BUT_0)
((AlertDialog)dialog).getListView().setItemChecked(i, false);
}
}
Dont think you can change the values in the list since the list-items (checkboxes) are controlled by the builder-object. However, you could simply make the dialog re-initiate when the first item is clicked... by dismissing the dialog that is showing, and create a new one....
If you want to set a check box to not be checked and you need to set the checkedItems array on the call to setMultiChoiceItems(), you need to set the checked array items to false as well. Make sure your checked array is final so you can access it in the listener.
builder.setMultiChoiceItems(list, checked,
new DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog,
int item, boolean isChecked) {
if(isChecked && item == ANY_ITEM_BUT_0)
{
for(int i=0; i<list.length;i++){
if (i != ANY_ITEM_BUT_0) {
checked[i] = false;
((AlertDialog)dialog).getListView().setItemChecked(i, false);
}
}
}
}
});