I have a hangman-app which I fetch a random word from Db i created, then I save it to randomedWord and then i make another String for holding randomedWord but replaced with only "_". This hiddenWord is displayed so the user knows how many chars there is.
When a user hits Enter a onlicklistener fires guess() method:
I have following code which initates a local String which has the value of a TextView(userInput). Then if randomedWord contains the guess I want to put in guess into the same position as it is in the randomedWord, but now to hiddenWord and then update the TextView again.
Guess method:
public void guess()
{
String guess = userInput.getText().toString();
if(randomedWord.contains(guess))
{
hiddenWord = hiddenWord.replaceAll(guess, guess);
this.wordHolder.setText(hiddenWord);
} else
{
showImages();
}
}
The problem I think is this line:
hiddenWord = hiddenWord.replaceAll(guess, guess);
because hiddenWord just contains "_" and therefore I can't replace with (guess, guess) where the first is WHAT to be replaced and last is WITHWHAT.
How do I replace the same POSITION as it is in randomedWord with guess into hiddenWord?
I would change your approach slightly. When a user inputs and guess() is called, find all occurences of that guess in randomedWord and then set the characters in hiddenWord to guess. Using StringBuilder and String.indexOf(), it would look something like this. Also, guess will need to be a char:
StringBuilder builder = new StringBuilder(hiddenWord);
int index = word.indexOf(guess);
while (index >= 0) {
builder.setCharAt(index, guess);
index = word.indexOf(guess, index + 1);
}
hiddenWord = builder.toString();
My solution to the problem looks like this:
// INVWORD METHOD WHICH TURNS THE FETCHED WORD INTO A COPY BUT ONLY "_"
public void invWord()
{
hiddenWord = randomedWord;
hiddenWord = hiddenWord.replaceAll(".", "_");
}
// GUESS METHOD WHICH IS CALLED WHEN ENTER-BUTTON ISCLICKED
public void guess() throws IndexOutOfBoundsException
{
char guess = userInput.getText().charAt(0);
StringBuilder builder = new StringBuilder(hiddenWord);
String j = ""+guess;
int index = randomedWord.indexOf(guess);
if (randomedWord.contains(j))
{
while (index >= 0)
{
builder.setCharAt(index, guess);
index = randomedWord.indexOf(guess, index + 1);
hiddenWord = builder.toString().trim();
wordHolder.setText(hiddenWord);
if (hiddenWord.trim().contains(randomedWord))
{
winner();
}
}
}
else
{
showImages();
}
}
Problem is that I would need to add a +" " to the hiddenWord = hiddenWord.replaceAll(".", "_"); to make the word be like _ _ _ _ _ and makes the user see how many ketters the word is. In my solution it will only be long ____, but it works. If I set index*2 at builder.setCharAt(index, guess); the formatting will be good but then winner(); is never run, I guess because the " " makes the hiddenWord no longer = ranomedWord.
How can I solve this?
Got it all solved! The feeling when everything works smoothly.... :)
Heres the code:
// Set listener to enter-button and do guess when textfield is not empty and toast that input need if it is
enterLetterButton.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
if (!(userInput.getText().toString().isEmpty()) )
{
guess();
} else if (userInput.getText().toString().isEmpty())
{
Toast toast = Toast.makeText(getApplicationContext(), "You need to insert a letter", Toast.LENGTH_SHORT);
toast.show();
}
}
});
// invWord() method. Converts the randomedWord to a string of "_".
public void invWord()
{
hiddenWord = randomedWord;
hiddenWord = hiddenWord.replaceAll(".", "_" +" ");
}
//guess() method. Puts the guess(char) at the index fetched and if the hiddenWord contains no more "_" winner() is called
public void guess() throws IndexOutOfBoundsException
{
char guess = userInput.getText().charAt(0);
StringBuilder builder = new StringBuilder(hiddenWord);
String j = ""+guess;
int index = randomedWord.indexOf(guess);
if (randomedWord.contains(j))
{
while (index >= 0)
{
builder.setCharAt(index*2, guess);
index = randomedWord.indexOf(guess, index + 1);
hiddenWord = builder.toString().trim();
wordHolder.setText(hiddenWord);
if (!(hiddenWord.toString().contains("_".toString())) )
{
winner();
}
}
}
else
{
showImages();
}
}
Related
I am an android noobie. What I am trying to do is to make this String an ArrayList. This is done. When i Print it On (with tv.setText) , the result is what i need but in this if i have right below i cannot find the "1".
The result i want to have is to store the text between the noumbers inside another ArrayList but to go there i have to be able to read the strings from the ArrayList.
public class MainActivity extends AppCompatActivity {
String text = "1Hello12People22Paul22Jackie21Anna12Fofo2";
TextView tv;
List<String> chars = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);
PrinThemNow();
}
public void PrinThemNow(){
chars = Arrays.asList(text.split(""));
tv.setText(toString().valueOf(chars));
for(int i=0;i<chars.size();i++){
if(toString().valueOf(chars.get(i)) == " 1"){
Toast.makeText(this,"I found One",Toast.LENGTH_LONG).show();
//This if is not working while the TV's text shows " 1"
}
}
}
}
First, just a tip, from string to char[] you can use
char[] chars = myString.toCharArray();
because it has no sense to save a char array as a string ArrayList
but now the problem. you have your string and you wanna print the text between the numbers.
It's not really clear what is your goal but lets try.
I will suppose you used the char[] because it's 10 times better and easier
case 1) you wanna print text betweens "1"s
//lets loop the chars
bool firstOneFound = false;
int firstOccurrence = -1;
int secondOccurrence = -1;
int i = 0;
for(char c : chars){
//is it equals to 1?
if(c.equals('1')){
//check if we are already after the first 1
if(firstOneFound){
//if yes, we found the final one
secondOccurrence = i;
break;
}
else{
//this is the first occurrence
firstOccurrence = i;
firstOneFound = true;
}
}
i++;
}
if(firstOccurrence != -1 && secondOccurrence != -1){
String myFinalString = myString.subString(firstOccurrence, secondOccurrence);
}
case 2) you wanna print all text except numbers (maybe with a space instead)
for(char c : chars){
//check if it's a number
if(c >= '0' && c <= '9'){
//replace the number with anything else
c = ' '; //if you wanna have it as a space
}
}
//print the final string
String myFinalString = new String(chars);
NOTE:
You can also use ArrayList of string, just replace ' with "
hope it helps
I had a problem when I type the text I do not want the keyboard changes automatically, but after a space keyboard changes to the original state.
For example, I want to dial numbers that I move into this state the keyboard: But when I need to enter the number followed by a space, the keyboard itself is changed automatically:And it is necessary that the user himself can change the state of the keyboard, if it is necessary to enter characters. I use a mask on the text of Edit Text. With the help of this library set mask: MaskFormatter. an example of a mask: private static final String MASK = "99 AA 999999";
private EditText mInputCertificate;
#Override
public void setViews(View rootView, Bundle savedInstanceState) {
// Some code
mInputCertificate = (EditText) rootView.findViewById(R.id.input_car_certificate);
MaskFormatter maskFormatter = new MaskFormatter(MASK, mInputCertificate);
mInputCertificate.addTextChangedListener(maskFormatter);
}
There are ways to solve this problem?
I made my custom TextWatcher for EditText:
private String getString (String s) {
String newValue = s.replaceAll("\\s", "");
/*if (newValue.length() < 2 || newValue.length() >= 4) {
mEditText.setInputType(InputType.TYPE_CLASS_NUMBER);
} else {
mEditText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}*/
StringBuilder builder = new StringBuilder();
for (int i =0; i < newValue.length(); i++) {
if (i == 2 || i == 4) {
builder.append(' ');
builder.append(newValue.charAt(i));
} else {
builder.append(newValue.charAt(i));
}
}
return builder.toString();
}
#Override
public void afterTextChanged(Editable s) {
Log.d("EDITTEXT", "getEditable " + s);
String text = getString(s.toString());
mEditText.removeTextChangedListener(this);
mEditText.getText().clear();
mEditText.append(text.toUpperCase());
mEditText.addTextChangedListener(this);
mEditText.setSelection(mEditText.length());
}
This work for me. And I used .append(SomeText) instead .setText(SomeText).
i need to change the text="font roboto regular" to Font Roboto Regular in xml itself, how to do?
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18sp"
android:textColor="#android:color/black"
android:fontFamily="roboto-regular"
android:text="font roboto regular"
android:inputType="textCapWords"
android:capitalize="words"/>
If someone looking for kotlin way of doing this, then code becomes very simple and beautiful.
yourTextView.text = yourText.split(' ').joinToString(" ") { it.capitalize() }
You can use this code.
String str = "font roboto regular";
String[] strArray = str.split(" ");
StringBuilder builder = new StringBuilder();
for (String s : strArray) {
String cap = s.substring(0, 1).toUpperCase() + s.substring(1);
builder.append(cap + " ");
}
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(builder.toString());
Try this...
Method that convert first letter of each word in a string into an uppercase letter.
private String capitalize(String capString){
StringBuffer capBuffer = new StringBuffer();
Matcher capMatcher = Pattern.compile("([a-z])([a-z]*)", Pattern.CASE_INSENSITIVE).matcher(capString);
while (capMatcher.find()){
capMatcher.appendReplacement(capBuffer, capMatcher.group(1).toUpperCase() + capMatcher.group(2).toLowerCase());
}
return capMatcher.appendTail(capBuffer).toString();
}
Usage:
String chars = capitalize("hello dream world");
//textView.setText(chars);
System.out.println("Output: "+chars);
Result:
Output: Hello Dream World
KOTLIN
val strArrayOBJ = "Your String".split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val builder = StringBuilder()
for (s in strArrayOBJ) {
val cap = s.substring(0, 1).toUpperCase() + s.substring(1)
builder.append("$cap ")
}
txt_OBJ.text=builder.toString()
Modification on the accepted answer to clean out any existing capital letters and prevent the trailing space that the accepted answer leaves behind.
public static String capitalize(#NonNull String input) {
String[] words = input.toLowerCase().split(" ");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < words.length; i++) {
String word = words[i];
if (i > 0 && word.length() > 0) {
builder.append(" ");
}
String cap = word.substring(0, 1).toUpperCase() + word.substring(1);
builder.append(cap);
}
return builder.toString();
}
you can use this method to do it programmatically
public String wordFirstCap(String str)
{
String[] words = str.trim().split(" ");
StringBuilder ret = new StringBuilder();
for(int i = 0; i < words.length; i++)
{
if(words[i].trim().length() > 0)
{
Log.e("words[i].trim",""+words[i].trim().charAt(0));
ret.append(Character.toUpperCase(words[i].trim().charAt(0)));
ret.append(words[i].trim().substring(1));
if(i < words.length - 1) {
ret.append(' ');
}
}
}
return ret.toString();
}
refer this if you want to do it in xml.
You can use
private String capitalize(final String line) {
return Character.toUpperCase(line.charAt(0)) + line.substring(1);
}
refer this How to capitalize the first character of each word in a string
android:capitalize is deprecated.
Follow these steps: https://stackoverflow.com/a/31699306/4409113
Tap icon of ‘Settings’ on the Home screen of your Android Lollipop
Device
At the ‘Settings’ screen, scroll down to the PERSONAL section and
tap the ‘Language & input’ section.
At the ‘Language & input’ section, select your keyboard(which is
marked as current keyboard).
Now tap the ‘Preferences’.
Tap to check the ‘Auto – Capitalization’ to enable it.
And then it should work.
If it didn't, i'd rather to do that in Java.
https://stackoverflow.com/a/1149869/2725203
Have a look at ACL WordUtils.
WordUtils.capitalize("your string") == "Your String"
Another approach is to use StringTokenizer class. The below method works for any number of words in a sentence or in the EditText view. I used this to capitalize the full names field in an app.
public String capWordFirstLetter(String fullname)
{
String fname = "";
String s2;
StringTokenizer tokenizer = new StringTokenizer(fullname);
while (tokenizer.hasMoreTokens())
{
s2 = tokenizer.nextToken().toLowerCase();
if (fname.length() == 0)
fname += s2.substring(0, 1).toUpperCase() + s2.substring(1);
else
fname += " "+s2.substring(0, 1).toUpperCase() + s2.substring(1);
}
return fname;
}
in kotlin, string extension
fun String?.capitalizeText() = (this?.toLowerCase(Locale.getDefault())?.split(" ")?.joinToString(" ") { if (it.length <= 1) it else it.capitalize(Locale.getDefault()) }?.trimEnd())?.trim()
Kotlin extension function for capitalising each word
val String?.capitalizeEachWord
get() = (this?.lowercase(Locale.getDefault())?.split(" ")?.joinToString(" ") {
if (it.length <= 1) it else it.replaceFirstChar { firstChar ->
if (firstChar.isLowerCase()) firstChar.titlecase(
Locale.getDefault()
) else firstChar.toString()
}
}?.trimEnd())?.trim()
As the best way for achieving this used to be the capitalize() fun, but now it got depricated in kotlin. So we have an alternate for this. I've the use case where I'm getting a key from api that'll be customized at front end & will be shown apparently. The value is coming as "RECOMMENDED_OFFERS" which should be updated to be shown as "Recommended Offers".
I've created an extension function :
fun String.updateCapitalizedTextByRemovingUnderscore(specialChar: String): String
that takes a string which need to be replaced with white space (" ") & then customise the words as their 1st character would be in caps. So, the function body looks like :
fun String.updateCapitalizedTextByRemovingUnderscore(
specialChar: String = "") : String {
var tabName = this
// removing the special character coming in parameter & if
exist
if (spclChar.isNotEmpty() && this.contains(specialChar)) {
tabName = this.replace(spclChar, " ")
}
return tabName.lowercase().split(' ').joinToString(" ") {
it.replaceFirstChar { if (it.isLowerCase())
it.titlecase(Locale.getDefault()) else it.toString() } }
}
How to call the extension function :
textView.text =
"RECOMMENDED_OFFERS".updateCapitalizedTextByRemovingUnderscore("_")
OR
textView.text = <api_key>.updateCapitalizedTextByRemovingUnderscore("_")
The desired output will be :
Recommended Offers
Hope this will help.Happy coding :) Cheers!!
capitalize each word
public static String toTitleCase(String string) {
// Check if String is null
if (string == null) {
return null;
}
boolean whiteSpace = true;
StringBuilder builder = new StringBuilder(string); // String builder to store string
final int builderLength = builder.length();
// Loop through builder
for (int i = 0; i < builderLength; ++i) {
char c = builder.charAt(i); // Get character at builders position
if (whiteSpace) {
// Check if character is not white space
if (!Character.isWhitespace(c)) {
// Convert to title case and leave whitespace mode.
builder.setCharAt(i, Character.toTitleCase(c));
whiteSpace = false;
}
} else if (Character.isWhitespace(c)) {
whiteSpace = true; // Set character is white space
} else {
builder.setCharAt(i, Character.toLowerCase(c)); // Set character to lowercase
}
}
return builder.toString(); // Return builders text
}
use String to txt.setText(toTitleCase(stringVal))
don't use android:fontFamily to roboto-regular. hyphen not accept. please rename to roboto_regular.
To capitalize each word in a sentence use the below attribute in xml of that paticular textView.
android:inputType="textCapWords"
I'm new android/java programmer and I can't find anywhere how to set default varriable value only on first call. My console log delete after second call. My code looks like:
public class Ftp {
[...]
//Console
String console_strings[] = new String [15];
int console_line = 0;
//
[...]
public void drawConsole(String msg){
CharSequence time = DateFormat.format("hh:mm:ss", d.getTime());
String message = "["+time+"] "+msg;
TextView console = (TextView)((Activity)context).findViewById(R.id.console);
String newString = "";
for(int i = 0; i < console_strings.length; i++){
if(console_strings[i] != null)
newString += console_strings[i] + "\n";
else
{
console_strings[i] = message;
newString += console_strings[i] + "\n";
break;
}
}
console.setText(newString);
}
}
Whenever I want to add something to the console, it delete old text value.
There are multiple ways to do this. The problem you are having is that you are setting the entire textview's text at once. You could do one of a few things. You could do
console.setText(console.getText() + newString);
or
console.append(newString);
Both of these would work. There are multiple other ways, but those should do it for you.
TextView has also an append method
I have two identical views with a number of editTexts. In one, pre-defined answers are populated in the editTexts (but not shown to the user). In the second, the user starts with all blank editTexts, and then fills them out in an attempt to make them the same as the pre-defined answers.
So I want to loop through the user's view, checking it against the pre-defined one, until an inequality is found, in which case the method will return false.
My code is below. Inside the onCreate I have a buttonListener (when the user is ready to check answers)
btnSolution.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(checkAnswer() == true){
Toast.makeText(getBaseContext(), "all good!", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getBaseContext(), "no good", Toast.LENGTH_LONG).show();
}
}
});
the checkAnswer() method is then defined as follows
public boolean checkAnswer() {
final int ROW_COUNT = 15;
final int COL_COUNT = 10;
final String ROWS[] = {"R1","R2","R3","R4","R5","R6","R7","R8","R9","R10","R11","R12","R13","R14","R15"};
final String COLS[] = {"C1","C2","C3","C4","C5","C6","C7","C8","C9","C10"};
for(int i=0; i<ROW_COUNT; i++) {
for(int j=0; j<COL_COUNT; j++) {
String a = ROWS[i];
String b = COLS[j];
int editTextBaseId = getResources().getIdentifier("box" + a + b, "id", getPackageName());
int editTextAnswerId = getResources().getIdentifier("boxA" + a + b, "id", getPackageName());
EditText editTextBase = (EditText)findViewById(editTextBaseId);
EditText editTextAnswer = (EditText)findViewById(editTextAnswerId);
String textBase = editTextBase.getText().toString();
String textAnswer = editTextAnswer.getText().toString();
if(textBase.equals(textAnswer)) {
}
else {
return false;
}
}
}
return true;
}
Unfortunately when I try and run this I am getting a crash and the following error in my LogCat
12-17 00:05:02.075: E/SKIA(16370): FimgApiStretch:stretch failed
Any obvious errors?
That's not an error itself. I guess you're using a Samsung as your target device, if so, don't worry about it.
In the other hand, maybe it's better to compare only the strings. All those findViewById are inneficient.
Looking at your code:
EditText editTextAnswer = (EditText)findViewById(editTextAnswerId);
Do you have both views in the same layout, and the one with the answers is hidden? I mean, if you have the view with blank editTexts as the content of your activity, you can't find the editText with the answer as it's in other xml (assuming you did it as a different xml).