Creating TextViews in Android with an array - java

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" />

Related

I want to add Edit Text dynamically not more not less than 5 Edit Texts in android java

I need to add 5 Input fields (EditText) dynamically one by one on button click and want to take values from them and store them into database using Room Persistence with MVVM.
Here I'm adding the view dynamically
private void addEditTextView() {
View inputView = getLayoutInflater().inflate(R.layout.row_edit_text, null, false);
EditText val1 = inputView.findViewById(R.id.input_value_1);
binding.layoutList.addView(inputView);
}
Any suggestion would be very helpful.
Thank you in advance.
Add view based on child count
private void addEditTextView() {
if (binding.layoutList.getChildCount() <= 5) {
View inputView = getLayoutInflater().inflate(R.layout.row_edit_text, null, false);
EditText val1 = inputView.findViewById(R.id.input_value_1);
binding.layoutList.addView(inputView);
}
}
"When I clicked Add button it is adding input field one by one, this code is working but I just want to limit for 5 fields not more not less and take values from them."
If you want to add exactly 5 fields on button click I recommend designing a fragment with the 5 fields in place, then when the button is clicked, inflate the fragment into your parent view. Then code the fragment appropriately with the data you're working with.
Then if you wanted, you could deflate the fragment on button click to clear the view or add some other way to clear the fragment when you want. Much easier than what you're doing currently in my own opinion.
You might as well include a submit button in your fragment assuming this is some kind of form.
You can simply define an integer and increase it every time you add the EditText but you should check if your integer is less than 5 everytime the method is called.
Example
private void addEditTextView() {
int count = 0;
if (count < 5){
View inputView = getLayoutInflater().inflate(R.layout.row_edit_text, null, false);
EditText val1 = inputView.findViewById(R.id.input_value_1);
binding.layoutList.addView(inputView);
count++;
}
}

How can I programmatically generate textviews inside layout

I need to generate TextView inside a layout from a random, API generated, ArrayList. I cant seem to find a way in which they appear in one line, like a String, one after the other and also shift below once the line has reached the max layout width limit. I want each TextView to be sperate as I want to click them.
Would like to achieve something like this...
This is the current code but the line stops and I don't know how to shift it below. Currently I am using a relative layout as the base layout but it is not necessary.
for (int i = 0; i < abc.size(); i++) {
titleText = new TextView(this);
titleText.setId(i);
titleText.setText(abc.get(i));
relativeLayout.addView(titleText, i);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 10, 10, 10);
layoutParams.addRule(RelativeLayout.RIGHT_OF, titleText.getId() - 1);
titleText.setLayoutParams(layoutParams);
titleText.setTextColor(getResources().getColor(R.color.teal_700));
tvArray.add(titleText);
}
Example
In your xml
<LinearLayout
android:id="#+id/my_ll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
And write code in yourjava.class
LinearLayout my_ll = (LinearLayout) findViewById(R.id.my_ll);
for(int i=0;i<your_number_of_textviews;i++)
{
TextView text = new TextView(this);
text.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
text.setText(""+i);
my_ll.addView(text);
}
I think this solution would have solved it. First before the loop retrieve somewhere the width of the screen by using -
Point screenSizePoint = new Point();
// this gives you the furthest point from 0,0 e.g. 1440x3168
getWindowManager().getDefaultDisplay().getSize(screenSizePoint);
int sum = 0;
Then you retrieve your abc list somewhere.
And then you always compute the width of the current TextView by using this
titleText.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int width = titleText.getMeasuredWidth();
sum += width;
if (sum >= screenSizePoint.x) {
// shift to next line
}
and sum it up with the width of text views placed before and if the width is bigger than the screen width you just begin on another line.

Outputting editText and textViews based off user input?

I was wondering if it was possible to ouput xml elements such as editText and textView based off user input. For example I'm making a simple game app and in the app you get taken to a new activity where it asks the amount of players. Based off the input (e.g. 5) I woulld like to display editText's and textViews so the players can be given names. Is this possible with Java and if so, how?
Sure is, though without having to go through XML.
Pass the number of players to the next activity as an argument. Then make sure you have a ViewGroup (LinearLayout for example) in the second activity's layout.
Then loop through and create the Views dynamically:
ViewGroup container = findViewById(R.id.linearLayout);
for( int i = 0; i < numberOfPlayers; i++ ){
EditText et = new EditText(this);
et.setHint(R.string.new_player_hint);// String providing a hint to the user
container.addView(et);
}
You can put the EditTexts in a List or if that's all you'll have you can directly cycle over the ViewGroup's children to get their values later on:
for( int i = 0; i < container.getChildCount(); i++ ){
String playerName = ((EditText) container.getChildAt(i)).getText().toString();
}
If you're going to have many possible players you should wrap the LinearLayout in a ScrollView.
Because you'll likely use this in onCreate remember that you can't rely on the EditText to save its own data in case the Activity is destroyed, so save them yourself and feed them back in when re-creating.

ListView with different number of TextViews in every row

I have a chat functionality in my app and I want to group sequential messages from the same user, something similar to that picture bellow:
So, I have my message_row.xml with one TextView to display the content of one message. My Message model has an ArrayList with all the sequential messages from the same user.
My CustomMessageAdapter.java looks like that:
if (inflater == null) {
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
// [...]
if (getItemViewType(position) == MINE) {
convertView = inflater.inflate(R.layout.my_message_row, null);
} else {
convertView = inflater.inflate(R.layout.message_row, null);
}
// [...]
TextView senderName = (TextView) convertView.findViewById(R.id.senderName);
TextView content = (TextView) convertView.findViewById(R.id.content);
senderName.setText(message.getSenderName());
//I want to do something like this:
for (int i = 0; i < message.getMessages().size(); i++) {
// display a different TextView for each different message...
}
// [...]
return convertView;
What I cannot do is display a new TextView for each different messages in messages arraylist.
As inflating view classes is expensive and updating them can also be expensive it would be wise to take a simpler approach to this problem. I would suggest simply concatenating the strings with newlines delimiters and apply the entirety to the message.
Further Thoughts
Should you need complex control over the display of the text, consider using Spannable to format your text inside a single TextView.
http://developer.android.com/reference/android/text/Spannable.html
As demonstrated here: Is there any example about Spanned and Spannable text
spanbuffer = new TextView(context);
spanbuffer.setText(newText, TextView.BufferType.SPANNABLE);
Spannable s = (Spannable) spanbuffer.getText();
s.setSpan(new ForegroundColorSpan(Color.RED), 0, newText.length() - 1, 0);
this.append(s);
You can control several text attributes in this manner.
I would suggest in your message_row.xml instead of inflating TextView inflate linear layout and in that linear layout add TextViews programmatically for each iteration in
for (int i = 0; i < message.getMessages().size(); i++) {
// display a different TextView for each different message...
}
But, since inflating is expensive i would suggest to split your messages with new row and add them all in one TextView.
in your array create a id for two persons of conversation when you paint in the adapter indentify waths id is and paint the texview corresponding something like this:
if (iduser.equals("1")){ textviewUser.setText("some text");}else{texviewOther.setText("sometext")}
add dynamic textview to your row,
private void createTextView(LayoutInflater inflater, LinearLayout llTv) {
llTv.removeAllViews();
int i = 0;
while (i < mMessages.size()) {
View llTv= inflater.inflate(R.layout.textTtem, llTv, false);
TextView textView = (TextView) llTv.findViewById(R.id.tv_message);
textView.setText(mMessage.get(i).getMesage());
textView.setOnClickListener(this);
llTv.addView(textView);
i++;
}
}
your textitem should look like this,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical">
<TextView
android:id="#+id/tv_message"
android:layout_width="match_parent"
android:padding="..."
android:layout_margin="..."
android:layout_height="wrap_content"
android:textSize="14sp"/>
</LinearLayout>
you can send inflater like this:
mInflater = LayoutInflater.from(mContext);

Is it possible to create a list of form fields from an array in Android?

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);
}

Categories