Dynamic view setting same value for every view added dynamically - android

With following function, I am adding view dynamically. but through this, last call values to "addview" are getting set in all views. Like If i call addview function with "aaaa" in its 0 index it will add one view with aaaa name, and then again i call addview with "bbbb" in its 0 index it will add one more view but this time it set "bbbb" to previous view also. Means now both dynamically added view will have "bbbb" value in its edittext. Please help.
public void addView(String[] values) {
layoutInflater =
(LayoutInflater) getActivity( ).getBaseContext( ).getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView = layoutInflater.inflate(R.layout.lay_fcp_child, null);
ImageView ivRemove;
EditText etName;
RelativeLayout layDOB;
final TextView tvDate;
final Spinner spRelationship;
tvDate = (TextView) convertView.findViewById(R.id.tv_ins_dob);
layDOB = (RelativeLayout) convertView.findViewById(R.id.lay_ins_dob);
etName = (EditText) convertView.findViewById(R.id.et_ins_personname);
etName.setFilters(new InputFilter[]{filterName, new InputFilter.LengthFilter(60)});
ivRemove = (ImageView) convertView.findViewById(R.id.iv_fcp_remove);
spRelationship = (Spinner) convertView.findViewById(R.id.sp_fcp_relationship);
AdapterIDValue adapterRelations = new AdapterIDValue(getActivity(), R.layout.spinner_selected_item_relation, alSRelationship);
spRelationship.setAdapter(new NothingSelectedSpinnerAdapter(adapterRelations, R.layout.spinner_hint_relationship, getActivity()));
etName.setText(values[0]);
spRelationship.setSelection(Integer.parseInt(values[3]));
tvDate.setText(values[1]);
tvDate.setTag(values[2]);
tvDate.setTextColor(Color.BLACK);
try {
layDynamic.addView(convertView);
}catch (Exception sdf){
System.err.print(sdf);
}
svMain.fullScroll(ScrollView.FOCUS_DOWN);
}

Yes you can create with RecyclerView OR ListView, or if you want to do with scroll view the generate dynamic Ids of every view, so you can solve your problem.

Each call to addview(...) method will create a new adapter and set it to spRelationship. This new adapter replace the previous. You are not "adding views", you're "setting the views".
You have to set the adapter only once and change its data.

Related

Dynamically add a button to a view from a listview Adapter GetView method

As a little eperiment, I'm trying to do the following.
I have an AXML describing a vertical linear layout which contains a listview (only filling 200dp of the vertical linear layout ). The AXML is inflated when the activity starts with SetContentView. Then the listview is correctly populated with values using its Adapter.
In the GetView method of the listview Adapter, I am trying to also dynamically create a button and add it to the linear layout, but for some reason the button is not added.
If I try to add the button in the constructor method of the Adapter instead, it is correctly added.
Can you tell me what could be possibly going wrong?
Let me add some code:
class TracksAdapter : BaseAdapter<string> {
Activity context;
List<Dictionary<string,string>> trackList;
// constructor
public TracksAdapter (Activity context, List<Dictionary<string,string>> trackList) {
this.context = context;
this.trackList = trackList;
// Just as a little test, if I create the button from here it will be correctly added to linear layout:
var ll = context.FindViewById<LinearLayout>(Resource.Id.linLayForResultsActivity);
Button b1 = new Button(context);
b1.Text = "Btn";
ll.AddView(b1);
}
public override View GetView(int position, View oldView, ViewGroup parent) {
// if I create the button from here it will not be added to the layout
var ll = context.FindViewById<LinearLayout>(Resource.Id.linLayForResultsActivity);
Button b1 = new Button(context);
b1.Text = "Btn";
ll.AddView(b1);
// this other code is working
View view = context.LayoutInflater.Inflate(Resource.Layout.ResultItem, null);
var artistLabel = view.FindViewById<TextView>(Resource.Id.resultArtistNameTextView);
artistLabel.Text = trackList[position]["trackArtistName"];
return view;
}
}
Update: adding some more context information because I know this can be a bit weird to understand without it:
In GetView, I don't need to return the new button I am trying to create there. GetView only need to return a listview view item, but, along its execution, GetView also has to create and add a button to the linear layout containing the listview.
The real code is much more complex than that. I have simplified it in the question. In the real code, the listview items are made of text and a button. The GetView also attaches event handlers to the buttons. Then what I need is, when a user clicks a button in any of the listview items, another button is added below the listview. So I need the code for adding another button to be in GetView, and the button needs to be added outside of the listview, ie. to the linear layout containing the listview.
Use the LayoutInflator to create a view based on your layout template, and then inject it into the view where you need it.
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);
// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");
// insert into main view
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
I looked in you code, you are returning view, while you add the button to ll, you should return ll
what you return in getView() is what you see in the list item layout, since you're adding the button to ll and returning view, the button won't appear.
you can add the button to view as you implementation
Also check this:
Try using boolean addViewInLayout (View child, int index, ViewGroup.LayoutParams params)
http://developer.android.com/reference/android/view/ViewGroup.html#addViewInLayout(android.view.View, int, android.view.ViewGroup.LayoutParams)
It's working... Without making any changes now it's working as it should... ! Ugh!
I really don't know what I was doing wrong here... probably it was because of some sort of caching of older version of the installed APK.. ? I know this sort of stuff can happen, and that's why I've always been uninstalling the app before deplyoing the new version to the device... but still...!

Android - programatically changing the row layout of a custom listView row fails when focus is requested on its edittext child

Sorry for the long title.
I have an android application which shows a custom listView with 5 TextView columns. When the user clicks a row, I change the layout to have 3 TextViews and 2 EditTexts. I have different layout files for both of them. Everything worked fine initially, the row layout changes properly and I am able to click on the EditText and input values. However, I want either of the 2 EditText to automatically gain focus based on what is clicked. I already have a working code for this. My problem is that programatically requesting requestFocus() seems to block the part where I change the row layout with the new view.
Here is the code that changes my row layout, it works fine without the requestFocus() line:
private void changeLayout(final View view){
//get views from old row layout
TextView textViewQuantity = (TextView)view.findViewById(R.id.qtyInput);
TextView textViewDiscountReq = (TextView)view.findViewById(R.id.discInput);
TextView textViewName = (TextView)view.findViewById(R.id.dialogItemName);
TextView textViewPrice = (TextView)view.findViewById(R.id.price);
TextView textViewDiscount = (TextView)view.findViewById(R.id.discount);
//store values in strings
String itemName = textViewName.getText().toString();
String itemPrice = textViewPrice.getText().toString();
String itemDiscount = textViewDiscount.getText().toString();
String itemQty = textViewQuantity.getText().toString();
String itemDisc = textViewDiscountReq.getText().toString();
//set the view to gone
textViewQuantity.setVisibility(View.GONE);
textViewDiscountReq.setVisibility(View.GONE);
textViewName.setVisibility(View.GONE);
textViewPrice.setVisibility(View.GONE);
textViewDiscount.setVisibility(View.GONE);
//get the old layout
LinearLayout ll_inflate = (LinearLayout)view.findViewById(R.id.search_result_layout);
//get the inflate/new view
View child = getLayoutInflater().inflate(R.layout.search_result_inflate, null);
//get the views in the new view, populate them
TextView newName = (TextView)child.findViewById(R.id.dialogItemName);
newName.setText(itemName);
TextView newDiscount = (TextView)child.findViewById(R.id.discount);
newDiscount.setText(itemDiscount);
TextView newPrice = (TextView)child.findViewById(R.id.price);
newPrice.setText(itemPrice);
qtyIn = (EditText)child.findViewById(R.id.qtyInputSearchResult);
qtyIn.setText(itemQty);
qtyIn.setFilters(new InputFilter[] {filter});
discIn = (EditText)child.findViewById(R.id.discInputSearchResult);
discIn.setText(itemDisc);
//show new layout
ll_inflate.removeAllViews();
ll_inflate.removeAllViewsInLayout();
ll_inflate.addView(child);
//request focus here
if(focusTarget == 1){
Log.d("hello", "focus target is 1 " );
qtyIn.setFocusable(true);
qtyIn.setFocusableInTouchMode(true);
qtyIn.requestFocus();
}
else if(focusTarget == 2){
Log.d("hello", "focus target is 2 " );
discIn.requestFocus();
}
Log.d("hello", "focus state qtyIn = " + qtyIn.isFocused());
Log.d("hello", "focus state discIn = " + discIn.isFocused());
}
The interesting part is that the Log shows the proper values, it says the proper focus status according to what I want. However, the ll_inflate.addView(child); line does not work at all!
Does anyone know what happened here? I'm really confused as to why the layout didn't change but the lines after the .addView() line executed. Another weird thing is how requestFocus(); prevents the view from changing.
Any help is very much appreciated. Thanks.
You are doing this in wrong way. You should have two type of view in list, one for show data and one for edit it.
First set view type count
final int TYPE_EDIT =0,TYPE_VIEW =1;//EDIT 7/9/016 type need to be start from 0
public int getViewTypeCount (){
return 2;
}
public int getItemViewType (int position){
//return type as needed. simple if you add int for this in data model
}
And inside getView
public View getView (int position, View convertView, ViewGroup parent){
int type = getItemViewType ();
if(null==convertView){
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(type ==TYPE_EDIT){
convertView = inflater.inflate(R.layout.rowEditlayout, parent, false);
}else{
convertView = inflater.inflate(R.layout.rowlayout, parent, false);
}
}
}
Do the changes in list data on edit button click and call notifydatasetchanged on adapter

Setting empty view for android ListView not working for views created in Java

I have no problem setting the empty view for a ListView if the emptyView is inflated from xml. But if I create the view on the fly, it does not appear. So what’s wrong with the following code?
if (myData.isEmpty()) {
System.out.println(“there is no data“);
TextView emptyView = new TextView(this);
emptyView.setText("no data found");
myListView.setEmptyView(emptyView);
}
Add the empty view to the parrent before setting it as the empty view.
if (myData.isEmpty()) {
System.out.println(“there is no data“);
TextView emptyView = new TextView(this);
emptyView.setText("no data found");
ViewGroup parent = (ViewGroup) myListView.getParent();
parent.addView(emptyView);
myListView.setEmptyView(emptyView);
}

Changing the visibility of a image inside a list view

I have this function in the bottom, In this function I fill the listview in the MainActivity, I can fill with any text I want, but I do not know how to hide, I tried the thing in the comment part to hide it, but did not work.
I need to check a certain condition and if true hide R.id.dire_win, if false hide R.id.radiant_win
Also I need to fill R.id.team01_pic in each row of the list view with an .png/.jpg url.
Thanks for your help in advance.
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
SingleContactActivity.this, matchList,
R.layout.list_match, new String[] { TAG_team01_name, TAG_team02_name , TAG_RESULT }, new int[] {
R.id.team01_name, R.id.team02_name , R.id.result});
//ImageView imgView = (ImageView) findViewById(R.id.radiant_win);
//imgView.setVisibility(View.INVISIBLE);
//TextView textview =(TextView )findViewById(R.id.text);
setListAdapter(adapter);
}
Update: I tried to create this function as one of the answers said, but did not work .
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_match, parent, false);
//TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.radiant_win);
//textView.setText(values[position]);
// change the icon for Windows and iPhone
//String s = values[position];
imageView.setImageResource(R.drawable.team_navi);
//imageView.setVisibility(View.INVISIBLE);
return rowView;
}
Solution is to use Custom adapter instead of Simple adapter. Then you have to create a custom xml with all widgets you want (imageView,TextField, etc.). In your custom adapter class, inside the getView() method, that you have previously overridden, you can specify the conditions of imageView visibility. This example should help you:
http://www.learn-android-easily.com/2013/06/listview-with-custom-adapter.html
Also read this (http://developer.android.com/reference/android/widget/Adapter.html)

Inflating several same layouts with diffrent data

How can I inflate several same layouts with diffrent texts and images? I tried use this code
for (final Tour t : info.tours) {
final LinearLayout list = (LinearLayout) findViewById(R.id.tours_list);
Log.d(Const.LOG_TAG, "Add child view to tours_list");
final LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View child = inflater.inflate(R.layout.tour_item_for_guide_info,
list, true);
final ImageView tourImage = (ImageView) findViewById(R.id.tour_image);
final String tourImgUrl = Const.HOST + t.image;
imageLoader.DisplayImage(tourImgUrl, tourImage);
TextView tourText = (TextView) findViewById(R.id.text);
tourText.setText(t.name);
}
but text and image setted in first inflated layout, replacing the previous text and image. I understand what it's happens because layouts have same ids. Can I resolve it? I know about ListView and adapters, but I would like to learn if it might be done without them.
I assume that the ImageView and TextView - tourImage, tourText - are elements of R.layout.tour_item_for_guide_info.
If this is so, then when you reference it, you should use the child view to get them.
With other words, instead of:
ImageView tourImage = (ImageView) findViewById(R.id.tour_image);
TextView tourText = (TextView) findViewById(R.id.text);
You should have:
ImageView tourImage = (ImageView)child.findViewById(R.id.tour_image);
TextView tourText = (TextView)child.findViewById(R.id.text);
Not sure if this will definetly fix your problem, but it looks like a bug.

Categories

Resources