programmatically control cursor and text in EditText - java

I have a EditText box in which i want to control the cursor and modify the text programmatically
I have 12 button keypad made using 12 buttons in a GridView. With each button press I have a specific text which is to be inserted in EditText box at cursor position. For this i need cursor position so that i can insert the my custom text in the EditText view
I have two buttons for moving cursor position left/right by one character. Alternatively the cursor can also be set by touching EditText view (as EditText is supposed to behave)
Also i want the current position of cursor in EditText whenever Cursor position changes (I think i have to implement some kind of interface but i dont know how)
What i have tried so far
I am storing the key presses in an ArrayList<String>
I am setting the edittext.setText(String) everytime a key is pressed
can get the editable text through getText() but setText() only accepts strings.
Hence i am confused. What should i do to fulfill all my requirements.
PS: I am a Android beginner, and am making my 2nd app (which is a scientific calculator if it helps)
also if anyone volunteers to review my code, I'll be deeply obliged to him

I dont know why you need the cursor position of the textview but take a look at this question here : Get Cursor Position in Android in Edit Text?
Actually you can edit the text in the textview on code by getting the input or if you want you can implement the TextWatcher interface to know what every input the user type in your textview like this one:
private class CheckText implements TextWatcher {
#Override
public void afterTextChanged(Editable s) {
//triggers after the user changed the input on text
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//triggers before the user changed the input on text
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
//triggers when the user changed the input on text
}
}

To set any number in EditText use Wrapper class then set it on EditText using toString().
For set position you can use editText.setSelection(position);

It is how I did something similar
Stored id of all the button in a array as shown below.
int[] kbdButtons = { R.id.button1, R.id.button2, R.id.button3,
R.id.button4, R.id.button5, R.id.button6, R.id.button7,
R.id.button8, R.id.button9, R.id.button10, R.id.button11,
R.id.button12, R.id.button13, R.id.button14, R.id.button15}
2.Then added custom Onclicklistner to all buttons in the kbdButtons array
for (int i = 0; i < kbdButtons.length; i++) {
Button buttonNum = (Button) dialoglayout
.findViewById(kbdButtons[i]);
buttonNum.setOnClickListener(hindiKbdBtnsClick);
}
and here is the declaration of custom clicklistner
private OnClickListener hindiKbdBtnsClick = new OnClickListener() {
#Override
public void onClick(View v) {
int btnId = v.getId();
if (isShift && btnId != R.id.kbdKeyLeftShift
&& btnId != R.id.kbdKeyRightShift) {
sNotPressedView.setVisibility(View.VISIBLE);
sPressedView.setVisibility(View.GONE);
isShift = false;
}
if (btnId == R.id.kbdKeyLeftShift || btnId == R.id.kbdKeyRightShift) {
if (!isShift) {
sNotPressedView.setVisibility(View.GONE);
sPressedView.setVisibility(View.VISIBLE);
isShift = true;
} else {
sNotPressedView.setVisibility(View.VISIBLE);
sPressedView.setVisibility(View.GONE);
isShift = false;
}
} else if (btnId == R.id.kbdKeySpace || btnId == R.id.kbdKeyEnter) {
hkEditText.append(" ");
} else if (btnId == R.id.kbdKeyBackSpace) {
String txt_curr_val = hkEditText.getText().toString();
if (txt_curr_val.length() != 0)
txt_curr_val = txt_curr_val.substring(0,
txt_curr_val.length() - 1);
hkEditText.setText(txt_curr_val);
hkEditText.setSelection(txt_curr_val.length());
}else if (btnId == R.id.kbdKeyHide) {
mDialog.hide();
}else {
Button b = (Button) v;
String btnText = b.getText().toString();
hkEditText.append(btnText);
}
}
};
Explanation - hkEditText is my editText view i.e.
EditText hkEditText = (EditText)FindViewById(R.id.myEdittextId);
-see I just appended the text written on the button that is pressed at that time.
-you can also see the functionality of some special buttons like space, shift and enter

Related

Can I save the selection from a drop-down list and set it as the default value for the next app start?

there is a drop-down menu with a custom listView in my app. The data in this listView comes from an arraylist (one image and 2 strings for each entry). When the user selects an option from this list, it shows the image and the first string value in an imageview and a textview - see picture below.
Listview
After selection
Now I want the selection by the user to be saved and automatically loaded and displayed upon the next app start.
Here is my code for opening the list and selecting an option:
fromDropDown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fromDialog = new Dialog(ActivityMain.this);
fromDialog.setContentView(R.layout.from_spinner);
fromDialog.getWindow().setLayout(MATCH_PARENT,1200);
fromDialog.show();
EditText editText = fromDialog.findViewById(R.id.edit_text);
ListView listView = fromDialog.findViewById(R.id.list_view);
JavaAdapter javaAdapter = new JavaAdapter(ActivityMain.this,R.layout.list_row,arrayList);
listView.setAdapter(javaAdapter);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence cs, int start, int before, int count) {
javaAdapter.getFilter().filter(cs);
}
#Override
public void afterTextChanged(Editable s) {
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
fromDropDown.setText(javaAdapter.getItem(position).getExample());
picLeft.setImageResource(javaAdapter.getItem(position).getImage());
fromDialog.dismiss();
}
});
}
});
Right now I set the "default" value for the first start by doing this:
fromDropDown.setText(javaAdapter.getItem(0).getExample());
picLeft.setImageResource(javaAdapter.getItem(0).getImage());
But after the user selects an option, I want the app to save that selection and display this new selection on the next app start instead of my "default" value.
This presumably works with sharedpreferences, but I can't figure it out... Maybe someone can give me a hint in the right direction how this could be implemented.
you can save in shared preferences the position of selected item, and instead to set by default 0 you to this one:
save position
val sharedPref = context.getSharedPreferences("APP_SHARED", Context.MODE_PRIVATE)
with(sharedPref.edit()) {
putInt("position", selectedPosition).apply()
}
///after application loaded
val sharedPref = context.getSharedPreferences("APP_SHARED",Context.MODE_PRIVATE)
val position = sharedPref.getInt("position", 0) //0 default value in case when nothing was setted
fromDropDown.setText(javaAdapter.getItem(position).getExample());
picLeft.setImageResource(javaAdapter.getItem(position).getImage());

How to take inputs in multiple textviews?

i am new to development. i am creating an android calculator app with advanced functionality.The thing is i am using text view for taking and displaying inputs/outputs. My question is, how can i take Multiple inputs in multiple Textviews.
For example i have 3 text views,when user will enter 1st input in first textview(by default) and when user press the specific button it moves automatically to next textview . In some cases i want to take 2 inputs and in some cases i want to take 3 ,
How can i achieve this
Note: I dont want to use edit text , coz all buttons of already available in my app.Using Edit text will make softkeyboard to appear, and then for hiding the softkeyboard, i need to use hiding code lines in every class
You can do something like following:
private TextView[] textViews;
private TextView tvCurrentEditing;
private Button btnNext;
private Button btnPrev;
private Button btnSetText;
private int index = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
textViews = new TextView[3];
//Initialize all your textviews like textViews[0] = findViewById(<textview-id1>);
//textViews[1] = findViewById(<textview-id2>);
//textViews[2] = findViewById(<textview-id3>);
tvCurrentEditing = textViews[index];// I am assuming this is your first
//initialzie btnSettext
btnSettext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tvCurrentEditing.setText("<what ever you want");
}
});
//initialize next buton
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(index < textViews.length) {
index++;
}
tvCurrentEditing = textViews[index];
}
});
//Initialize previous button
btnPrev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(index > 0) {
index--;
}
tvCurrentEditing = textViews[index];
}
});
}
The names of the views could be different. The point is always use tvCurrentEditing whenever you want to change data of TextView. And update tvCurrentEditing whenever needed.

Set button onClick based on users selected spinner item

In my application I have fragment which contains spinner, button, editText and multiple TextViews. This is my code for getting users selected item and displaying it:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//Get position
int index = productSpinner.getSelectedItemPosition();
int[] tableSpoonList = getResources().getIntArray(R.array.tableSpoon);
int[] glassList = getResources().getIntArray(R.array.glass);
int[] teaSpoonList = getResources().getIntArray(R.array.teaSpoon);
// Set the texts and defaults
if (glassList[index] == 0) {
typeGlass.setVisibility(View.INVISIBLE);
} else {
typeGlass.setText(getString(R.string.glass) + glassList[index] + getString(R.string.grams));
typeGlass.setVisibility(View.VISIBLE);
}
if (tableSpoonList[index] == 0) {
typeTablespoon.setVisibility(View.INVISIBLE);
} else {
typeTablespoon.setText(getString(R.string.table_spoon) + tableSpoonList[index] + getString(R.string.grams));
typeTablespoon.setVisibility(View.VISIBLE);
}
if (teaSpoonList[index] == 0) {
typeTeaspoon.setVisibility(View.INVISIBLE);
} else {
typeTeaspoon.setText(getString(R.string.tea_spoon) + teaSpoonList[index] + getString(R.string.grams));
typeTeaspoon.setVisibility(View.VISIBLE);
}
}
As I mentioned, I have an editText and a button. I want the user to enter a number in editText and do little calculations with the values then display it.
I came up with solution, setting buttons onCLick called convert:
public void convert (View view) {
int userInput = Integer.parseInt(valueInput.getText().toString());
if (userInput == 0) {
Toast.makeText(getContext(), "Enter the value!", Toast.LENGTH_SHORT).show();
} else {
double customTableSpoon = (1/tableSpoonList[index]) * userInput;
typeTablespoon.setText(Double.toString(customTableSpoon));
}
}
But as you can see, I cant get from
double customTableSpoon = (1/tableSpoonList[index]) * userInput;
tableSpoonlist[index], because it is defined in spinners onItemSelected. However, If I define it outside before convert method
//Get position
int index = productSpinner.getSelectedItemPosition();
int[] tableSpoonList = getResources().getIntArray(R.array.tableSpoon);
int[] glassList = getResources().getIntArray(R.array.glass);
int[] teaSpoonList = getResources().getIntArray(R.array.teaSpoon);
I get crash when switching to that fragment, because
int index = productSpinner.getSelectedItemPosition();
returns null.
And I cant implement onClick in fragment, because I'm already implementing AdapterView.OnItemSelectedListener.
Also, my spinner is created onCreateView:
//Create spinner
productSpinner = (Spinner) view.findViewById(R.id.productSpinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(), R.array.products_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
productSpinner.setAdapter(adapter);
productSpinner.setOnItemSelectedListener(this);
How can I get the spinners selected item so the user can "edit" it?

How to show text while writing on other one?

I built an app which is medical calculator and there is a lot of texts there and every TextView express specific value like
ptn = patient name
wt = weight
hit = hight
... etc
and may be the user forgot what he have to write in the text while he writing, So I suggest a method to remember him and that by putting extra TextViewat the bottom of the screen, so when the user doesn't writing the text is empty.. then when he click on "ptn" the text below show "patient name" then when he left the text and click on the next text "wt" the text below erase "patient name" and replace it with "weight".. etc
and suggest for that this code :
e1 = (EditText) findViewById(R.id.Name);
StringV = (TextView) findViewById(R.id.StringV);
////
e1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
StringV.setText("");
}
});
e1.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
StringV.setText("");
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
StringV.setText("Patient Name");
}
});
but when run the app the result was depressed!
when i click on the next text the below one didn't change it change just while i'm writing on the text i want it to change when i click on the next text till finishing the writing and click on the next text ..
How to do that, please ?
I think your work can be done with simple :
public class YourClass extends Activity implements OnClickListener{
EditText name , weight;
TextView StringV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
name = (EditText) findViewById(R.id.Name);
weight = (EditText) findViewById(R.id.Weight);
StringV = (TextView) findViewById(R.id.StringV);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.Name:
StringV.setText("Patient Name");
break;
case R.id.Weight:
StringV.setText("Weight");
break;
// write as many cases as you want
default:
StringV.setText(" ");
break;
}
}
}
if it helped don't forget to thanks and accept.
Do not use hacky and non-standard ways of achieving this functionality. Android already provides a solution for this type of problem in its design support library, using Floating labels for EditText. You're supposed to use TextInputLayout which I recently explained in a blog post of mine.

How to return user input values (double) from EditText- Android

I'm new to OOP, but I've had experience with C previously. I'm learning Java and working on building an app slowly. I find I learn more when I apply what I've read and learned from other sources to projects.
The problem I've been facing for a while now is in regard to returning values users have inputted into EditText fields and using those values to run some calculations. Here is my code:
public class Linmotion extends Activity {
// Creating the variables
EditText time, acc, dis, ivel, fvel;
Button solve;
int count = 0;
double time1,acc1,dis1,ivel1,fvel1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_linmotion1);
time = (EditText) findViewById(R.id.EditText01);
acc = (EditText) findViewById(R.id.EditText02);
dis = (EditText) findViewById(R.id.EditText03);
ivel = (EditText) findViewById(R.id.EditText04);
fvel = (EditText) findViewById(R.id.EditText05);
solve = (Button) findViewById(R.id.buttonSolve);
//Trying to return inputted values
/*
if (!(time.getText() == null)) {
time1=Double.parseDouble(time.getText().toString());
}
if(!(acc.getText()==null)){
acc1=Double.parseDouble(acc.getText().toString());
}
if(!(ivel.getText()==null)){
ivel1=Double.parseDouble(ivel.getText().toString());
}
if(!(fvel.getText()==null)){
fvel1=Double.parseDouble(fvel.getText().toString());
}s
if(!(dis.getText()==null)){
dis1=Double.parseDouble(dis.getText().toString());
}
/*
* Double.parseDouble(time.getText().toString());
* Double.parseDouble(acc.getText().toString());
* Double.parseDouble(ivel.getText().toString());
* Double.parseDouble(fvel.getText().toString());
* Double.parseDouble(dis.getText().toString());
*/
// add button listener
solve.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
if (time1 < 0) {
count++;
if (acc1 < 0) {
count++;
}
if (ivel1 < 0) {
count++;
}
if (fvel1 < 0) {
count++;
}
if (dis1 < 0) {
count++;
}
if (count > 2) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
Linmotion.this);
final AlertDialog alert = alertDialog.create();
alert.show();
alertDialog.setTitle("Error");
alertDialog
.setMessage("Please input values into at least 3 fields");
alertDialog.setPositiveButton("OK",new DialogInterface.OnClickListener() {
// function of dialog button
public void onClick(DialogInterface dialog,
int id) {
alert.cancel();
}
});
}
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.linmotion, menu);
getActionBar().setDisplayShowTitleEnabled(false);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
The if statements and the other Double.parseDouble lines have been commented out because every time I try to debug the code the app crashes the instant Linmotion is created. I suspect its from the fact that onCreate runs the Double.parseDouble code and the values in the field are null. I tried to fix this with the if statements and it still crashes. I'm not sure where to go from here.
Again, if I wasn't clear I just want the values inputted into the EditText to return a double and then use that double in the Java code to run some equations and an alert dialog if not enough fields have been filled in.
EDIT/UPDATE:
I finally figured out what was wrong with my code. I took in advice from everyone and revised accordingly, so here it is:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_linmotion1);
time = (EditText) findViewById(R.id.eTexttime);
acc = (EditText) findViewById(R.id.eTextacc);
dis = (EditText) findViewById(R.id.eTextdis);
ivel = (EditText) findViewById(R.id.eTextivel);
fvel = (EditText) findViewById(R.id.eTextfvel);
solve = (Button) findViewById(R.id.buttonSolve);
solve.setOnClickListener(new OnClickListener() {
#SuppressWarnings("deprecation")
#Override
public void onClick(View v) {
count=0;
if (time.getText().toString().equals("")){
count++;
}
if(dis.getText().toString().equals("")){
count++;
}
if(fvel.getText().toString().equals("")){
count++;
}
if(ivel.getText().toString().equals("")){
count++;
}
if(acc.getText().toString().equals("")){
count++;
}
if (count>2){
// TODO Auto-generated method stub
final AlertDialog alert= new AlertDialog.Builder(Linmotion.this).create();
alert.setTitle("Oops");
alert.setMessage("Please input values in at least 3 fields.");
alert.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alert.cancel();
}
});
alert.show();
count=0;
}
if(!(time.getText().toString().equals(""))){
time1=Double.parseDouble(time.getText().toString());
}
if(!(acc.getText().toString().equals(""))){
acc1=Double.parseDouble(acc.getText().toString());
}
if(!(dis.getText().toString().equals(""))){
dis1=Double.parseDouble(dis.getText().toString());
}
if(!(ivel.getText().toString().equals(""))){
ivel1=Double.parseDouble(ivel.getText().toString());
}
if(!(fvel.getText().toString().equals(""))){
fvel1=Double.parseDouble(fvel.getText().toString());
}
} });
}
In regard to the issues I had with the alertdialog I realized that my count integer would continue to increase every time the solve button was clicked. To fix this I simply equaled the integer to 0 at the beginning of the onclicklistener and at the end of the if statement regarding the dialog. Thanks everyone.
It looks to me like you're doing it right. I think the problem might be that it's in your OnCreate method.
Try making the Button Solve's OnClick method run your commented code before doing the logic!
You can get the value from an EditText using getText()..
See this link for more details
According to the docs getText() returns an Editable.
so,
time = (EditText) findViewById(R.id.EditText01);
String value = time.getText().toString();
Now, as i've said earlier, since getText() returns an Editable you need to convert it into String before you use it..
So, change
if (!(time.getText() == null)) {
to
if (!(time.getText().toString() == null)) {
Also, if you want to check if the EditText is empty or not, try like this..
if (!(time.getText().toString() .equals(""))) {
Try this answer..
Your code isn't working because you are trying to read these text fields on creation. This is not what you want to do.
You are trying to access the EditTexts before the page finishes loading. Instead, you need to do this in an event handler, like you have for the buttons. Read the values in an event handler, not in onCreate.
The simplest option would be to add an "update" button and do all those operations in the onClick handler for that button.
Most likely your EditText fields initially contain text, that cannot be parsed with Double.parseDouble (Something like the empty string). A NumberFormatException is thrown is this case. If you want to get the values at the time solve button is clicked, you have to get the text inside OnClickListener.onClick (otherwise you use the initial strings, i.e. the strings in the android:text attributes in the activity_linmotion1 layout). To handle invalid input, you can simply catch the NumberFormatException:
solve.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
double time1 = Double.parseDouble(time.getText().toString());
double acc1 = Double.parseDouble(acc.getText().toString());
double ivel1 = Double.parseDouble(ivel.getText().toString());
double fvel1 = Double.parseDouble(fvel.getText().toString());
double dis1 = Double.parseDouble(dis.getText().toString());
// ... rest of your original listener code
} catch (NumberFormatException ex) {
// show error in dialog or something
}
}
});
Oncreate is the first method called when an activity is created, so by the time the onCreate is called, the editText is having an empty string which you are giving as an input to parseDouble which will give NumberFormatException.
You can avoid this crash by putting a button and handling the button onClick event. Inside this button click you collect the values from editfield. You can handle on click by defining listeners in the following way
<Button android:id="#+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="yourHandlerName" />
Now define your onClick with getText to get text from editfield in the following way
public void yourHandlerName(View v) {
switch(v.getid()) {
case R.id.mybutton: Double.parseDouble(editField.getText().to string());
}
You have to register a Listener. Because onCreate() is called when the Actvity first start. This means that you can't get the text from your EditTexts because the Actvity is creating. But you can use your OnClickListener or other Listeners. You can easily write your commented lines to the OnClickListener. At the time you are clicking the button the method getText().toString() return the values. If you want to do it without clicking on a button use addTextOnChangedListener() on yout EditText.

Categories