I'm trying to create a fill the gap game in Android Studio with Java, for that I'm taking a sentence, separating the keyword (to fill by the user) from the String, and adding the Strings as follow in a horizontal LinearLayout (within a vertical Layout):
TextView before keyword + TextView keyword + TextView after keyword
In a different LinearLayout below I have a following TextView (TextView Line3) making a second line with the same width as the horizontal LinearLayout above. -- Something like a line 2
As TextView after keyword is too long and makes a second line starting after the "TextView keyword", I want to take what goes to the second line of "TextView after keyword" and move it to "TextView Line3".
The problem is that it keeps saying there is only 1 line and "TextView after keyword" displays two
I defined them as such:
private TextView firstSentence, secondSentence, thirdSentence;
public TextView answerText;
private String sentence = "I do not like anyone in this world of idiots";
private boolean newLineBoolean = true;
private String keyword = "like";
private String[] sentenceDivision;
private String displayForKeyword = "";
private String thirdLine = "";
this in onCreate
answerText = findViewById(R.id.answerPlace);
firstSentence = findViewById(R.id.firstSentence);
secondSentence = findViewById(R.id.secondSentence);
thirdSentence = findViewById(R.id.thirdSentence);
sentenceDivision = sentence.split(keyword);
firstSentence.setText(sentenceDivision[0]);
secondSentence.setText(sentenceDivision[1]);
for(int i = 0; i<keyword.length();i++)
{
displayForKeyword = displayForKeyword + " ";
}
answerText.setText(displayForKeyword);
checkNumberOfLines();
And this method
private void checkNumberOfLines(){
String firstWords = sentenceDivision[1].substring(0, sentenceDivision[1].lastIndexOf(" "));
String lastWord = sentenceDivision[1].substring(sentenceDivision[1].lastIndexOf(" ") + 1);
sentenceDivision[1] = firstWords;
thirdLine = lastWord + " " + thirdLine;
secondSentence.setText(sentenceDivision[1]);
thirdSentence.setText(thirdLine);
secondSentence.post(new Runnable() {
#Override
public void run() {
int lineCount = secondSentence.getLineCount();
if (lineCount > 0) {
checkNumberOfLines();
}
else{ newLineBoolean = false;
}
}
});
}
But it displays as follows:
enter image description here
Does someone know why? Thanks in advance!
It might be because of the definition of TextView.getLineCount()
public int getLineCount() {
return mLayout != null ? mLayout.getLineCount() : 0;
}
if mLayout is a BoringLayout then getLineCount() always returns 1.
To use a different kind of text layout (DynamicLayout) that actually computes its line count, you could try either to make the text selectable by calling setTextIsSelectable or set a Spannable instead of a CharSequence in the TextView (see makeSingleLayout).
I agree with your sentence and this is not the best solution for your use case for which you might get less trouble by using something like a FlowLayout instead of the LinearLayouts and placing each word inside a separate TextView.
Edit to answer questions in comment
After adding the FlowLayout to the activity's layout xml you can create the TextViews for the words in the sentence dynamically:
// in onCreate()
FlowLayout flowLayout = findViewById(R.id.flow_id);
String[] words = sentence.split(" ");
TextView wordText;
for (int i = 0; i < words.length; i++) {
String word = words[i];
//if an edit text is needed for user input
if (i == keywordIndex) {
wordText = new EditText(this);
wordText.setHint("____");
} else {
wordText = new TextView(this);
wordText.setText(word);
}
wordText.setTextColor(getResources()
.getColor(R.color.your_color));
wordText.setBackgroundColor(getResources()
.getColor(android.R.color.white));
flowLayout.add(wordText);
}
Yes, you could use a RecyclerView with a GridLayoutManager or StaggeredGridLayoutManager to layout the views for the sentence words but it would require creating a RecyclerView.Adapter. But I think the RecyclerView would be more suitable for displaying a vertical set of
sentences (as FlowLayouts for example).
Related
guys.
I need a little bit inspiration right here. I want to create an application that have a highlight feature, just like screenshot below. But, I don't have an idea how to do this. I think Spannable TextView only can't just help me. Do you have some idea?
Thank you.
Example of highlight menu in Medium App
You can use SpannableString
To highlight specific text use this method.
private void highlightString(String input) {
//Get the text from text view and create a spannable string
SpannableString spannableString = new SpannableString(mTextView.getText());
//Get the previous spans and remove them
BackgroundColorSpan[] backgroundSpans = spannableString.getSpans(0, spannableString.length(), BackgroundColorSpan.class);
for (BackgroundColorSpan span: backgroundSpans) {
spannableString.removeSpan(span);
}
//Search for all occurrences of the keyword in the string
int indexOfKeyword = spannableString.toString().indexOf(input);
while (indexOfKeyword > 0) {
//Create a background color span on the keyword
spannableString.setSpan(new BackgroundColorSpan(Color.YELLOW), indexOfKeyword, indexOfKeyword + input.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//Get the next index of the keyword
indexOfKeyword = spannableString.toString().indexOf(input, indexOfKeyword + input.length());
}
//Set the final text on TextView
mTextView.setText(spannableString);}
I am developing my first Android app. I have a table layout in my app, which will add rows dynamically. But, I want to convert the table rows into string. I tried "row.toString()" but I am not getting the expected result. Please find the following code snippet:
View view = null;
for(i = 0, j = tblayout.getChildCount(); i < j; i++)
{
view = tblayout.getChildAt(i);
TableRow rw = (TableRow)tblayout.getChildAt(i);
ColorDrawable viewColor = (ColorDrawable) view.getBackground();
int colorId = viewColor.getColor();
if(colorId == Color.parseColor("#E143ED23")) {
num ++;
//temCnt = view.toString();
temCnt = rw.toString();
}
}
Toast.makeText(getApplicationContext(),temCnt, Toast.LENGTH_LONG).show();
But it is not showing the actual table row data. It is showing some ids' or garbage value.
My requirement is:
I have 2 text boxes and 2 buttons. When the first button "Ok" is pressed the value inside the text boxes will be populated into the Table layout along with a checkbox. By default the row will be checked. But user can uncheck each items. After that, when the second button "Save All" is pressed, then it will search for all the table rows which are checked and it should insert the table rows into the my MS SQL table.
Is there any way for converting the table row into a string in Java? I really trapped on this. It would be very helpful if someone can help me on this.
Please help...
toString() is a very basic method in Java, C# and other programming languages. Java's Object class has a basic implementation for it and you can override this method in any class that inherits from Object (that is, every class whatsoever :)). I don't know if those that developed the TableRow class of Android have overridden this method. It could be that what you're getting is some unreadable, meaningless representation of a TableRow object.
Let's say you have a TextView called txtName within the TableRow, followed by a second TextView called txtNumber. You can get what you want by doing the following:
...
ColorDrawable viewColor = (ColorDrawable) view.getBackground();
int colorId = viewColor.getColor();
if(colorId == Color.parseColor("#E143ED23")) {
num ++;
//temCnt = view.toString();
TextView nameField = (TextView) rw.findViewById(R.id.txtName);
TextView numberField = (TextView) rw.findViewById(R.id.txtNumber);
temCnt = nameField.getText().toString() + ": " + numberField.getText().toString();
}
...
For example, given:
String[] formFields = {"name","description","notes"};
Can I create a list of EditText fields in Android using that array instead of hard coding the EditText fields?
You can do something like this:
String[] array = new String[] { "A", "B", "C" };
int previousId = 0;
// Loop through all the Strings in the array
for(int i = 0; i < array.length; i++) {
// Get the text from the array
String text = array[i];
// Create a new EditText
EditText editText = new EditText(context);
// To add the Rules for the position of the views later on we need to define an id.
// In this case I assign the index in the array as Id, but in your app you should define
// ids in values/ids.xml like this: <item name="firstEditText" type="id" /> and use these
editText.setId(i + 1);
// Set the text for the new EditText
editText.setText(text);
// Create the LayoutParams
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// Add the rules where to place the view.
if(i == 0) {
// The first EditText will be placed at the top of the parent.
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
} else {
// All EditTexts after the first one are placed below the previous one.
params.addRule(RelativeLayout.BELOW, previousId);
}
// We save the id of this EditText so we can position the next EditText below it.
previousId = editText.getId();
// Add the view to your layout - in this case a RelativeLayout - with the LayoutParams we defined above
relativeLayout.addView(editText, params);
}
I've run into a little problem.
In my GUI, I have a text area in the center (BorderLayout). Then I have a JList on the West.
When I click on a member of the song titles I have in my list, the text area should display the title, artist, and price of the song.
I have everything working, but the problem is that when I click on a member, the title,artist, and the price is displayed TWICE.
Here is the code for "valueChanged()" and parts of codes relevant.
public void valueChanged(ListSelectionEvent e)
{
Object source = e.getSource();
int index = songList.getSelectedIndex();
Song selection = songCollection[index];
if(source == songList)
{
textArea.append(selection.getTitle() + " " + selection.getArtist() + " " + selection.getPrice() + "\n" );
}
}
private Song songCollection[] = new Song[5];
private String songTitle[] = new String[5];
//Fill song array
songCollection = getSongs();
songTitle = getSongTitle();
//Methods:
public Song[] getSongs()
{
Song[] array = new Song[5];
array[0] = new Song("Summer", "Mozart", 1.50);
array[1] = new Song("Winter", "Mozart", 1.25);
array[2] = new Song("Spring", "Mozart", 2.00);
array[3] = new Song("Baby", "Justin Bieber", 0.50);
array[4] = new Song("Firework", "Katy Perry", 1.00);
return array;
}
public String[] getSongTitle()
{
String[] names = new String[5];
for(int i = 0; i < 5; i++)
names[i] = songCollection[i].getTitle();
return names;
}
I noticed something just now when I was fiddling around with my program again. When I press a member in the list, it is still printed TWICE like before. However, I noticed that it prints once when I press and hold down my mouse, and it prints AGAIN when I let go of it. So if I press my mouse on 1 member, and drag the cursor up/down to other members, they print once, but when I let go of the mouse, it prints the one I ended in one more time.
JTextArea.append() is being called twice from your ListSelectionListener.
The reason can be found in How to Use Lists:
Many list selection events can be generated from a single user action such as a mouse click. The getValueIsAdjusting method returns true if the user is still manipulating the selection. This particular program is interested only in the final result of the user's action, so the valueChanged method does something only if getValueIsAdjusting returns false.
You need to check that the selection in the JList is no longer being manipulated. You can surround the append method with the check:
if (!e.getValueIsAdjusting()) {
textArea.append(...);
}
Alright, I'm trying to create textviews dynamically with strings i have in an array. Everything works right now besides when i create the textviews instead of them going down they each stay on the same line and run off the screen. I want each textview i create under the next. Code Below works just need it to create under the next instead all on one line.
public void GenList(){
DataBase entry = new DataBase(this);
entry.open();
String data = entry.getData();
int datanumber = entry.FindShit();
if(datanumber == 0 || datanumber == 1){
setContentView(R.layout.nowordlist);
}else{
int length = entry.results.length;
View linearLayout = findViewById(R.id.sayLinear);
for(int i=0;i<length;i++)
{
TextView value = new TextView(this);
value.setText(entry.results[i]);
value.setId(i);
value.setTextSize(50);
value.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
((LinearLayout) linearLayout).addView(value);
}
}
}
You'll need to change the orientation of the LinearLayout (R.id.sayLinear) you're adding the TextViews to. By default the orientation is set to 'horizontal', which will make the TextViews appear next to each other on a single line. Try changing it to 'vertical':
<LinearLayout
<!-- other attributes -->
android:orientation="vertical" />