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 ;)
Related
I'm facing a problem. Not sure what to call it, or what causes it
I'm learning Android SQLite and to train started making a simple note app.
The problem is I have a custom dialog for category select, before opening the dialog everything is fine in the EditText field, but after opening, and closing it the text starts writing over, like creating multiple layers of the same text and the text cursor leaves a line after every symbol. (See "bug demo" GIF of the problem)
Has anyone else seen something like this? What could be causing this, the dialog?
Edit:
So this is the code that takes action when clicking on the star to open the dialog
starred.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(CreateNoteActivity.this);
View mView = getLayoutInflater().inflate(R.layout.dialog_category_select, null);
ListView categoryList = mView.findViewById(R.id.category_list);
Button cancelSelect = mView.findViewById(R.id.cancelSelect);
final CategoryListAdapter adapter = new CategoryListAdapter(CreateNoteActivity.this);
categoryList.setAdapter(adapter);
//get the data and append to a list
Cursor data = myDB.getCategories();
while(data.moveToNext()){
Category thisNote = new Category(data.getInt(0), data.getString(1), data.getString(2));
adapter.add(thisNote);
}
categoryList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, final int i, long l) {
final Category selectedCategory = (Category) adapterView.getItemAtPosition(i);
int duration = Toast.LENGTH_SHORT;
String s = "Category celected: "+selectedCategory.getCategoryName();
Toast toast = Toast.makeText(context, s, duration);
toast.show();
}
});
builder.setView(mView);
final AlertDialog selectCategory = builder.create();
selectCategory.getWindow().setBackgroundDrawable(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
selectCategory.show();
View decorView = getWindow().getDecorView();
decorView.setBackgroundResource(android.R.color.transparent);
int width = (int)(getResources().getDisplayMetrics().widthPixels*0.80);
int height = (int)(getResources().getDisplayMetrics().heightPixels*0.80);
selectCategory.getWindow().setLayout(width, height);
cancelSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectCategory.dismiss();
}
});
}
});
This answer might help you
Write this after the dialog close
ediText = findViewById(R.id.edit_text);
editText.setSelection(editText.getText().length);
Basically using the above logic, the cursor won't be pointed at the first character of the editText on the dialog close
Noticed that I was trying to set a transparent background to display my custom dialog bcg two times.
So what fixed the problem was removing two lines
*View decorView = getWindow().getDecorView();
decorView.setBackgroundResource(android.R.color.transparent);*
Not sure why it was causing this. Should check what is getDecorView() method. Used it cause found it as a solution to show the custom background.
This line works as well
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
Guess this was a case of rubber duck debugging - just had to tell someone about the problem to fix it. Thanks everyone.
Try this code when you dismiss or close the dialog,
edittext.setSelection(editText.getText().toString().trim().length);
I have 85 settings items that I need to display on a view. I cannot use a RecyclerView or a ListView because EditTexts are horrible. Doing the way I am doing causes a huge slow down. I do not want to make these manually. Any help is appreciated.
Relevant code:
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
LinearLayout ll = (LinearLayout) view.findViewById(R.id.ssm_ll);
List<Category> AllCats = (List<Category>) getArguments().getSerializable("Category");
temp = new LinearLayout(getActivity());
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
new Thread(new Runnable() {
public void run() {
for (Category cg : AllCats) {
LinearLayout tv = (LinearLayout) inflater.inflate(R.layout.scoring_setting_template, null);
TextView Catwording = (TextView) tv.findViewById(R.id.sst_catwording);
Catwording.setText("" + cg.getCatWording());
temp.addView(tv);
}
}
}).run();
temp.addView(temp);
ll.addView(temp);
}
Too Long for Comment, Not Sure if it Works, Just a Suggestion to Try
I haven't tested this at all, but it was too long to suggest trying in a comment. If it doesn't work let me know and I will delete this as a possible answer (please keep from your negative votes again I am not certain of this as an answer).
Since an Adapter in a ListView is supposed to handle creating the next view that isn't seen, which allows smooth scrolling, you could possibly still manage this in a ListView (theoretically). You could programmatically set the id and handle the the next call like so within your Adapter's getView() :
editText.setId(position + 1); // + 1 so your id is never 0
if(position < getCount() - 1)
editText.setNextFocusDown(position + 2); // the id of the next edit text
else
editText.setImeOptions(EditorInfo.IME_ACTION.DONE);
Theoretically, your ListView will always have built the next item in the list's view unless it is the last item in the list (which you can then set the ime options to done), not 100% on that though. Again, I am not sure if this works but it is obviously too much for a comment.
while I am making a post
For the content of each EditText you could do something like
private SparseArray<String> mEditTextInputs = new SparseArrayt<>();
then in getView(), make position parameter final and try
editText.setText(mEditTextInputs.get(position);
editText.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable s){}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){
mEditTextInputs.put(position, s.toString());
}
}
This is not the best idea, but in order to do what you ask create a Layout and Populate a ScrollView with EditText so when you select next on keyboard it goes down one EditText:
Here is an example:
https://gist.github.com/lt-tibs1984/5d3e6a50f9d883026014
to go even further each time you do:
int count = 0;
for (String item : items) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.list_item, null);
EditText editText = (EditText)view.findViewById(R.id.editTextDemo);
editText.setText(item);
// set a tag here to uniquely identify it later
editText.setTag(count);
mLinearLayout.addView(view);
count++;
}
Alternative loop:
for (int i = 0 ; i < 25; i++) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.list_item, null);
EditText editText = (EditText)view.findViewById(R.id.editTextDemo);
editText.setText(items.get(i));
// set a tag here to uniquely identify it later
editText.setTag(i);
mLinearLayout.addView(view);
}
UPDATE
This project is no longer maintained today, but solutions are most welcomed.
Thanks.
I am creating an automation test project in which I have issue to select the item from the AutoCompleteTextView.
You can see the snap and the views[all expanded] it has. The dropdown of the AutoCompleteTextView does not appear in view tree nor I am able to select using mouse.
I have tried below approaches to select the item form from the AutoCompleteTextView adapter:
UiScrollable locationList = new UiScrollable(new UiSelector().scrollable(true)); locationList.scrollTextIntoView(location);
UiScrollable locationList = new UiScrollable(locationEditText.getSelector()); locationList.scrollTextIntoView(location); Here locationEditText is my AutoCompleteTextView
UiObject selectedLocation = locationList.getChild(new UiSelector().text(location)); selectedLocation.click(); from the locationList it does not select the item with the string passed.
editLocationResId = "android:id/text1"; UiObject selectedLocation = new UiObject(new UiSelector().resourceId(editLocationResId)); selectedLocation.click(); The id from the adpter textview does not work either.
Can anybody help me with selecting the item from the AutoCompleteTextView in uiautomator? Or the more approaches get the desire output.
Get the cordinates of text field :
int x = element.getLocation().getX();
int y = elmement.getLocation().getY();
Add values to get the right cordinates.
x = x+x1
y = y+y1
Use tap function to click on it.
TouchAction action = new TouchAction(driver);
action.tap(x,y).perform();
first open the pick-up list, then try to use UiDevice.pressKey(), to send a DPAD_DOWN OR UP event and press Enter to select the item you want.
If you need to press the first element from the dropdown list, I have found a useful workaround:
public void selectFirstElement() {
TouchAction touchAction = new TouchAction(getAppiumDriver());
int xTapped = autoCompleteTextView.getLocation().getX() + autoCompleteTextView.getSize().getWidth() / 2;
int yTapped = autoCompleteTextView.getLocation().getY() + autoCompleteTextView.getSize().getHeight() ;
touchAction.tap(xTapped, yTapped).perform(); }
Given an AutoCompleteTextView declared as autoCompleteTextView, you can get the current location on the screen and calculate the item which is gonna be located below it. Hope it helps!
Well, i found a turn around(this is for autocompletetextview, for spinner delete setText()):
UiObject edit = mDevice.findObject(new UiSelector().className(EditText.class).instance(0));
edit.click();
edit.setText(name);
Rect rect = edit.getBounds();
mDevice.waitForWindowUpdate(Package.DIGI_PACKAGE, 1000);
mDevice.click(rect.left + 64, rect.bottom + 72);
Get object, click it, insert text that you want,wait for dropdown to appear then click under it with some pixels
I had created and have been using the simplest and the most efficient way. Just locate, type and then select the desired value in autocomplete text view.
Hope it will work for you as well.
driver.findElement(By.id(“Element ID”)).clear();
driver.findElement(By.id(“Element ID”)).sendKeys("Type what you want to select");
driver.pressKeyCode(AndroidKeyCode.KEYCODE_PAGE_DOWN);
driver.pressKeyCode(AndroidKeyCode.ENTER);
You can find the element that you want to select using its text. Make sure that this line of code is executed after the suggestion list has been shown.
//Get a reference to the autocomplete element
UiObject2 autocomplete = device.findObject(By.res("yourpackage","autocomplete_id"));
//Put a text that will trigger the suggestion list
autocomplete.setText("68623 Lampertheim");
//Gain the focus
autocomplete.click();
//Finally, find the element that we want in the suggestion list and click it
device.findObject(By.text("68623 Lampertheim")).click();
Hope it helps.
try the code below it worked for me.
I am using the the AutoCompleteText to auto complete the location where the user is currently in, the locationList is nothing but an array that i wrote in the strings.xml file, so use your own string array here.
locationList = res.getStringArray(R.array.ticketLocation);
ArrayAdapter<String> locationAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, locationList);
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.txtCountries);
textView.setThreshold(1);
textView.setAdapter(locationAdapter);
textView.setValidator(new Validator());
textView.setOnFocusChangeListener(new FocusListener());
textView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
TextView ticketLocation = (TextView) view;
getTicketLocation = ticketLocation.getText().toString();
}
});
and below is the code for validating the text input in the location field, the fixText() method prevent the user from typing text that does not exist in your string array, for instance: if the user type "germany" which does not exist in your string array list, it will be replaced by " " which is an empty string inside your edittext input field
class Validator implements AutoCompleteTextView.Validator {
#Override
public boolean isValid(CharSequence text) {
// Log.v("Test", "Checking if valid: " + text);
Arrays.sort(locationList);
if (Arrays.binarySearch(locationList, text.toString()) > 0) {
return true;
}
return false;
}
#Override
public CharSequence fixText(CharSequence invalidText) {
// Log.v("Test", "Returning fixed text");
/*
* I'm just returning an empty string here, so the field will be
* blanked, but you could put any kind of action here, like popping
* up a dialog?
*
* Whatever value you return here must be in the list of valid
* words.
*/
return "";
}
}
class FocusListener implements View.OnFocusChangeListener {
#Override
public void onFocusChange(View v, boolean hasFocus) {
// Log.v("Test", "Focus changed");
if (v.getId() == R.id.txtCountries && !hasFocus) {
// Log.v("Test", "Performing validation");
((AutoCompleteTextView) v).performValidation();
}
}
}
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)
listView=(ListView)findViewById(R.id.list);
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View viewItem, int position, long arg3) {
if(!itemClicked)
{
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.gov)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
itemClicked=true;
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
else
{
viewItem=parent.getChildAt(clickedItemPos);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.INVISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.INVISIBLE);
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
final int[] coordAndCat = FavoriteCoord(ime.toString());
Nullpointer exception happens when I have more elements and when you scroll and click the last item on the listview. How to workaround this?
Note: I'm trying to display 2 buttons in every item that is being clicked. This code works for all clicks on items besides the last one (if there are many elements in the list and you need to scroll)
clickedItemPos isn't defined after else unless clickedItemPos=position has been called earlier. What line does the error happen on?
listView=(ListView)findViewById(R.id.list);
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View viewItem, int position, long arg3) {
if(!itemClicked)
{
viewItem = parent.getChildAt(position);
//start >> This might be where your problem is (R.id.gov)
((Button)viewItem.findViewById(R.id.gov)).setVisibility(View.VISIBLE);
//end <<
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
itemClicked=true;
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
else
{
viewItem=parent.getChildAt(clickedItemPos);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.INVISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.INVISIBLE);
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
final int[] coordAndCat = FavoriteCoord(ime.toString());
I think you said R.id.gov instead of R.id.go unless R.id.gov is truly an id you have. That is the only thing I saw 'wrong', please show a stacktrace for the error next time, it would help in debugging =)
EDIT
is clickedItemPos initialized somewhere else? because if it isn't this line: viewItem=parent.getChildAt(clickedItemPos); in your else statement would probably be null if nothing was selected before. I understand you want to use this in order to check for previously clicked items, but if nothing was clicked before, this will never get set to a value and therefore be null try doing this in that else statement to avoid the possible null variable:
else
{
if(clickedItemPos != null){ //only add this if there was a previous clicked item
viewItem=parent.getChildAt(clickedItemPos);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.INVISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.INVISIBLE);
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}else{
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
}
hopefully that will fix it. In your stack trace it says line 91 in your class is the line causing the error, what variable is located on that line? that is usually a good indicator of what variable is causing the null pointer, but since we don't know the line numbers for your code it is hard to guess where the issue is.
Yes there is repeated code in that solution but you could always make a method to put the repeated code in and call that instead if you want.
Good Luck, hope this helps.