Dynamically add UI content in android - android

I have an android app which asks a question followed by x number of options.
Each option contains a textview, ImageView and a radio button.
The value of x (i.e. the number of options) is not constant. I want to dynamically add UI content to satisfy this requirement.
At the moment I have written the code in the layout's xml to display a maximum of 4 options. If number of options is 2 I hide the options 3 and 4 using something like
tvoption1.setVisibility(View.GONE);
tvoption2.setVisibility(View.GONE);
However this is not very scalable. Can anyone tell me how to add options for java dynamically. Or is there a better approach?

A View can be added at runtime by using the inflater like this:
LinearLayout linearLayout = (LinearLayout)inflater.inflate(R.layout.news_categories_item, null);
TextView categoryValueTextView = (TextView)linearLayout.findViewById(R.id.news_category_item_value);
mMainLinearLayout.addView(categoryValueTextView);
In this example, a LinearLayout containing a TextView is inflated. A reference to the constituent TextView is then obtained, and the TextView is dynamically added (at runtime) to the main linear layout (mMainLinearLayout).
The inflater object may be obtained in an Activity by using getLayoutInflater().

create your row layout separately, from the main xml
Get LayoutInflater service from context:
LayoutInflater inflater=(LayoutInflater)getSystemService(LAYOUT_INFLATE_SERVICE);
use following method to addview to main xml, I assume you have parent layout llParent in xml and you want to add items in this llPaent, from list list.
for(int i=0;i<list.size();i++)
{
LinearLayout llView=(LinearLayout)inflater.inflate(R.layout.row);
//get view id and set values
TextView txt=(TextView)llView.findViewById(R.id.text);
}

A ListView is a good view for displaying several similar items. Here is a tutorial (Other views with adapters are good too, such as GridView or Gallery).
You will probably want to create your own adapter for the list, so you can display all three views (checkbox, image and text) as one item, but there are lots of examples on that available on the net as well as here on SO.

Related

How to dynamic insert elements of a string array into textview and position it?

I get the list of elements from the HTTP response, then I want to dynamically insert that list into the textview inside the "box" that you can see, currently it just inserts a string and overlaps them one over the other. I tried changing the layout (all three constraint, relative and linear) and it didn't help. Does anyone know how to position them dynamicly inside the boxes and not overlap but have margins like in the second picture? Otherwise, inside the project, I use a constrain layout.
Here is my code:
RelativeLayout parentLayout = (RelativeLayout) findViewById(R.id.layout);
int size = response.toArray().length;
final TextView[] tv = new TextView[size];
TextView temp;
for (int i = 0; i < size; i++)
{
temp = new TextView(Activity.this);
temp.setText(response.get(i).getName());
parentLayout.addView(temp);
tv[i] = temp;
}
Here is the picture how it looks right now:
And here is the picture how I want it to looks like:
This sounds like a typical ListView use case.
Firstly, I'd suggest you go through the documentation -
https://developer.android.com/reference/android/widget/ListView
You can see an implementation example of a list view with an array of strings here -
https://androidexample.com/Create_A_Simple_Listview_-_Android_Example/index.php?view=article_discription&aid=65
In general, you choose the UI of your item and the listView populates the view to each item in your list (each string in your case).
In the adapter, you give each item the data it needs for the UI.
I would suggest you to use RecyclerView for this type of task. You may use ListView as well.
But RecyclerView is more flexible and advanced than ListView.
Create a simple layout or xml file for your row item to be shown in RecyclerView.
Add that row xml file in onCreateViewHolder method. And inside method onBindViewHolder do necessary task like for example, showing name in the list for each position.
Go to this link for your reference : https://developer.android.com/guide/topics/ui/layout/recyclerview
Instead of Array<String> you can use Array<CustomModel> as well depending on your requirement.
Simple example of RecyclerView with model objects as list : https://www.javatpoint.com/android-recyclerview-list-example
Well, the proper way to do what you need is use ListView or RecyclerView.
Anyway, if you want to use your current solution, you need to specify the position of each TextView.
For example, assign an ID to each textview you create and then set the position of it under the previous one. Here you can find how to do that.

How to add blocks of linearLayouts and is there a better way?

This is the main idea of what I am trying to do.
I would like to ask you what is the best way to make such a design. the problem is that these gray/black blocks might not show up (user will choose which should show up). So I would like to find out do I need to make these 3 text views inside linearLayout programatically? Is there anyway to create some sort of template which I would only have to edit by setting new texts for textViews and add them to some sort of layout?
Another option is to just have a LinearLayout and an xml for the row entry. Then you can do:
LinearLayout layout = (LinearLayout) this.findViewById(R.id.your_layout_id);
List<Blocks> userBlocks = getMyUserBlocks();
for(Block b : userBlocks) {
View blockView = LayoutInflater.from(getBaseContext())
.inflate(R.layout.your_row_layout, layout, false);
TextView someData = (TextView) blockView.findViewById(R.id.your_text_view_id);
someData.setText(b.someAttribute.toString());
layout.addView(blockView);
}
You will need a separate xml layout for the block row.
You can use a ListView with large dividers. Your dark gray blocks are the row views, and you can just append them to a dataset and update the adapter for the ListView. For the dividers, see setDivider() and setDividerHeight().

How to add editable View components to a layout in Android?

So, what I'd like is: defining a component, which includes TextView-s and an ImageView. This is an item, which I'd like to add to a (for example Linear) layout, so I can display all the custom items, I added one after the other.
The point is, that these items have to be editable, because a database query result will define their text content and the image.
Your custom component should be a ViewGroup itself. You can add any number of TextViews and ImageViews to it, and access them by their ID.
MyCustomViewGroup component = (MyCustomViewGroup)linearLayout.findViewById(...);
TextView textView1 = (TextView)component.findViewById(...);
ImageView imageView = (ImageView)component.findViewById(...);
You can go for the XML approach for defining your component. For instance, you can define your component as a LinearLayout, then add all the elements (TextViews, ImageViews) you need to that layout.
As for the "editable" part, just provide your elements with an id property
android:id="#+id/my_view"; that way you may obtain them through a findViewById(R.id.my_view) call.
You cast the results to whatever View implementation you are expecting, then change it's text/content/image with the interpreted results from your query.

Duplicate layout IDs returning as -1 after view replacement

Short Story:
I have a layout "layout.xml", which gets replaced by another layout "success.xml" after a successful web request. Both layouts have an ImageView that provides the backgrounds to the layouts. These 2 backgrounds both need to be the same, and both are dependent on a user preference.
Longer Story: This all happens in a Fragmnet with an AsyncTask replacing the contentView with "success.xml" in onPostExecute after the web request. This happens as follows:
View view = getView();
view = null;
view = View.inflate(context, R.layout.success, null);
What I tried to do is give both ImageViews the following android:id="#+id/background_image" and then call
ImageView background = (ImageView)view.findViewById(R.id.background_image);
background.setImageResource(R.drawable.bg1);
This background-setting works for the initial view (layout.xml), but on trying to change to "success.xml", I get a NullPointException because background is null.
I've checked and the View's id is set to -1 while the original view's background_image id is set to something sensible and valid.
I've also tried setting the second view's background id like this: android:id="#id/background_image", i.e. without the '+', but still no luck.
The added complication is that it's not just 2 layouts, but about 5 that I need to do this for, so it would be really handy to recycle view id's.
Any help would be greatly appreciated.
Your code for replacing the fragment's view will not do what you want, the original view will remain the same as you change only a reference to that view and not the actual object.
To replace the view of the fragment with the new layout you could have another ViewGroup(for example a FrameLayout) in the basic layout (layout.xml) wrapping your current content(don't forget to give it an id) of layouts.xml(as I understand this is the basic layout). Then, when it's time to replace the layout you could simply do:
// remove the current content
((ViewGroup) getView().findViewById(R.id.yourWrapperLayout)).removeAllViews();
// add the new content
View.inflate(context, R.layout.success, ((ViewGroup) getView().findViewById(R.id.yourWrapperLayout)));
You could avoid adding an extra layout if, by any chance, all your five layouts have the same type for the root view(like a LinearLayout etc). In this case you would use the same code as above but you'll modify the other layouts file to use a merge tag. Also, you'll be looking for the id of the root in the layout.xml layout into which you'll add the content of the other files.
Then you could have the same ids, but you'll have to reinitialize any reference to the views(meaning that you'll have to search for the view again if you store a reference to the view(like a Button field in the fragment class)).

How do I implement an alphabetically separated GridView in Android?

I want to use a GridView to display data that is separated alphabetically by row. Each row of the grid view should contain up to four names, and there should only be names starting with the same letter in a row. I know how to set up a GridView, just not how to set it up in this format. The screenshot below shows what I would like to do:
Make a layout file table.xml for the Grid or TableLayout. Make a layout file cell.xml for the cell. Now order names and put them into appropriate cells by inflating the cell.xml.
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
...
view = inflater.inflate(R.layout.cell, table, false);
tableRow.addChild(view);
view.setText(name);
I think, you'll manage table rows creation by yourself.
The simpliest way is to make static layout e.g. Linear oriented vertically with internal 26 grids (or just put grids in runtime)
-Scroll
----Linaear(vertical)
-------GridView(id=aGrid, w=match_parent, h=wrap_content)
-------GridView(id=bGrid, w=match_parent, h=wrap_content)
...
-------GridView(id=zGrid, w=match_parent, h=wrap_content)
Then, to bind data with UI you can declare Map gridViews and push data accordingly word's first letter.

Categories

Resources