How to fix TextWatcher on orientation change? - java

I want to write a validator for multiple editText's using TextWatcher.
I already have method to validate if the data written by user is correct.
And also added validation to check if editText is empty. But here is where it's not working as I would like to.
This TextWatcher is also activated when phone changes orientation and I don't want this to happen. I want it work only when user deletes data from editText.
Here is the code:
#Override
final public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
final public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
final public void afterTextChanged(Editable s) {
String text = textView.getText().toString();
if(textView.getText().toString().isEmpty()){
textView.setError("Can't be empty");
ParametersFrag.isCorrect = false;
} else {
validate(textView, text);
}
}
And the validate part in fragment look like this:
editText2_5.addTextChangedListener(new ParameterValidator(editText2_5) {
#Override
public void validate(TextView textView, String text) {
double parDouble = Double.parseDouble(Tab2Fragment.editText2_5.getText().toString());
if (parDouble < sth_min) {
textView.setError(getString(R.string.err_min_value) + " " + sth_min);
ParametersFrag.isCorrect = false;
} else if (parDouble > sth_max) {
textView.setError(getString(R.string.err_max_value) + " " + sth_max);
ParametersFrag.isCorrect = false;
} else {
ParametersFrag.isCorrect = true;
}
}
});
Question is how can I make it not triggering on orientation change?
Thank You

try this:
#Override
public void onConfigurationChanged(#NotNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
switch (newConfig.orientation) {
case Configuration.ORIENTATION_LANDSCAPE:
editText2_5.addTextChangedListener(null);
break;
case Configuration.ORIENTATION_PORTRAIT:
// editText2_5.addTextChangedListener(null);
// ============= OR =============
// editText2_5.addTextChangedListener(new ParameterValidator(editText2_5) {
// #Override
// public void validate(TextView textView, String text) {
// double parDouble = Double.parseDouble(Tab2Fragment.editText2_5.getText().toString());
// if (parDouble < sth_min) {
// textView.setError(getString(R.string.err_min_value) + " " + sth_min);
// ParametersFrag.isCorrect = false;
// } else if (parDouble > sth_max) {
// textView.setError(getString(R.string.err_max_value) + " " + sth_max);
// ParametersFrag.isCorrect = false;
// } else {
// ParametersFrag.isCorrect = true;
// }
// }
// });
break;
default:
break;
}
}

private var doesDeviceTitled = false
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
doesDeviceTitled = when (newConfig.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
true
}
else -> {
false
}
}
}
Note: The above code was in Kotlin
then after wrap validation using this boolean variable.
editText2_5.addTextChangedListener(new ParameterValidator(editText2_5) {
#Override
public void validate(TextView textView, String text) {
if(!doesDeviceTitled){
//Your validation code here.
}
}});
Happy Coding :)

OK, so now as I think, you need to declare android:configChanges="orientation" in your <activity> tag in AndroidManifest.xml and remove this:
public void onConfigurationChanged(#NotNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
switch (newConfig.orientation) {
case Configuration.ORIENTATION_LANDSCAPE:
editText2_5.addTextChangedListener(null);
break;
case Configuration.ORIENTATION_PORTRAIT:
// editText2_5.addTextChangedListener(null);
// ============= OR =============
// editText2_5.addTextChangedListener(new ParameterValidator(editText2_5) {
// #Override
// public void validate(TextView textView, String text) {
// double parDouble = Double.parseDouble(Tab2Fragment.editText2_5.getText().toString());
// if (parDouble < sth_min) {
// textView.setError(getString(R.string.err_min_value) + " " + sth_min);
// ParametersFrag.isCorrect = false;
// } else if (parDouble > sth_max) {
// textView.setError(getString(R.string.err_max_value) + " " + sth_max);
// ParametersFrag.isCorrect = false;
// } else {
// ParametersFrag.isCorrect = true;
// }
// }
// });
break;
default:
break;
}
}

Related

Retreive Arraylist modified from Adaptater RecyclerView to first activity

I've an activity in which I use a RecyclerView. In the Adaptater I modify the content of an ArrayList. How can I retrieve my modified ArrayList in my first activity
Thank you very much for your help
Best regards
Georges
holder.imageClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (laPlateaux.get(position).Cat.equals("U7")) {
keyPlateau = "PlatU7" + "-" + zdte + "-" + laPlateaux.get(position).AccueilNum;}
else {
keyPlateau = "PlatU9" + "-" + zdte + "-" + laPlateaux.get(position).AccueilNum; }
if (laPlateaux.get(position).Cat.equals("U7")) {
if (laPlateaux.get(position).Select.equals("N")){
mDatabase.child("PlateauxU7").child(keyPlateau).child("Selected").setValue("Y");
holder.imageClick.setImageDrawable(holder.itemView.getContext().getDrawable(R.drawable.valoknew));
laPlateaux.get(position).Select = "Y";
notifyDataSetChanged();}
else {
mDatabase.child("PlateauxU7").child(keyPlateau).child("Selected").setValue("N");
holder.imageClick.setImageDrawable(holder.itemView.getContext().getDrawable(R.drawable.valnoknew));
laPlateaux.get(position).Select = "N";
notifyDataSetChanged();}}
else {
if (laPlateaux.get(position).Select.equals("N")){
mDatabase.child("PlateauxU9").child(keyPlateau).child("Selected").setValue("Y");
holder.imageClick.setImageDrawable(holder.itemView.getContext().getDrawable(R.drawable.valoknew));
laPlateaux.get(position).Select = "Y";
notifyDataSetChanged();}
else {
mDatabase.child("PlateauxU9").child(keyPlateau).child("Selected").setValue("N");
holder.imageClick.setImageDrawable(holder.itemView.getContext().getDrawable(R.drawable.valnoknew));
laPlateaux.get(position).Select = "N";
notifyDataSetChanged();}}} }); }
#Override
public int getItemCount() {
return laPlateaux.size();
}
I guess you must just implement the public getter in your adapter, that's all.
In the Adapter
public List<PlaceholderItem> getKeyPlateau() {
return keyPlateau;
}
In the activity
ArrayList<String> keyPlateau = adapter.getKeyPlateau();

Android Broadcast Receiver as inner static class Passing a String

Probably you want to jump to Update 2 and check the code if needed
I am building a barcode scanner and having difficulty in passing data that I have captured from an inner class that extends BroadcastReceiver to MainActivity class, I do understand the difference between static and non static objects, but I got stuck.
Cant invoke my logic method from the inner class.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
protected void onCreate(Bundle savedInstanceState){...}
public void Logic(String result){// Do something...}
//Inner Class
public static class ScanResultReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {...
// data here captured fine!
// Here I want to send my data to MainActivity Logic(result)
Logic(result);
}
}
If I make "Logic()" as Static method, I get a lot of errors regards to calling non static from static method from Toaster/variables..etc
Update
This method is inside MainActivity, I do want to call it from the inner class
public void Logic(String result) throws Exception {
//prepare the results
if (mDecodeResult.decodeValue.substring(0, 1).equals("{") && mDecodeResult.decodeValue.substring(mDecodeResult.decodeValue.length() - 1).equals("}")) {
if (!(mDecodeResult.decodeValue.equals("SCAN AGAIN"))) {
mDecodeResult.decodeValue = mDecodeResult.decodeValue.substring(1);
mDecodeResult.decodeValue = mDecodeResult.decodeValue.substring(0, mDecodeResult.decodeValue.length() - 1);
}
}
if (mDecodeResult.decodeValue.equals("SCAN AGAIN")) {
Toast toast = Toast.makeText(getApplicationContext(),
"No scan data received! Please Scan Again", Toast.LENGTH_SHORT);
toast.show();
} else if (mDecodeResult.decodeValue != null && tourFlag) {
String formattedDate = getTime();
String scanContent = mDecodeResult.decodeValue;
boolean found = false;
if (ForcedOrRandom.equals("Random")) {
String[] b;
for (String l : ToBeScanned) {
b = l.split(":");
if (scanContent.equals(b[0])) {
Log.d("remove", "scanned: " + scanContent);
Log.d("remove", "remove : " + b[0]);
found = true;
}
}
} else if (ForcedOrRandom.equals("Forced")) {
String[] b;
for (String I : FTobeScannedNext) {
b = I.split(":");
if (scanContent.equals(b[0])) {
Log.d("remove", "scanned: " + scanContent);
Log.d("remove", "remove : " + b[0]);
found = true;
}
}
}// end Skip/Forced
if (listLoaded && found) {
theResult[resultCount].setTourID(currentTourId);
theResult[resultCount].setBarcode(scanContent);
BarcodeObject a = getBarcodeInfo(scanContent);
if (ForcedOrRandom.equals("Random")) {
} else {
if (myTimer != null) {
myTimer.cancel();
Timer = (TextView) findViewById(R.id.timertext);
Timer.setText("");
PlayOrPause.setVisibility(View.INVISIBLE);
}
boolean isTimed = a.getForceNextBarCode().equals("");
if (!(isTimed)) {
PlayOrPause = (ImageButton) findViewById(R.id.PlayPause);
PlayOrPause.setVisibility(View.VISIBLE);
PlayOrPause.setImageResource(R.drawable.pause);
final AlertDialog.Builder timealert = new AlertDialog.Builder(this);
PlayOrPause.setEnabled(true);
long duration = Integer.parseInt(a.getForceNextBarCode());
duration = duration * 60000;
myTimer = new CountDownTimer(duration, 1000) {
#Override
public void onTick(long millisuntilFinished) {
int seconds = (int) (millisuntilFinished / 1000) % 60;
int minutes = (int) ((millisuntilFinished / (1000 * 60)) % 60);
Timer = (TextView) findViewById(R.id.timertext);
Timer.setText(minutes + ":" + seconds);
timeLeft = millisuntilFinished;
}
String value = "";
#Override
public void onFinish() {
Timer = (TextView) findViewById(R.id.timertext);
theResult[resultCount].setScanstatus(scanStatusTimeElapsed);
timealert.setTitle("Site Secure");
timealert.setMessage("Time Elapsed! Enter reason");
// Set an EditText view to get user input
final EditText input = new EditText(MainActivity.this);
timealert.setView(input);
timealert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
value = input.getText().toString();
// Do something with value!
while (value.equals("")) {
timealert.setView(input);
timealert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
value = input.getText().toString();
}
});
}
theResult[resultCount].setComments(value);
}
});
timealert.setIcon(android.R.drawable.ic_dialog_alert);
timealert.show();
Timer.setText(R.string.Time_Elapsed);
}
};
myTimer.start();
}
}
theResult[resultCount].setBarcodeID(a.getBarCodeId());
theResult[resultCount].setDateScanned(formattedDate);
theResult[resultCount].setSkipped(getResources().getString(R.string.Scanned));
}// end big if listLoaded && found
contentTxt.setText(scanContent);
Toaster(getResources().getString(R.string.TScan_Complete));
if (mainScanCounter == 0) {
if (tourDecider(scanContent)) {//tour decider is called to determine if this is boolJanamScanner random or forced tour
tourId = scanContent;
if (!(readFileOffline(siteSecurePath + "/doneTourNumber.txt").equals(""))) {
SYNC.setEnabled(true);
}
}
} else if (mainScanCounter > 0) {
if (ForcedOrRandom.equals("Random")) {
ListManager(scanContent);
} else {
ForcedListManager(scanContent);
}
}
} else if (mDecodeResult.decodeValue != null && officerScanFlag) {
TextView officertextview = (TextView) findViewById(R.id.officerid);
UserObject theofficer = getUserInfo(mDecodeResult.decodeValue);
if (theofficer == null) {
popUps("Error", "Invalid Officer ID, Please Rescan", "TITLE");
officerScan.setEnabled(true);
} else if (theofficer != null) {
// officer ID found need to store it for backup
officerId = theofficer.getOfficerid();
makeFileOffline(officerId, "officerID");
officertextview.setText(theofficer.getUsername());
officerScanFlag = false;
startTimersOfficerID = getTime();
tourBtn.setEnabled(true);
}
}
if (mDecodeResult.decodeValue != null && exceptionFlag) {
Log.d("check", "exception was clicked");
String ex_result = mDecodeResult.decodeValue;
for (int i = 0; i < theExceptions.length; i++) {
if (!(theExceptions[i].getBarcode().equals(ex_result))) {
String refnum = theExceptions[i].getRefNum();
i = theExceptions.length;
theResult[resultCount - 1].setException(refnum);
}
}
exceptionFlag = false;
Toaster(getResources().getString(R.string.TScan_Complete));
}
} // Logic Ends
Update 2
Not sure if I need to have another thread for this but I will put what I have found, my issue have narrowed to the following:
I am waiting on an intent called
<action android:name="device.scanner.USERMSG" />
with a permission
android:permission="com.permission.SCANNER_RESULT_RECEIVER"
now my issue
if a user tap button and released in less than .5 second onKeyup() event will be fired before my onReceive() that is inside the static class which is extends BroadcastReceiver, and that causes problem because Logic() will be invoked before updating the String inside onReceive()
if user hold the button long enough, onReceive will be invoked and everything is good and happy.
How can I make sure that onReceive() always invoked first?
public boolean onKeyUp(int keycode, KeyEvent event) {
if (keycode == 221 || keycode == 220 || keycode == 222) {
Logic(result);
}
return true;
}
Move this line of code:
public void Logic(String result){// Do something...}
inside your class ScanResultReceiver and it will work for sure. Your code should look like this:
public static class ScanResultReceiver extends BroadcastReceiver {
public ScanResultReceiver() {
//empty constructor
}
#Override
public void onReceive(Context context, Intent intent) {...
// data here captured fine!
// Here I want to send my data to MainActivity Logic(result)
Logic(result);
}
public void Logic(String result){/* ... */}
}

Java android RelativeLayout set on swipe Listener doesn't work with listView inside

Hi I have a swipe listener on RelativeLayout in relative layout I have texview ... and ListView , when I swipe to up I show a listView , when I swipe down I hide a listView. A list View is inside a relativeLayout, But when I slide down (in relativeLayout) a listVIew never hide . This is what I did :
ublic class RelativeLayoutTouchListener implements View.OnTouchListener {
static final String logTag = "ActivitySwipeDetector";
private Activity activity;
static final int MIN_DISTANCE = 100;// TODO change this runtime based on screen resolution. for 1920x1080 is to small the 100 distance
private float downX, downY, upX, upY;
// private MainActivity mMainActivity;
public RelativeLayoutTouchListener(MainActivity mainActivity) {
activity = mainActivity;
}
public void onRightToLeftSwipe() {
Log.i(logTag, "RightToLeftSwipe!");
Toast.makeText(activity, "RightToLeftSwipe", Toast.LENGTH_SHORT).show();
// activity.doSomething();
}
public void onLeftToRightSwipe() {
Log.i(logTag, "LeftToRightSwipe!");
Toast.makeText(activity, "LeftToRightSwipe", Toast.LENGTH_SHORT).show();
// activity.doSomething();
}
public void onTopToBottomSwipe() {
Log.i(logTag, "onTopToBottomSwipe!");
Toast.makeText(activity, "onTopToBottomSwipe", Toast.LENGTH_SHORT).show();
// activity.doSomething();
}
public void onBottomToTopSwipe() {
Log.i(logTag, "onBottomToTopSwipe!");
Toast.makeText(activity, "onBottomToTopSwipe", Toast.LENGTH_SHORT).show();
// activity.doSomething();
}
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
Log.e("sdasdas", "dsfdsfdsfsdf");
downX = event.getX();
downY = event.getY();
return true;
}
case MotionEvent.ACTION_UP: {
Log.e("dziaƂa", "kikik");
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
Log.e("delta y " , deltaY +"");
// Log.e("delta " , deltaY +"");
// // swipe horizontal?
// if (Math.abs(deltaX) > MIN_DISTANCE) {
// // left or right
// if (deltaX < 0) {
// this.onLeftToRightSwipe();
// return true;
// }
// if (deltaX > 0) {
// this.onRightToLeftSwipe();
// return true;
// }
// } else {
// Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long horizontally, need at least " + MIN_DISTANCE);
// // return false; // We don't consume the event
// }
//
// // swipe vertical?
// if (Math.abs(deltaY) > MIN_DISTANCE) {
// // top or down
// if (deltaY < 0) {
// this.onTopToBottomSwipe();
// return true;
// }
// if (deltaY > 0) {
// this.onBottomToTopSwipe();
// return true;
// }
// } else {
// Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long vertically, need at least " + MIN_DISTANCE);
// // return false; // We don't consume the event
// }
final ViewGroup.LayoutParams params = MainActivity.relativeLayout1.getLayoutParams();
if(deltaY<0){
params.height = (int) activity.getResources().getDimension(R.dimen.dimen_entry_in_dp);
relativeLayout1.setLayoutParams(params);
MainActivity.listView1.setVisibility(View.GONE);
}else{
params.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
MainActivity.relativeLayout1.setLayoutParams(params);
MainActivity.listView1.setVisibility(View.VISIBLE);
}
return false; // no swipe horizontally and no swipe vertically
}// case MotionEvent.ACTION_UP:
}
return false;
}
}
and this is how I call this listner :
relativeLayout1.setOnTouchListener(new RelativeLayoutTouchListener(this));
Now I do this . I checked possition on ListView , but when I swipe a listView to Up and it always listView hide , I don't know if this works corretly
listView1.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
boolean enable = false;
if (listView1 != null && listView1.getChildCount() > 0) {
boolean firstItemVisible = listView1.getFirstVisiblePosition() == 0;
boolean topOfFirstItemVisible = listView1.getChildAt(0).getTop() == 0;
enable = firstItemVisible && topOfFirstItemVisible;
}
if(enable) {
Log.e("works ? ", "works");
listView1.setOnTouchListener(new RelativeLayoutTouchListener(MainActivity.this));
}
}
});

How to validate to rating bar on Button click in Android?

I want to validation on RatingBar in Android. I have 5 rating Bar and 1 Button. I don't want to submit the data without pressed the rating bar. I want to take validation on Rating bar.
Can someone help me. How to take validation on Rating bar?
Here is my Activity code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rating_baar);
databaseHelper = new DatabaseHelper(this);
databaseHelper.onOpen(db);
addListenerOnRatingBar_one();
addListenerOnRatingBar_two();
addListenerOnRatingBar_three();
addListenerOnRatingBar_four();
addListenerOnRatingBar_five();
addListenerOnButton();
}
#SuppressLint("SimpleDateFormat")
public void addListenerOnButton() {
buttonSubmitRate = (Button) findViewById(R.id.button_SubmitRate);
buttonSubmitRate.setOnClickListener(new OnClickListener() {
#SuppressLint("SimpleDateFormat")
#Override
public void onClick(View v) {
if((etTaskName.getText().toString().isEmpty()))
etTaskName.setError("Field Can Not Be Empty !");
else if (!etTaskName.getText().toString().trim().matches("[a-zA-Z{ }]+"))
etTaskName.setError("Accept Alphabets Only.");
else {
strEmpName = textViewNAme.getText().toString().trim();
strTaskName = etTaskName.getText().toString().trim();
String strCurrentDate = new SimpleDateFormat("dd/MM/yyyy").format(new Date());
System.out.println("strCurrentDate = " + strCurrentDate);
String strCurrentMonth = new SimpleDateFormat("MMM").format(new Date());
System.out.println("strCurrentDate = " + strCurrentMonth);
String strCurrenYear = new SimpleDateFormat("yyyy").format(new Date());
System.out.println("strCurrenYear = " + strCurrenYear);
System.out.println("__________________________________________________________________________________");
databaseHelper.insertPerformance_Details(intentStr1, strEmpName,
strTaskName, rateVal_one,
rateVal_two, rateVal_three,
rateVal_four,rateVal_five,
strCurrentDate,strCurrentMonth,
strCurrenYear);
System.out.println("Data Add SuccesFully !!!!");
etTaskName.setText("");
Intent i = new Intent(RatingBaar_Class.this, Rating_Msg.class);
startActivity(i);
finish();
overridePendingTransition(R.anim.anim_in,R.anim.anim_out);
}
}
});
}
public void addListenerOnRatingBar_one() {
ratingBar_one = (RatingBar) findViewById(R.id.ratingBar1);
ratingBar_one.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
rateVal_one = String.valueOf(rating);
System.out.println(" rateVal_one = " + rateVal_one);
}
});
}
/* Exactly the same methods for four other rating bars, except for variable names */
public void addListenerOnRatingBar_two() { ... }
public void addListenerOnRatingBar_three() { ... }
public void addListenerOnRatingBar_four() { ... }
public void addListenerOnRatingBar_five() { ... }
At first set all rating bar to 0 value. Then on click to button, check if the value has altered in all of them. If so, only valid else invalid.
Also you can use listener to each rating bar and change value of some boolean variable to true
Example:
boolean flag1 = false;
boolean flag2 = false;
.... //similarly upto 5
Then in rating bar listener1
{
flag1 = true;
}
Similarly for all set flag to be true
And in button onClickListener do the following:
if(flag1 && flag2 && flag3 && flag4 && flag5){
//do your work
}else{
//display message that one of the rating bar hasn't been touched
}

Android - End TextWatcher when user enters '.'

I have a TextWatcher set up and working (nearly) exactly as I want it. However, I would like this TextWatcher to stop as soon as the user enters a '.'. The only solution I have found so far crashes the app if the user entirely deletes the text. It is also important that the ENTIRE TextWatcher ends at the moment the user enters a '.'.
I have tried placing the TextWatcher within the loop, however it doesn't seem to work.
private TextWatcher userEnterListener = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if(after==0) {
shownText = "Please try again";
}
else if(after==1) {
shownText = "A";
}
else if(after==2) {
shownText = "An";
}
else if(after==3) {
shownText = "And";
}
else if(after==4) {
shownText = "Andr";
}
else if(after==5) {
shownText = "Andro";
}
else if(after==6) {
shownText = "Androi";
}
else if(after==7) {
shownText = "Android";
}
else if(after==8) {
shownText = "Android A";
}
else if(after==9) {
shownText = "Android Ap";
}
else if(after==10) {
shownText = "Android App";
}
else {
shownText = "Please try again";
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
recordedString = (s.toString());
update();
}
};
maybe this could work:
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if(s.toString().equals("Android App") && start == '.'){
//here add an Empty TextWatcher to the EditText who has this TextWatcher added.
}
recordedString = (s.toString());
update();
}

Categories

Resources