I'm developing an app with a form users will have to fill.
The form has some textview, edittexts, a listview and two buttons.
The listview consist of a textview and two radiobuttons.
I populate the listview with a question and two radiobuttons in every row.
If I reuse the convertview given in overriden getView method, when I check a radiobutton, it will check the first radiobutton visible while scrolling down as per every screen scrolled.
#Override
public View getView(int position, View convertView, ViewGroup parent){
if(convertView == null){
convertView = ((Activity)context).getLayoutInflater().inflate(R.layout.riskrowlayout, parent, false);
}
((TextView)convertView.findViewById(R.id.tvPreg)).setText(data.get(position));
return convertView;
}
Otherwise, if I inflate the layout everytime getView gets called, it will automatically uncheck the radiobutton I checked while scrolling.
#Override
public View getView(int position, View convertView, ViewGroup parent){
convertView = ((Activity)context).getLayoutInflater().inflate(R.layout.riskrowlayout, parent, false);
((TextView)convertView.findViewById(R.id.tvPreg)).setText(data.get(position));
return convertView;
}
What I'm doing wrong? How can I solve this?
If you need more info ask and I'll give you.
Thank you very much in advantage!
Problem from last comment solved, just pasted this code from another post:
#Override
public int getViewTypeCount() {
return getCount();
}
#Override
public int getItemViewType(int position) {
return position;
}
You need to keep your check data into an array. When you scroll down and came back checked row it doesnt know where is checked. If you dont have model array simply create a checked list and set all false inside and inside getview method look at array.
#Override
public View getView(int position, View convertView, ViewGroup parent){
if(convertView == null){
convertView = ((Activity)context).getLayoutInflater().inflate(R.layout.riskrowlayout, parent, false);
}
TextView textView = (TextView) convertView.findViewById(R.id.tvPreg);
textView.setText(data.get(position));
radioButton.setChecked(checked.get(position));
return convertView;
}
Related
I am stuck at a very minor error ,
I want to place a condition inside the getview of the Baseadapter class.
If the condition is true it should not inflate ,else it should inflate in the listview.
Some help would be really appreciated
This is my code
public View getView(final int position, View convertView, ViewGroup parent) {
View itemView = inflater.inflate(R.layout.slidelistrow, parent, false);
// Get the position
resultp = data.get(position);
if(resultp.get(MainFragment.TAG_PACKAGE).equals(Constants.PACKAGE_NAME))
{
return null;
}else
{
return itemView;
}
}
you are doing it wrong. getView can not return null, otherwise your application will crash. What you have to do is to submit the exact dataset you want show, it means that your data has to contains exactly what you want to show in the ListView
I defined a Adapter which extends BaseAdapter when I use ListView to display something.I overrided View getView (int position, View convertView, ViewGroup parent) method to reuse View component, in the method, I also wrote if(convertView == null) {System.out.println("test");} block. There are 50 rows data in ListView and the screen only can display about 20 rows data. when I ran the application, LogCat printed less than 50 rows of "test" though I slided the screen to make sure all data are loaded.But why ? I think it should print 50 rows data. Here is the key code:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = inflater.inflate(resource, null);
System.out.println(++count + "convertView == null:" + convertView);
}
}
someone help me please, I am a newbie.... thanks
Android does not inflate a View for every item in your adapter. It reuses inflated views previously used for other items.
The pattern for binding views in a adapter is something like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if(convertView == null) {
view = inflater.inflate(resource, null);
} else {
view = convertView;
}
// bind data to view here
return view;
}
In fact you normally would use a ViewHolder class. But first fix your basic adapter before reading about that.
Because convertView will be null only if there isn't a previously returned view that can be recycled (i.e. it's no longer on screen).
The views you return from an adapter's getView() can be recycled in later calls to getView(). The framework passes such recyclable views in via the convertView arg.
So your convertView == null branch only gets run enough times to fill the listview screen once and after that, when scrolling, these old views get recycled.
You missing return view.
ListView recycles view. How ListView's recycling mechanism works
Use a ViewHolder pattern
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = inflater.inflate(resource, null);
holder = new ViewHolder();
holder.tv = (TextView)convertView.findViewById(R.id.textView1);
//initialize views
convertView.setTag(holder);
} else {
holder =(ViewHolder) convertView.getTag();
}
// update your view here
holder.tv.setText("hi");
return convertView;
}
static class ViewHolder {
// YourViews Declaration
TextView tv; // an example
}
I have a ListView in which each row is a TextView, and display a line of text. I'm getting a problem where occasionally an unwanted empty row appears. The empty row goes away once list scrolls past that particular area.
I've verified my list rows contain the correct information by using the following code after pausing the app in the debugger. Nothing in the output shows up empty or null, etc.
for (int i = 0; i<list.getChildCount(); i++) {
System.out.print((TextView) list.getChildAt(i)).getText());
}
This shows the information I expected.
I also checked the data backing my Adapter for empty entries, new lines, etc.
My getView() method inside the Adapter is as follows:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView t;
if (convertView == null) {
convertView = mInflator.inflate(R.layout.single_message_row, null);
t = (TextView) convertView;
t.setMovementMethod(LinkMovementMethod.getInstance());
t.setTextSize(mMsgSize);
}
else {
t = (TextView) convertView;
}
CharSequence text = get(position);
t.setText(text);
return t;
}
Below is an image demonstrating the problem (the area in red):
Try after changing getView method as:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if(row==null){
LayoutInflater inflater=getLayoutInflater();
row=inflater.inflate(R.layout.single_message_row, parent, false);
}
TextView t=(TextView)row.findViewById(R.id.yourtextview);
t.setText("position "+position);
t.setMovementMethod(LinkMovementMethod.getInstance());
t.setTextSize(mMsgSize);
CharSequence text = get(position);
t.setText(text);
return row;
}
It seems the problem was caused by using match_parent for my TextView width in the ListView. Changing it to wrap_content seems to have fixed it.
For an unwanted empty list item occurring in the ListView, I tried this:
List<String> listofItems;
String strlist=listofItems.get(position);
if(strlist.isEmpty())
{
remove(strlist);
}
'position' is what i got as a parameter in View getView method, because i was implementing a custom adapter.
it worked fine for me!
In my Android application I have a ListView with 5 elements. I created a custom adapter, in order to change the background of some elements of the listView. For example, the second item of the list view is not ready yet, so I want to setBackground(Color.Gray), so he can look like it's not done it. In order to do that, I Overrided the getView() method from ArrayAdapter in my custom adapter how it follows:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if(!itensAvailable[position]) v.setBackgroundColor(Color.Gray);
return v;
}
The weird thing is, no matter if I use the boolean itensAvailable[position] or !itensAvailable[position] the first element of the list always has it's background changed! All the others elements of the list are behaving like expected, except the first one. More weird than that, if I do
if(position == 2) v.setBackgroundColor(Color.Gray);
it changes the background from the item in the position 2, and the first item as well! If I do
if(position == 2) {
v.setBackgroundColor(Color.Gray);
System.out.println(v.getText());
}
Even more weird! Only the text from the position 2 gets printed, not the text from the first item.
What is going on? Android bug? By the way, im testing it on a XOOM 3.2 Honeycomb device.
And obviously, if I comment this if code, the first item doens't has it's background changed.
It is very strange !
What happens if you write :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if(!itensAvailable[position]) v.setBackgroundColor(Color.Gray);
else v.setBackgroundColor(Color.Transparent);
return v;
}
I cannot explain the weird behaviour. Can you try the following code and see if it solves your problem -
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = to the view to be displayed;
}
if(!itensAvailable[position]) convertView.setBackgroundColor(Color.Gray);
return convertView;
}
I Have the exact same issue. Strange indeed!
What worked for me is to remove the line
View v = super.getView(position, convertView, parent);
and use instead -
LayoutInflater inflater = LayoutInflater.from(getContext());
View v = inflater.inflate(R.layout.__my__layout__, parent, false);
.... more view manipulations ....
hope it helps!
Hallo all,
I have a ListView which contains a Button in each line. The following code is part of the getView() Method
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
TextView tv;
Button saveA_button;
EditText edittext;
FITB_ViewWrapper wrapper;
if (row == null) {
LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (ChooseMode_Act.modeInfo.equalsIgnoreCase("Training")) {
row = li.inflate(R.layout.exercise_for_training_fitb,parent, false);
}else {
row = li.inflate(R.layout.exercise_for_exam_fitb,parent, false);
}
wrapper=new FITB_ViewWrapper(row);
row.setTag(wrapper);
if (ChooseMode_Act.modeInfo.equalsIgnoreCase("Exam")) {
saveA_button=wrapper.getSaveAnswer_Button();
OnClickListener l=new OnClickListener() {
#Override
public void onClick(View v) {
Integer mp=(Integer)v.getTag();
Log.i("mp","my Position is: "+mp);
}
};
saveA_button.setOnClickListener(l);
}
}else {
wrapper=(FITB_ViewWrapper) row.getTag();
}
For my App i need to known to which item the Button belongs to, so i try to detect it. The code
Log.i("mp","my Position is: "+mp);
puts out a message: mp myPosition is: null
I can't understand, why do i get a "null" but not an Integer? How can i find out the Position of an Item in a ListView?
Thanks a lot.
Log.i("mp","my Position is: "+position);
you have the position already !
public View getView(final int position, View convertView, ViewGroup parent) {
The Views in a ListView are reused as you scroll up and down. Thus, setting values in getView often has unintented consequences, like the image that you meant to set for item number 5 appearing in item number 10, 15 and 20 also.
To avoid this, if you want to set properties in getView you need to make sure you set or unset them for each view.
I'm not sure what exactly you are trying to accomplish with your code, but it might help to move the setTag outside of the if statement, to make sure you are setting it each time that a view is used.