ListView Create cell programmatically - android

I need to put a series of checkboxes in the cell of a ListView. The problem is that I do not know ahead of time how many. I am guessing, but please correct me if I am wrong, that I need to create it programmatically. There will only be a few cells so I am not worried about reusability. How do I approach doing that?
No xml just build the cell in the getView method --> is this as simple as creating a View and add to it?
xml but append checkboxes to the xml --> I have no idea how to do this.
Is there some sort of dynamic xml CheckBox list that I can use?

I always prefer to use XML to separate the presentation of the controller (or code that controls the app)..
You just need to create a list view and define it's adapter. The adapter will have an XML (a row) where you can design the checkbox and the other elements that you want...
Check out the documentation where you can see an example of a listview with an adapter.
-- edit:
In your case you need to add the checkboxes programmatically in your adapter. Just define a view in your xml where you can add your checkboxes.
-- edit2:
Here is an example XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="50dp" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/checkboxContainer" >
</RelativeLayout>
</RelativeLayout>
In your adapter you
//get the container
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.NAME_OF_YOUR_XML, parent, false);
RelativeLayout your_container = (RelativeLayout) rowView.findViewById(R.id.checkboxContainer);
//declare your checkbox
CheckBox cb = new CheckBox(context);
cb.setText("your text");
// add the checkbox to your container
your_container.addView(cb);
This is just an example. I didn't test the code. Maybe you should use a linear layout instead of a relative layout to place your checkboxes easily..

easiest and most flexible is to use the ArrayAdapter and make an XML layout that looks like the single cell you'd want. Put your data in the array, create the Adapter and assign it to the ListView, and boom, your list has the right number of rows (cells). You can also customize the binding easily so that each cell has some information based on the corresponding Array entry.

Related

ListView and ArrayAdapter

When we build a ListView in android studio, we need to use an ArrayAdapter.
What is the task of second argument in constructor of ArrayAdapter ?
I cannot understand what is android.R.layout.simple_list_item_1 used for ?
This layout describe how the item list looks like.Maybe you want every item contain a text view and image.You should specify these details in this layout.
android.R.layout.simple_list_item_1 is a layout in which the data from your ArrayAdapter gets populated(added).
This is the id of the layout that you need to use for populating each of the item in the list. If it says android.R.layout that means you are going to use one of the standard android layouts. simple_list_item_1 This is the name of the file which will populate each row of the list. try changing this to simple_list_item_2 to see how the layout in list changes.
You can also use your custom adaptors and custom layouts(which would be in majority of the cases in day to day apps).
For full list of standard layouts available Go here
This argument defines how list items would appear in ListView, There are many layouts you can also try them out or you can make your own custom layout to modify apperance of listitems in Listview by using CustomAdapter.
1.create custom layout name custom_layout.xml & paste bellow code
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="16sp" >
</TextView>
Use like R.layout.custom_layout instead of android.R.layout.simple_list_item_1

building flexible GUI

I have a Layout that I want to populate with items consisting of 2 textviews and one button. I do not know before hand how many items that will populate my Layout.
Since I don't know when writing the layout.xml how many items I want to add, thats means that I have to add the items in the java instead of the xml. But I do not like to build GUI in java because it looks ugly.
Does anyone know if I can create an xml file for my item and then add new items to my layout during execution?
I have written some pseudo code to try to demonstrate what I want to accomplish:
MainLayout.xml
//My empty Layout
<Layout myMainLayout >
</RelativeLayout>
Fragment_post.xml
//one post
<TextView/>
<TextView/>
<Button/>
In the code somewhere
setContentView(R.layout.MainLayout);
MyMainLayout.addFragment(R.layout.Fragment_post);
You can add your fragment_post.xml wherever you want:
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout view=(LinearLayout)inflater.inflate(R.layout.yourfragment, null);
yourLayout.addView(view);
Please don't confuse a Fragment with a piece of the GUI. See here for details: http://developer.android.com/guide/components/fragments.html
Sure you can do this. Just set an initial empty layout to your activity.
onCreate()
{
setContentView(R.layout.initial_layout);
}
Then get and keep a reference to main layout.
LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout mainLayout=(RelativeLayout)inflater.inflate(R.layout.initial_layout, null);
Next, add new views to your layout as and when you need them.
LinearLayout view=(LinearLayout)inflater.inflate(R.layout.fragment_post, null);
mainLayout.addView(view);
But note that what you refer to as fragments here are not what android refers to as fragments. Learn about actual android fragments here:
http://developer.android.com/guide/components/fragments.html

Android ListView addHeaderView not working with a simple View

I'm inflating a View and adding it to a ListView for using it as a padding for the top element within the ListView. The problem is that the view doesn't render in the ListView unless I change View to for example TextView, cannot I use a simple View here? why?
This is the code for adding the pad:
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view top_pad = inflater.inflate(R.layout.search_pad, null);
list.addHeaderView(top_pad);
The pad XML file layout.search_pad
<?xml version="1.0" encoding="UTF-8"?>
<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="#333" />
It is possible to add an Item of type View to your header, the problem is that if there is nothing telling the view how tall is should be at a minimum, and the view contains no children the ListView will shrink its header to a 0 height.
So to fix my implementation i added in XML a
android:minHeight="#dimen/minHeader"
where minHeader is
<dimen name="minHeader">5dp</dimen>
Again a callout here for addHeaderView(View v):
Note: When first introduced, this method could only be called before setting the adapter with setAdapter(ListAdapter). Starting with KITKAT, this method may be called at any time. If the ListView's adapter does not extend HeaderViewListAdapter, it will be wrapped with a supporting instance of WrapperListAdapter.
Sorry this is late, Happy Coding.

Creating table rows programmatically while defining layout in XML

I am trying to add rows to a TableLayout that I define in an XML file. The XML file contains a header row for the table.
I can add new rows quite well using info from various tutorials but the code required for setting up the layout for the new rows is a horrendous mess and it seems like a pain in the ass to maintain whenever the layout for the header row changes.
Is it possible to create new rows to a TableLayout while still defining the row layout in XML? For example define a template row in XML, obtain a handle to it in code and then clone the template whenever I need it.
Or is the right way to do this somehow completely different?
Your proposed approach will work fine and it more or less matches the common pattern used when populating ListView items.
Define a layout that contains a single row. Obtain a LayoutInflater by using LayoutInflater.from(myActivity). Use this inflater to create new rows using your layout like a template. Generally you will want to use the 3-argument form of LayoutInflater#inflate passing false for the third attachToRoot parameter.
Let's say you wanted to use a template layout with a label and a button in each item. It might look something like this: (Though yours would define your table rows instead.)
res/layout/item.xml:
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/my_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button android:id="#+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Then at the point where you inflate:
// Inflate the layout and find the component views to configure
final View item = inflater.inflate(R.layout.item, parentView, false);
final TextView label = (TextView) item.findViewById(R.id.my_label);
final Button button = (Button) item.findViewById(R.id.my_button);
// Configure component views
label.setText(labelText);
button.setText(buttonText);
button.setOnClickListener(buttonClickListener);
// Add to parent
parentView.addView(item);

android nested listview

is it possible/advisable to have a nested listview?
i.e. a listView that's contained within a row of another listview?
an example would be where my main list is displaying blog posts, and then in each row, you'd have another list view for the comments for each post (that would be collapsible)
I had the same problem today, so this is what I did to solve it:
I have a ListView, with a CustomAdapter, and on the getView of the customAdapter, I have something like this:
LinearLayout list = (LinearLayout) myView.findViewById(R.id.list_musics);
list.removeAllViews();
for (Music music : albums.get(position).musics) {
View line = li.inflate(R.layout.inside_row, null);
/* nested list's stuff */
list.addView(line);
}
So, resuming, It's not possible to nest to ListViews, but you can create a list inside a row using LinearLayout and populating it with code.
Is what you're looking for the ExpandableListView? Of course, that's limited to only two levels of listings (but that sounds like it would work for your needs).
This sound like what you're looking for? If you're not, or if this doesn't work, I would suggest having two list views: one of, say, blog posts, and the second of comments, and an action on a blog post item takes you to the second view, populated with the relevant comments.
you can do it like this :
inside the parent listview row xml layout add the following table layout
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/table_show"
android:background="#beb4b4">
</TableLayout>
then you have to make a layout for the child list with name reply_row.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tv_reply_row"
android:textColor="#000"/>
</TableRow>
in your parent listview adapter getview method add the following code :
TableLayout replyContainer = (TableLayout)
// vi is your parent listview inflated view
vi.findViewById(R.id.table_show);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//child listview contents list
String [] replys = {"a","b","c","d"};
for (int i=0;i<replys.length;i++)
{
final View comments = inflater.inflate(R.layout.reply_row, null);
TextView reply_row = (TextView) comments.findViewById(R.id.tv_reply_row) ;
reply_row.setText(replys[i]);
//for changing your tablelayout parameters
TableLayout.LayoutParams tableRowParams=new TableLayout.LayoutParams
(TableLayout.LayoutParams.FILL_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
int leftMargin=3;
int topMargin=2;
int rightMargin=3;
int bottomMargin=2;
tableRowParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
comments.setLayoutParams(tableRowParams);
TableRow tr = (TableRow) comments;
replyContainer.addView(tr);
}
You'd better use one ListView, not nested. Nesting ListView is an inefficient way. Your ListView may not scroll smoothly and take up more memory.
You could organize your data structure to show nested data in one ListView. Or you can use this project PreOrderTreeAdapter.
It is convenient to show nested data in ListView or RecyclerView. It can be used to make ListView or RecyclerView collapsible, just change the way you provide your data than notify the adapter.

Categories

Resources