editText does not fill the entire column from gridLayout - android

I have a simple GridLayout which contains two textviews and two editexts on each row. The Gui is like this
I want both editexts to fill the entire free space from the gridLayout.
The gridLayout and the editexts are added programatically with the following code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ScrollView indexDefRootView = (ScrollView) rootView.findViewById(R.id.scrollViewContainer2);
GridLayout gridLayout = new GridLayout(getActivity());
gridLayout.setColumnCount(4);
gridLayout.setRowCount(20);
int tmpIndex = 0;
// Drawable drawable = getResources().getDrawable(R.drawable.backtextcom);
for (int i = 1; i < 20; i++) {
if (true) {
TextView tv = new TextView(getActivity());
tv.setPadding(60, 0, 10, 30);
Spec row = GridLayout.spec(tmpIndex);
Spec col = GridLayout.spec(0);
tv.setText("Left Text " +(i-1));
GridLayout.LayoutParams first = new GridLayout.LayoutParams(row, col);
gridLayout.addView(tv, first);
EditText editText1 = new EditText(getActivity());
//editText1.setBackground(drawable);
editText1.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
GridLayout.LayoutParams param = new GridLayout.LayoutParams();
param.height = ViewGroup.LayoutParams.WRAP_CONTENT;
param.width = GridLayout.LayoutParams.WRAP_CONTENT;
param.rowSpec = GridLayout.spec(tmpIndex);
param.columnSpec = GridLayout.spec(1);
editText1.setLayoutParams(param);
gridLayout.addView(editText1);
TextView tv1 = new TextView(getActivity());
tv1.setText("Right Text View "+i);
tv1.setPadding(60, 0, 10, 30);
row = GridLayout.spec(tmpIndex);
col = GridLayout.spec(2);
first = new GridLayout.LayoutParams(row, col);
gridLayout.addView(tv1, first);
EditText editText2 = new EditText(getActivity());
//editText2.setBackground(drawable);
editText2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
param = new GridLayout.LayoutParams();
param.height = ViewGroup.LayoutParams.WRAP_CONTENT;
param.width = GridLayout.LayoutParams.WRAP_CONTENT;
param.rowSpec = GridLayout.spec(tmpIndex);
param.columnSpec = GridLayout.spec(3);
editText2.setLayoutParams(param);
gridLayout.addView(editText2);
tmpIndex++;
i=i+2;
}
}
indexDefRootView.addView(gridLayout);
return rootView;
}
Any feedback will be appreciated.

Try these in your code
Change Width To match_parent in your code
param.width = GridLayout.LayoutParams.MATCH_PARENT;
Using XML is better way. Avoid Creating View unless Required

Related

GridLayout Items not visible in Nougat

I have to dynamically build views and I have used GridLayout as the parent layout to populate 2 views in a row. The code works perfectly fine in the platforms below Nougat. But in nougat version, the views are not populated.
Here is the code section below
private void populateAnswer(List<Answer> answerList, LinearLayout parent) {
GridLayout gridLayout = new GridLayout(context);
gridLayout.setBackgroundColor(getResources().getColor(android.R.color.holo_green_light));
gridLayout.setAlignmentMode(GridLayout.ALIGN_MARGINS);
GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams();
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
gridLayout.setLayoutParams(layoutParams);
gridLayout.setColumnCount(2);
Answer temp;
RadioGroup radioGroup = new RadioGroup(context);
if (answerList != null) {
for (int i = 0; i < answerList.size(); i++) {
temp = answerList.get(i);
if (temp.getaType().equals(RADIO_BUTTON)) {
RadioButton radioButton = new RadioButton(context);
radioButton.setTextColor(getResources().getColor(R.color.colorPrimary));
radioButton.setHighlightColor(getResources().getColor(R.color.colorPrimary));
GridLayout.LayoutParams rbLayoutParams = new GridLayout.LayoutParams();
rbLayoutParams.setGravity(Gravity.CENTER);
rbLayoutParams.height = GridLayout.LayoutParams.WRAP_CONTENT;
rbLayoutParams.width = GridLayout.LayoutParams.MATCH_PARENT;
radioButton.setLayoutParams(rbLayoutParams);
radioButton.setText(temp.getaDesc());
radioGroup.addView(radioButton);
} else if (temp.getaType().equals(CHECK_BOX)) {
CheckBox checkBox = new CheckBox(context);
checkBox.setTextColor(getResources().getColor(R.color.colorPrimary));
checkBox.setHighlightColor(getResources().getColor(R.color.colorPrimary));
checkBox.setText(temp.getaDesc());
gridLayout.addView(checkBox);
} else if (temp.getaType().equals(FREE_TEXT)) {
EditText editText = new EditText(context);
editText.setHint(temp.getaDesc());
editText.setHintTextColor(getResources().getColor(android.R.color.darker_gray));
gridLayout.addView(editText);
}
}
}
if (radioGroup.getChildCount() > 0) {
gridLayout.addView(radioGroup);
}
parent.addView(gridLayout);
}
I have attached the screenshots for different devices.
Using:
GridLayout.LayoutParams layoutParams = new ViewGroup.LayoutParams();
instead of:
GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams();

TextView on the right of dynamically created Buttons

As seen in the picture, everything works fine except that myTextView, instead of appearing just on the right of the last Button, it does on top of 16, 17 and 18. I can’t manage these 3 Buttons to appear bellow the rest. Here is my essential code, where I create dynamically the Buttons and myTextView:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout layout = (LinearLayout) findViewById(R.id.layout1); // id del XML
layout.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < 4; i++) {
LinearLayout fila = new LinearLayout(this);
fila.setLayoutParams(new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
for (int j = 0; j < 5; j++) {
if (i==3 && j==3){
TextView myTextView = new TextView(this);
LinearLayout.LayoutParams layoutParams=newLinearLayout.LayoutParams(490, 40);
layoutParams.setMargins(870, 30, 0, 0);
myTextView.setTextSize(26);
myTextView.setLayoutParams(layoutParams);
layout.addView(myTextView);
break;
}
Button btnTag = new Button(this); //
btnTag.setBackgroundColor(Color.TRANSPARENT);
btnTag.setLayoutParams(new LinearLayout.LayoutParams(255, 166));
fila.addView(btnTag);
btnTag.setId(j + 1 + (i * 5));
btnTag.setOnClickListener(prueba);
}
layout.addView(fila);
}
}
At last I have solved the problem. Instead of a LinearLayout I have to use a RelativeLayout. Like this, I can set the TextView wherever I want on the screen throughout the xml. Here is the code, where with rel_btn I set the Buttons wherever I want, too:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout1); // id del XML
for (int i = 1; i < 19; i++) {
RelativeLayout.LayoutParams rel_btn = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
switch(i) {
case 1: rel_btn.leftMargin = 0; rel_btn.topMargin = 0; break;
case 2: rel_btn.leftMargin = 255; rel_btn.topMargin = 0; break;
case 3: rel_btn.leftMargin = 510; rel_btn.topMargin = 0; break;
…… as many as Buttons requiered
}
rel_btn.width = 255; rel_btn.height = 165;
Button btnTag = new Button(this);
btnTag.setLayoutParams(rel_btn);
btnTag.setBackgroundColor(Color.TRANSPARENT);
btnTag.setId(0+i); // les pone el ID
btnTag.setOnClickListener(prueba);
layout.addView(btnTag);
}
}
1. Set layout weight sum
fila.setWeightSum(5);
2. Set width = 0dp and weight = 1 for all buttons
btnTag.setLayoutParams(new LinearLayout.LayoutParams(0, 166, weight));
3. Set width=0dp and weight = 2 for textview
LinearLayout.LayoutParams layoutParams= new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40);
layoutParams.weight = 2;
//layoutParams.setMargins(870, 30, 0, 0);
myTextView.setTextSize(26);
myTextView.setLayoutParams(layoutParams);
Updated onCreate method
public void onCreate(Bundle savedInstanceState) {
LinearLayout layout = (LinearLayout) findViewById(R.id.layout1); // id del XML
layout.setOrientation(LinearLayout.VERTICAL);
int width = 0; //0dp, we will use weight to set width
int weight = 1;
for (int i = 0; i < 4; i++) {
LinearLayout fila = new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, weight);
fila.setLayoutParams(params);
fila.setWeightSum(5);
for (int j = 0; j < 5; j++) {
if (i==3 && j==3){
TextView myTextView = new TextView(this);
LinearLayout.LayoutParams layoutParams= new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40);
layoutParams.weight = 2;
//layoutParams.setMargins(870, 30, 0, 0);
myTextView.setTextSize(26);
myTextView.setLayoutParams(layoutParams);
layout.addView(myTextView);
break;
}
Button btnTag = new Button(this); //
btnTag.setBackgroundColor(Color.TRANSPARENT);
btnTag.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 166, weight));
fila.addView(btnTag);
btnTag.setId(j + 1 + (i * 5));
btnTag.setOnClickListener(prueba);
}
layout.addView(fila);
}
}

Add multiple text views programmatically in Android

Here I have to add text view programmatically based on array list size. Text views should be appear in row like continues pattern...
eg. tv1, tv2, tv3 and so on till the size of array list.
But here I am getting text views which are appearing on each other. I can't read the text on them. Here is my code:
ArrayList<String> languageNames = new ArrayList<String>();
RelativeLayout rl = (RelativeLayout)findViewById(R.id.rl);
if(languageNames.size()>0)
{
int size = languageNames.size();
TextView[] tv = new TextView[size];
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
p.addRule(RelativeLayout.BELOW, tvLocation.getId());
for(int i=0; i<size; i++)
{
tv[i] = new TextView(getBaseContext());
tv[i].setText(languageNames.get(i).toString());
tv[i].setLayoutParams(p);
tv[i].setPadding(50, 50, 0, 0);
tv[i].setTextColor(Color.parseColor("#000000"));
rl.addView(tv[i]);
}
}
else
{
}
what needs to be done so that I can get text views in appropriate manner?
Add buttons inside a LinearLayout and add this LinearLayout in the RelativeLayout.
RelativeLayout r1 = (RelativeLayout) findViewById(R.id.r1);
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
p.addRule(RelativeLayout.BELOW, tvLocation.getId());
LinearLayout LL = new LinearLayout(getBaseContext());
LL.setOrientation(LinearLayout.VERTICAL);
for (int i=0;i< size;i++) {
tv[i] = new TextView(getBaseContext());
tv[i].setText(languageNames.get(i).toString());
tv[i].setPadding(50, 50, 0, 0);
tv[i].setTextColor(Color.parseColor("#000000"));
LL.addView(tv);
}
r1.addview(LL, p);
Try this code:
LinearLayout rl = (LinearLayout)findViewById(R.id.mainLayout);
TextView[] tv = new TextView[10];
for(int i=0; i<10; i++)
{
tv[i] = new TextView(getBaseContext());
tv[i].setText("TextView "+ i);
tv[i].setPadding(50, 50, 0, 0);
tv[i].setTextColor(Color.parseColor("#000000"));
rl.addView(tv[i]);
}
Hope this will help you

Re-Adding views to a fragment on onResume returns an IllegalStateException

I'm developing an Android 3.1 Tablet application with fragments.
I've seen that only two fragments are on memory at the same time. When I show a third one, first one calls onDestroyView.
I add EditText to fragment's view programmatically. Those EditText don't show again after fragment's view recreation on onResume method.
I use those EditText to let users add data to a form and I store a reference in firstTable HashMap. I will use that HashMap to retrieve user's values.
Here I create those EditText programmatically:
private LinearLayout createNewFirstTableRow(long articleId)
{
LinearLayout layout = new LinearLayout(mActivity);
LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
parentParams.weight = 1;
layout.setLayoutParams(parentParams);
if (firstTable == null)
firstTable = new HashMap<Long, ArrayList<EditText>>();
ArrayList<EditText> fields = new ArrayList<EditText>(7);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int i = 0; i < 7; i++)
{
EditText edit = new EditText(mActivity);
edit.setLayoutParams(params);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
fields.add(i, edit);
layout.addView(edit);
}
firstTable.put(new Long(articleId), fields);
return layout;
}
firstTable variable is a global variable: private HashMap<Long, ArrayList<EditText>> firstTable;.
To add my EditText I do the following on onResume:
#Override
public void onResume()
{
Log.v("QuantityFragment", "onResume: " + firstTableRowIndex);
if ((firstTable != null) && (secondTable != null))
{
firstTableRowIndex = FIRST_TABLE_ROW_INDEX;
secondTableRowIndex = SECOND_TABLE_ROW_INDEX;
LinearLayout table = (LinearLayout)view.findViewById(R.id.quantityTable);
for (int index = 0; index < firstTable.size(); index++)
{
Long articleId = articleIds.get(index);
table.addView(resumeTable(articleId, secondTable.get(articleId)), secondTableRowIndex);
table.addView(resumeTable(articleId, firstTable.get(articleId)), firstTableRowIndex);
firstTableRowIndex++;
secondTableRowIndex++;
}
}
super.onResume();
}
private LinearLayout resumeTable(Long articleId, ArrayList<EditText> fields)
{
LinearLayout layout = new LinearLayout(mActivity);
LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
parentParams.weight = 1;
layout.setLayoutParams(parentParams);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int index = 0; index < fields.size(); index++)
{
layout.addView(fields.get(index));
}
return layout;
}
But, here layout.addView(textView); I get an exception:
IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Is there another way to re-add those EditText?
UPDATE:
I have solved my problem changing resumeTable:
private LinearLayout resumeTable(Long articleId, ArrayList<EditText> fields)
{
LinearLayout layout = new LinearLayout(mActivity);
LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
parentParams.weight = 1;
layout.setLayoutParams(parentParams);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int index = 0; index < fields.size(); index++)
{
LinearLayout parent = (LinearLayout)fields.get(index).getParent();
parent.removeView(fields.get(index));
layout.addView(fields.get(index));
}
return layout;
}
This is the important part:
for (int index = 0; index < fields.size(); index++)
{
LinearLayout parent = (LinearLayout)fields.get(index).getParent();
parent.removeView(fields.get(index));
layout.addView(fields.get(index));
}
The question is open, if you have a better solution, please, let me know.
That exception is thrown because you store references to Views(the EditText) that were added to the layout and then later you're again re-adding those Views to a newly constructed parent.
Regarding a solution, I don't know why you decided to store references to those EditTexts. The only data that I see worth storing from those EditTexts is the text entered by the user, in which case you should store that text instead of that particular EditText .Your method would be:
//...
if (firstTable == null) {
// your HashMap now stores text instead of an EditText
firstTable = new HashMap<Long, ArrayList<String>>();// store only the text from the EditText
}
ArrayList<String> fields = new ArrayList<String>(7);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int i = 0; i < 7; i++) {
EditText edit = new EditText(mActivity);
edit.setLayoutParams(params);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
fields.add(i, ""); // the EditText are empty at first
layout.addView(edit);
}
firstTable.put(new Long(articleId), fields);
Then when is time to restore the EditTexts:
private LinearLayout resumeTable(Long articleId, ArrayList<String> fields) {
LinearLayout layout = new LinearLayout(mActivity);
LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
parentParams.weight = 1;
layout.setLayoutParams(parentParams);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int index = 0; index < fields.size(); index++) {
// create new EditTexts
EditText edit = new EditText(mActivity);
edit.setLayoutParams(params);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
edit.setText(fields.get(index)); // get the text coresponding to this particular EditText
layout.addView(edit);
}
return layout;
}
Of course when the user enters something in the EditTexts you should store it in the firstTable variable at the right position.
I think problen is due to adding the element of fields twice
ArrayList<EditText> fields = new ArrayList<EditText>(7);
1 - in createNewFirstTableRow
for (int i = 0; i < 7; i++)
{
EditText edit = new EditText(mActivity);
edit.setLayoutParams(params);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
fields.add(i, edit);//<-----------
layout.addView(edit);//<----------- added in layout
}
2- onResume()->resumeTable
for (int index = 0; index < fields.size(); index++)
{
layout.addView(fields.get(index));//<----------------
}
when fields element alreay added on the screen you can't add that twice.......

Dynamic TextView in Relative layout

I am triying to use dynamic layout for comment part of my project but when i settext of textview dynamicly the output only appears in top of the screen. And it puts the output over the other outputs
RelativeLayout ll=(RelativeLayout) findViewById(R.id.rl);
for(int i = 0; i < 20; i++) {
TextView cb = new TextView(this);
cb.setText("YORUMLAR"+yorum[0]+i);
cb.setTextSize(30);
ll.addView(cb);
}
So how can i put the output on the bottom of the screen linearly.
You should use LinearLayout to automatically add one TextView after another.
Assuming you can't live without RelativeLayout, you'll need to dynamically generate ids for all TextView you create in order to put one view under another. Here is example:
public class HelloWorld extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
RelativeLayout layout = (RelativeLayout)findViewById(R.id.layout);
Random rnd = new Random();
int prevTextViewId = 0;
for(int i = 0; i < 10; i++)
{
final TextView textView = new TextView(this);
textView.setText("Text "+i);
textView.setTextColor(rnd.nextInt() | 0xff000000);
int curTextViewId = prevTextViewId + 1;
textView.setId(curTextViewId);
final RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, prevTextViewId);
textView.setLayoutParams(params);
prevTextViewId = curTextViewId;
layout.addView(textView, params);
}
}
}
You've to provide the location of your newly added view. As #Adinia said, with no position, it will be aligned to the top by default. So you can use the following code to do it with RelativeLayout;
RelativeLayout containerLayout = (RelativeLayout) findViewById(R.id.container);
for (int i = 0; i < 20; i++) {
TextView dynaText = new TextView(this);
dynaText.setText("Some text " + i);
dynaText.setTextSize(30);
// Set the location of your textView.
dynaText.setPadding(0, (i * 30), 0, 0);
containerLayout.addView(dynaText);
}
If you want to show multiple textviews one after the other, then you should go with LinearLayout.
You may also add Dynamic textview to relative layout. Here with i have attached some code this may help you.
RelativeLayout ll=(RelativeLayout) findViewById(R.id.rl);
for(int i = 0; i < 20; i++)
{
TextView cb = new TextView(this);
cb.setText("YORUMLAR"+yorum[0]+i);
cb.setTextSize(30);
cb.setId(2000+i);
RelativeLayout.LayoutParams TextViewLayoutParams = new RelativeLayout.LayoutParams(100,100);
if (i != 0 )DispViewLayoutParams.addRule(RelativeLayout.BELOW, 2000 - (i-1));
ll.addView(cb,TextViewLayoutParams);
}

Categories

Resources