Xamarin - error message displayed in wrong position in RecyclerView - android

I have validate method inside my RecyclerView Adapter , this method made to validate row before add new row to my adapter , the issue I face when I edit in last row validation error appear in wrong position , I trace my adapter and I am sure it give right position
here is image for reference
my code I check if focused item is last item and validation is passed to add new row
private void CheckNewItemAddMethod(int position)
{
if (Validate(position) && position == ItemCount - 1)
{
transactionItemModelList.Add(new TransactionItemModel() { ItemID = -1 });
NotifyItemInserted(transactionItemModelList.Count - 1);
}
}
private bool Validate(int pos)
{
ItemCustomViewHolder Passedholder = FindViewHolderByPoistion(pos);
bool valid = true;
int x = 0;
if (! int.TryParse(Passedholder.itemCount.Text, out x) || x == 0){
valid = false;
}
int intItemPrice = 0;
if (string.IsNullOrEmpty(Passedholder.itemName.Text) || !int.TryParse(Passedholder.itemPrice.Text, out intItemPrice) || intItemPrice == 0)
{
valid = false;
Passedholder.itemName.SetError(mContext.GetString(Resource.String.empty_field), null);
}else
{
Passedholder.itemName.SetError((string)null, null);
}
if (string.IsNullOrEmpty(Passedholder.itemPrice.Text))
{
valid = false;
Passedholder.itemPrice.SetError(mContext.GetString(Resource.String.empty_field), null);
}
else
{
Passedholder.itemPrice.SetError((string)null, null);
}
return valid;
}
Note when I scroll it back to right view
any one can guide me why that happen

Related

Calling on click listener multiple times for updating text views?

In my activity i am showing user a question and 3 options to choose from, these options are text-views.
On clicking the text-view On click listener is performed which updates the text-views according to the option selected.
Now user again after reading the question performs on click listener on options. But this is working only twice then it stops clicking and updating.
Debug is not working either i am beginner so i am confused.
#Override
public void onClick(View v) {
int id = v.getId();
if(id == R.id.optionA) {
Answer = optionA;
LogAnswer = "a : " + optionA;
Log.w(TAG, LogAnswer);
conditions(questionnumber);
}
else if (id == R.id.optionB) {
Answer = optionB;
LogAnswer = "b : " + optionB;
Log.w(TAG, LogAnswer);
conditions(questionnumber);
}
else if (id == R.id.optionC) {
Answer = optionC;
LogAnswer = "c : " + optionC;
Log.w(TAG, LogAnswer);
conditions(questionnumber);
}
}
conditions method change text-views according to option.
public void conditions(int i){
if(Answer.equals(optionA) && i == 1 )
{
questionnumber = 2;
MartialStatus = Single;
GetQuestion(2);
}
else if(Answer.equals(optionB) && i == 1 )
{
questionnumber = 2;
GetQuestion(2);
}
}
It may be that my text-view onclicklistener is calling same text-view listener which breaks.

Check for Empty EditText fails

I've tried everything from matching strings, to using TextUtils.isEmpty. No matter what I do, b is always true (even when edittext is purposely left blank) which allows the code to proceed to the next steps (this is a Madlib app).
If anybody can see why the code isn't properly checking for blank edittext's and displaying the Please Fill In All Fields" toast when one is blank, it would be very appreciated. Thanks. Sorry for the messy code.
public class Madlibs extends Fragment {
switch (((MainActivity) getActivity()).getStory()) {
case 0:
output.setText(Stories[0]);
title = Titles[0];
actionBar.setTitle(title);
editTextNumber = 12;
addEdit = new BootstrapEditText[editTextNumber];
for (int i = 0; i < addEdit.length; i++) {
addEdit[i] = new BootstrapEditText(getActivity());
l_layout.addView(addEdit[i]);
params.setMargins(0, 20, 0, 20);
addEdit[i].setLayoutParams(params);
addEdit[i].setId(i);
}
addEdit[0].setHint("Name of Sickness");
addEdit[1].setHint("Adjective");
addEdit[2].setHint("Name of Boy");
addEdit[3].setHint("Body Part");
addEdit[4].setHint("Color");
addEdit[5].setHint("Animal");
addEdit[6].setHint("Article of Clothing");
addEdit[7].setHint("Relative");
addEdit[8].setHint("Adjective");
addEdit[9].setHint("Article of Clothing");
addEdit[10].setHint("Body Part");
addEdit[11].setHint("Number");
break;
case 1:
// fragment = new Madlibs();
break;
case 2:
// fragment = new MadlibsSaved();
}
convert = (BootstrapButton) view.findViewById(R.id.convert);
convert.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int i;
String s;
for (i = 0; i < addEdit.length; i++) {
s = addEdit[i].getText().toString().trim();
if (s.isEmpty() || s.length() == 0 || s.equals("") || s == null) {
b = false;
}
else
{
b = true;
}
}
if (b = true) {
gather();
postIt();
outputText = output.getText().toString();
} else {
Toast.makeText(getActivity().getApplicationContext(),
"Please Fill In All Fields", Toast.LENGTH_LONG)
.show();
}
}
});
Your problem is here
if (b = true) { // HERE
gather();
postIt();
outputText = output.getText().toString();
}
You are using b = true which sets b to true, and since you are able to do this successfully, the conditional evaluates to true every time. What you want instead is the comparison operator ==
if (b == true) {
gather();
postIt();
outputText = output.getText().toString();
}
or even better, since the variable you are comparing is a boolean, you could just use
if (b) {} //This is "if b is true..."
if (!b) {} //This is "if b is false..."
You can see another one of my answers about this here.
for (i = 0; i < addEdit.length; i++) {
s = addEdit[i].getText().toString().trim();
if (s.isEmpty() || s.length() == 0 || s.equals("") || s == null) {
b = false;
}
else {
b = true;
}
}
For Loop ends here and the following is outside the For Loop :
if (b = true) {
gather();
postIt();
outputText = output.getText().toString();
} else {
Toast.makeText(getActivity().getApplicationContext(),
"Please Fill In All Fields", Toast.LENGTH_LONG)
.show();
}
Problem 1 :
if(b == true) {
}
Problem 2 :
Now, suppose edittext 1 is empty, b is set to true but then it'll straightaway move ahead in the loop to edittext 2 to the last edittext which are not empty hence it'll set b to false again. You'll need to put the check inside the for loop.

EditText selection on focus not working

Since I am very disappointed in a way that Android is doing decimal input I decided to write my own EditDecimal control that inherits from EditText. I want it to select all on click and to put cursor on first position on focus. I don't want cursor to show because it's usless on most Android phones (you mostly cannot put it in right place and it makes me very nervous)
Problem is when you tap on control - FocusChanged is called but it does not set position of (hidden) cursor on first position but on position where user tapped. I can not find the problem... is there some other event that happens after FocusChange that moves cursor?
public class EditDecimal : EditText
{
// Every constructor is calling Initialize ...
private void Initialize()
{
FocusChange += OnFocusChanged;
Click += OnClicked;
SetCursorVisible(false);
}
private void OnFocusChanged(object sender, FocusChangeEventArgs e)
{
if (IsFocused)
SetSelection(1);
}
private void OnClicked(object sender, EventArgs e)
{
SelectAll();
}
}
I finnaly solved it. I had to subscribe to OnTouch event and to change cursor position from there.
public class EditDecimal : EditText
{
// Every constructor is calling Initialize ...
private InputMethodManager _imm ;
public int DecimalSpaces { get; set; }
readonly DecimalFormatSymbols _dfs = new DecimalFormatSymbols();
private void Initialize(Context context, IAttributeSet attrs)
{
AfterTextChanged += OnAfterTextChanged;
SetSelectAllOnFocus(true);
SetCursorVisible(false);
Touch += OnTouch;
_imm = (InputMethodManager)context.GetSystemService(Context.InputMethodService);
var a = context.ObtainStyledAttributes(attrs, Resource.Styleable.EditDecimal);
try
{
DecimalSpaces = a.GetInteger(Resource.Styleable.EditDecimal_decimalSpaces, 2);
}
finally
{
a.Recycle();
}
}
private void OnTouch(object sender, TouchEventArgs e)
{
base.OnTouchEvent(e.Event);
if (e.Event.Action == MotionEventActions.Up)
{
SelectAll();
}
}
protected override void OnFocusChanged(bool gainFocus, FocusSearchDirection direction, Rect previouslyFocusedRect)
{
base.OnFocusChanged(gainFocus, direction, previouslyFocusedRect);
SelectAll();
}
private void OnAfterTextChanged(object sender, AfterTextChangedEventArgs e)
{
const char ch1 = '.';
const char ch2 = ',';
switch (_dfs.DecimalSeparator)
{
case ch2:
{
if (Text.Contains(ch1.ToString()))
{
var position = Text.IndexOf(ch1);
if (Text.Contains(ch2.ToString()))
e.Editable.Delete(position, position + 1);
else
e.Editable.Replace(position, position + 1, ch2.ToString());
}
// we have to prevent showing two commas in number
var firstCommaPosition = Text.IndexOf(ch2);
var lastCommaPosition = Text.LastIndexOf(ch2);
if (firstCommaPosition > 0 && lastCommaPosition > 0 && firstCommaPosition != lastCommaPosition)
e.Editable.Delete(lastCommaPosition, lastCommaPosition+1);
}
break;
case ch1:
{
if (Text.Contains(ch2.ToString()))
{
var position = Text.IndexOf(ch2);
e.Editable.Delete(position, position + 1);
}
// we have to prevent showing two points in number
var firstPointPosition = Text.IndexOf(ch1);
var lastPointPosition = Text.LastIndexOf(ch1);
if (firstPointPosition > 0 && lastPointPosition > 0 && firstPointPosition != lastPointPosition)
e.Editable.Delete(lastPointPosition, lastPointPosition + 1);
}
break;
}
//thnx to http://stackoverflow.com/users/2240673/tom
var length = e.Editable.Length();
if (length <= 0) return;
if (NrOfDecimal(e.Editable.ToString()) > DecimalSpaces)
e.Editable.Delete(length - 1, length);
}
private int NrOfDecimal(string nr)
{
if (nr == null) return 0;
var nrCharArray = nr.ToCharArray();
var len = nr.Length;
var pos = len;
for (var i = 0; i < len; i++)
{
if (nrCharArray[i] != '.') continue;
pos = i + 1;
break;
}
return len - pos;
}
}
What came as suprize to me was a fact that EditText selection behaves differently if SetCursorVisible is set to true than when it is set to false. I thought that it was just visibility property.
Grepcode is your friend. It shows that TextView's onFocusChanged method checks if there's an Editor object defined for the View (which is the case with EditText) and a look at the Editor code shows this at line 889 ff:
// If a tap was used to give focus to that view, move cursor at tap position.
// Has to be done before onTakeFocus, which can be overloaded.
final int lastTapPosition = getLastTapPosition();
if (lastTapPosition >= 0) {
Selection.setSelection((Spannable) mTextView.getText(), lastTapPosition);
}
So perhaps the best way would be to write your own implementation of Editor. Although if have no idea right now how you attach that to your TextView resp. EditText. class.
Or you just set the selection back to the first position if that is what you want.

contains in HashSet<int[]>()

In android I'm trying to save grids that the user already have pressed.
Code snipping I’m using is:
// private
private HashSet<int[]> PlayerSelectedHashField = new HashSet<int[]>();
private boolean collisionDetected = false;
In a function I’m using
collisionDetected = PlayerSelectedHashField.contains(TmpPos); // -> Fail - not working
{doing something}
PlayerSelectedHashField.add(TmpPos); // int[] TmpPos - TmpPos is x y
The .add function is working as expected, but .contains always return false.
Why does it not working - and what can I do instead?
public boolean contains(Object o) {
return map.containsKey(o);
}
containsKey:
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
getNode:
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
It will not work since equals of arrays will do a == compare, and it will return true only if they point to the same instance.
Your problem could be fixed without work with Arrays.equals (the way to compare two arrays elements and not reference) (could be problematic (at least, for me.) i prefer an easy way)
Since you save X and Y coordinates, just make a class Point
public class Point {
public final int X;
public final int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
#Override
public boolean equals(Object obj)
{
if (obj == this) {
return true;
}
if (obj instanceof Point) {
Point pObj = (Point) obj;
return pObj.X == X && pObj.Y == Y;
}
return false;
}
#Override
public int hashCode()
{
int result = X;
result = 31 * result + Y;
return result;
}
}
then use Point class to save X, Y points.
Instead of create your custom point class, you can use the Android Point.
Example
Set<Point> points = new HashSet<Point>();
points.add(new Point(1, 3));
points.add(new Point(1, 4));
System.out.println(points.contains(new Point(1, 3)));
System.out.println(points.contains(new Point(1, 4)));
System.out.println(points.contains(new Point(1, 5)));
From the HashSet javadocs:
public boolean contains(Object o)
Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)).
So, generally, if you don't know what happens when you call equals on a particular object type, then contains also may not behave as you expect. It is never a bad idea to make a class for a particular object if that object type has conceptual meaning in your program. If you do that, you can override the equals method to make sure it is behaving exactly as you want.

Indexable Listview in Android

I'm trying to get an indexable list in my list view. I referred this. But while using the code, I'm facing with an error while using Korean Characters in the StringMatcher class. Can anyone explain me the usage of this class? Is this class required for English Characters as well?
Thanks in advance.
There are some changes to be done to make it work. In order to compile the project and get rid of korean text update the StringMatcher class
package com.woozzu.android.util;
public class StringMatcher {
public static boolean match(String value, String keyword) {
if (value == null || keyword == null)
return false;
if (keyword.length() > value.length())
return false;
int i = 0, j = 0;
do {
int vi = value.charAt(i);
int kj = keyword.charAt(j);
if (isKorean(vi) && isInitialSound(kj)) {
} else {
if (vi == kj) {
i++;
j++;
} else if (j > 0)
break;
else
i++;
}
} while (i < value.length() && j < keyword.length());
return (j == keyword.length())? true : false;
}
private static boolean isKorean(int i) {
return false;
}
private static boolean isInitialSound(int i) {
return false;
}
}

Categories

Resources