Android - dynamically adding view to popup dialog - android

I have an Alert Dialog that shows some text input fields.
When I enter data and click "OK", it saves this data and displays it in a custom view on the Activity that called the dialog.
If I want to edit this data, I click on the custom view and the same alert dialog pops up. I want to pre-populate the data, and allow editing, and adding new data. However, here is where I'm having a problem.
When I try to do add the existing data to the dialog, the views get added to the top of the view, and not the subview I want them added to. See here:
So the alert dialog inflates the view from my Activity:
View dialogView = LayoutInflater.from(this).inflate(R.layout.material_add_dialog, viewGroup, false);
builder.setView(dialogView);
But this R.layout.material_add_dialog is the main/top view.
I have a custom adapter class that I am using as well. Here is the getView() method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = Objects.requireNonNull(mInflater).inflate(R.layout.add_material_popup_dialog_row, null);
}
Material material = mMaterials.get(position);
EditText etMaterial = convertView.findViewById(R.id.material_add_text_material);
EditText etSupplier = convertView.findViewById(R.id.material_add_text_supplier);
EditText etWeight = convertView.findViewById(R.id.material_add_text_weight);
EditText etAmount = convertView.findViewById(R.id.material_add_text_amount);
etMaterial.setText(material.getMaterial());
etSupplier.setText(material.getSupplier());
etWeight.setText(material.getUnit());
etAmount.setText(material.getAmount());
return convertView;
}
So if you see convertView, this is inflating R.layout.add_material_popup_dialog_row which is the row that is being added at the top.
So really my question is, how can I add this row to a subview of the dialogs view?
Thanks.

You just need to get, or create, the subview. If it exists:
View dialogView = LayoutInflater.from(this).inflate(R.layout.material_add_dialog, viewGroup, false);
View subView = dialogView.findViewById(R.id.mySubViewId);
Or, you can create a new view and add it to the current view:
//You would need to create the appropriate view for your use-case.
View view = new View();
dialogView.addView(view);

you can try to create the container LinearLayout as root then addView(convertView) and return root

Related

Add listView header between list

This is my listView
I want to add a February header on top of 2016-02-02 and January in 2016-01-31. Is it possible?
Yes, you can do this by returning a different view in your getView() method in your adapter class. In your master list, that you pass to your adapter, you can add a divider item, a String or however you are holding all this data, I assume a custom class, that you know is meant to show a Month title. You can do a quick check in your getView() method and return a different view that displays the month..
In your getView() method, you can do this...
#Override
public View getView(final int position, View convertView, ViewGroup parent){
LayoutInflater mInflator = LayoutInflater.from(getContext());
View customView = mInflator.inflate(R.layout.times_layout, parent, false);
Time temp = getItem(position);
//Check to see if the time is supposed to be a header
//This is where you check to see if it meant to be a section header
if(temp.getDate.equals("HEADER")){
//Header, return section view instead of normal view
View sectionHeader = mInflator.inflate(R.layout.layout_list_divider, parent, false);
TextView txt_Section = (TextView) sectionHeader.findViewById(R.id.txt_Header);
sectionHeader.setClickable(false);
return sectionHeader;
}
//Normal View... do what you would do normally
return customView;
}
I hope this helps! Let me know.. it worked for me
In android It's called ExpandableListView
You can try this tutorial:
http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/
It also has a sample to download.

Android - add Layout views into ListView

the problems is, that I wan't to make ListView with elements which are containing image, description and two buttons. I'm making them in my own BaseAdapter extension, but fragment which is containing ListView is closing (wihtout errors in logcat..). I've found, that ListView is working well, when I'm not returning layout-type elements. So there is my sample with 'sample linear layout', which is not working.. Is there any possibility, to show layouts in ListView?
Here is my code:
Creating part:
lv = (ListView) getView().findViewById(R.id.main_wall_ambajes_lv);
AmbajAdapter aa = new AmbajAdapter(getActivity().getApplicationContext(), StaticData.ambajes);
lv.setAdapter(aa);
My getView method from adapter:
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout ll = new LinearLayout(getActivity());
ll.setOrientation(LinearLayout.VERTICAL);
ImageView iv = new ImageView(getActivity());
iv.setImageBitmap(placeholderBitmap);
ll.addView(iv);
ll.addView(iv);
ll.addView(iv);
ll.addView(iv);
return ll;
}
I don't know why you don't have any error however I don't think you proceed the correct way.
Usually you create the layout in the xml file of the layout folder and only inflate it in the getView(), for example as follow :
private LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
#Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = mInflater.inflate(R.layout.your_custom_layout, parent, false);
}
//your code for setting the image or other things goes here
//for example if you have a textView
TextView textView = (TextView) view.findViewById(R.id.my_textview_id);
textView.setText("my custom text for this cell");
return (view);
}
and your_custom_layout is simply the xml file of your layout.
Note that for performance reason due to cell recycling I only inflate the view when it is null and I only read once the LayoutInflater context and put it in mInflater. However for the best performance you should use a ViewHolder, but it is out of the scope of your question.

Change row height in listActivity when pressed

I have created a ListActivity class, with a custom Adapter.
Rows are simple: TextView and a Button.
Implemented getView method is as below:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.row, null);
}
TextView tV = (TextView) convertView.findViewById(R.id.tv);
tV.setText(MY_LIST[position]);
return convertView;
}
Now I want that each row, when pressed, dynamically add another button to itself, below the others components, and that consequently, the row height is increased.
How can I perform this steps?
New button should be hidden by default. When user clicked on row your handler makes something like mHiddenButton.setVisibility(View.VISIBLE).

How do use the LayoutInflater inflater properly

I created the Layout design using java code only not from the XML Layout Designs. The code I used is following
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(mContext);
tv.setText(hotelList.get(position).name);
return tv;
}
How to use layoutInflator for creating layout fro this. I need 2 more textviews in a single list item. the whole list contains 10 different list items
Please provide some codes for this. Help appreciated
I have gone through this before by having my static class too. Check this out, it will help:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if ( rowView == null) {
LayoutInflater inflator = this._activity.getLayoutInflater();
rowView = inflator.inflate(R.layout.todolistlisting, null);
TodoListViewHolder viewHolder = new TodoListViewHolder();
viewHolder._name = (TextView) rowView.findViewById(R.id.tVTLName);
viewHolder._completed = (TextView) rowView.findViewById(R.id.tVTLCCount);
viewHolder._remaining = (TextView) rowView.findViewById(R.id.tVTLRCount);
rowView.setTag(viewHolder);
}
TodoListViewHolder holder = (TodoListViewHolder) rowView.getTag();
VO_TodoList votodolist = this._items.get(position);
holder._name.setText(votodolist._title);
holder._completed.setText(votodolist._completed);
holder._remaining.setText(votodolist._remaining);
return rowView;
}
TodoListViewHolder is my view component holder here. like your TextView.
I guess you know how to make XML layout for this layout. So just make the XML layout and get the object of the main layout using the following code:
LinearLayout mainLayout=(LinearLayout) View.inflate(R.layout.yourlayout); //if yourlayout.xml is the name of the xml file you made and put in the layout folder.
To get the child of the layout, let's say if it's a TextView with the id text, then the code would be:
TextView textView=(TextView)mainLayout.findViewById(R.id.text);
You can add view at runtime by using inflater like this
LinerLayout linearLayout = (LinearLayout)inflater.inflate(R.layout.news_categories_item, null);
TextView categoryValueTextView = (TextView)linearLayout.findViewById(R.id.news_category_item_value);
mMainLinearLayout.addView(categoryValueTextView);
Here i am inflating one text view which is there in another linear layout(this is simple linear layout which holds only textview) at runtime and adding it to my main linear layout.
you can get the inflater object in your acitivity by using getLayoutInflater(). And if you want to get inflater in adapter you have to pass inflater object to constructor of adapter from your activity.

ListView in ArrayAdapter order get's mixed up when scrolling

I have a ListView in a custom ArrayAdapter that displays an icon ImageView and a TextView in each row. When I make the list long enough to let you scroll through it, the order starts out right, but when I start to scroll down, some of the earlier entries start re-appearing. If I scroll back up, the old order changes. Doing this repeatedly eventually causes the entire list order to be seemingly random. So scrolling the list is either causing the child order to change, or the drawing is not refreshing correctly.
What could cause something like this to happen? I need the order the items are displayed to the user to be the same order they are added to the ArrayList, or at LEAST to remain in one static order. If I need to provide more detailed information, please let me know. Any help is appreciated. Thanks.
I was having similar issues, but when clicking an item in the custom list, the items on the screen would reverse in sequence. If I clicked again, they'd reverse back to where they were originally.
After reading this, I checked my code where I overload the getView method. I was getting the view from the convertedView, and if it was null, that's when I'd build my stuff. However, after placing a breakpoint, I found that it was calling this method on every click and on subsequent clicks, the convertedView was not null therefore the items weren't being set.
Here is an example of what it was:
public View getView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
{
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.listitemrow, null);
RssItem rssItem = (RssItem) super.getItem(position);
if (rssItem != null)
{
TextView title = (TextView) view.findViewById(R.id.rowtitle);
if (title != null)
{
title.setText(rssItem.getTitle());
}
}
}
return view;
}
The subtle change is moving the close brace for the null check on the view to just after inflating:
public View getView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
{
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.listitemrow, null);
}
RssItem rssItem = (RssItem) super.getItem(position);
if (rssItem != null)
{
TextView title = (TextView) view.findViewById(R.id.rowtitle);
if (title != null)
{
title.setText(rssItem.getTitle());
}
}
return view;
}
I hope this helps others who experience this same problem.
To further clarify the answer of farcats below in more general way, here is my explanation:
The vi.inflate operation (needed here for parsing of the layout of a row from XML and creating the appropriate View object) is wrapped by an if (view == null) statement for efficiency, so the inflation of the same object will not happen again and again every time it pops into view.
HOWEVER, the other parts of the getView method are used to set other parameters and therefore should NOT be included within the if (view == null) statement.
Similarily, in other common implementation of this method, some textView, ImageView or ImageButton elements need to be populated by values from the list[position], using findViewById and after that .setText or .setImageBitmap operations.
These operations must come after both creating a view from scratch by inflation and getting an existing view if not null.
Another good example where this solution is applied for BaseAdapter appears in BaseAdapter causing ListView to go out of order when scrolled
The ListView reuses view objects when you scroll. Are you overriding the getView method? You need to make sure you set each property for every view, don't assume that it will remember what you had before. If you post that method, someone can probably point you at the part that is incorrect.
I have a ListView, AdapterView and a View (search_options) that contains EditText and 3 Spinners. ListView items are multiple copies of (search_options) layout, where user can add more options in ListView then click search to send sql query built according to users options.
I found that convertView mixing indecies so I added a global list (myViews) in activity and passed it to ArrayAdapter. Then in ArrayAdapter (getView) I add every newly added view to it (myViews).
Also on getView instead of checking if convertView is null, I check if the global list (myViews) has a view on the selected (position).. It totally solved problems after losing 3 days reading the internet!!
1- on Activity add this:
Map<Integer, View> myViews = new HashMap<>();
and then pass it to ArrayAdapter using adapter constructor.
mSOAdapter = new SearchOptionsAdapter(getActivity(), resultStrs, myViews);
2- on getView:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
ViewHolder viewHolder;
if (!myViews.containsKey(position)) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
view = inflater.inflate(R.layout.search_options, parent, false);
/// ...... YOUR CODE
myViews.put(position, view);
FontUtils.setCustomFontsIn(view, getContext().getAssets());
}else {
view = myViews.get(position);
}
return view;
}
Finally no more mixing items...

Categories

Resources