Reputation: 9374
I'm facing an annoying problem, the values of ListView items get mixed !
I have a simple ListView with a TextView ( with adapter view), and Onclicklistner ImageView, when I click on the ImageView the value of of the textview changes.
But when I scroll up and down, the values get mixed, so it's a little bit annoying.
I have been looking for a solution and I found which named " View Holder " I tried that as well, but i'm having the same problem here is my adapter view code :
public class adapter extends ArrayAdapter<statisticitem> {
int likes;
public adapter(Context context, ArrayList<statisticitem> questionaires) {
super(context, 0, questionaires);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom, parent, false);
holder = new ViewHolder();
holder.text1 = (TextView) convertView.findViewById(R.id.textView1);
holder.button = (ImageView) convertView.findViewById(R.id.imageView1);
holder.text2 = (TextView) convertView.findViewById(R.id.textView2);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final statisticitem s = getItem(position);
if (s != null) {
holder.text1.setText(s.getIdQuestion());
holder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
likes++;
holder.text2.setText("yasser");
}
});
}
return convertView;
}
}
and my view holder class :
public class ViewHolder {
TextView text1;
TextView text2;
ImageView button;
}
Upvotes: 1
Views: 362
Reputation: 1440
I started a project from scratch, added and slightly modified your code, tested... and finally got this:
statisticitem
public class statisticitem {
String id;
public statisticitem(String id) {
this.id = id;
}
public String getIdQuestion() {
return id;
}
}
Adapter
public class Adapter extends ArrayAdapter<statisticitem> {
int[] likes;
public Adapter(Context context, ArrayList<statisticitem> questionaires) {
super(context, 0, questionaires);
likes = new int[questionaires.size()];
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.itemview, parent, false);
holder = new ViewHolder();
holder.text1 = (TextView) convertView.findViewById(R.id.tvText1);
holder.button = (Button) convertView.findViewById(R.id.btButton);
holder.text2 = (TextView) convertView.findViewById(R.id.tvText2);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final statisticitem s = getItem(position);
if (s != null) {
holder.text1.setText(s.getIdQuestion());
holder.text2.setText(likes[position] > 0 ? "yasser" : "");
holder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
likes[position]++;
notifyDataSetChanged();
}
});
}
return convertView;
}
public class ViewHolder {
TextView text1;
TextView text2;
Button button;
}
}
Main Activity
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lvItems = (ListView) findViewById(R.id.lvItems);
// Build data.
ArrayList<statisticitem> questionaires = new ArrayList<statisticitem>();
for (int i = 0; i < 50; i++) {
questionaires.add(new statisticitem(String.valueOf(i)));
}
// Display items.
Adapter adapter = new Adapter(this, questionaires);
lvItems.setAdapter(adapter);
}
}
Layouts:
activity_main
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@+id/lvItems"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
itemview
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical" >
<TextView
android:id="@+id/tvText1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvText2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:id="@+id/btButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="like" />
</LinearLayout>
Upvotes: 0
Reputation: 4596
Inside the adapter class you are writing a if condition to check 's' is null or not write the else condition also
if (s !=null)
{
holder.text1.setText(s.getIdQuestion());
holder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
likes++;
holder.text2.setText("yasser");
}
});
}
else
{
//write something to the text view
holder.text1.setText("");
holder.text2.setText("");
}
check whether it helps!!!
Upvotes: 2
Reputation: 15831
Rewrite into
public class adapter extends ArrayAdapter<statisticitem> {
int likes;
public adapter(Context context, ArrayList<statisticitem> questionaires) {
super(context, 0, questionaires);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
final statisticitem s = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom, parent, false);
holder = new ViewHolder();
holder.text1 = (TextView) convertView.findViewById(R.id.textView1);
holder.button = (ImageView) convertView.findViewById(R.id.imageView1);
holder.text2 = (TextView) convertView.findViewById(R.id.textView2);
convertView.setTag(holder);
if (s != null) {
holder.text1.setText(s.getIdQuestion());
holder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
likes++;
holder.text2.setText("yasser");
}
});
} else {
holder.text1.setText("");
}
} else {
holder = (ViewHolder) convertView.getTag();
if (s != null) {
holder.text1.setText(s.getIdQuestion());
} else {
holder.text1.setText("");
}
}
return convertView;
}
}
You need set OnClickListener
once at time, because getView
method execute often then you expected.
And i recommend to you put likes
into ViewHolder like an
public class ViewHolder {
TextView text1;
TextView text2;
ImageView button;
int likes;
}
and in OnClickListener
:
holder.likes++;
holder.text2.setText("yasser");
instead of
likes++;
holder.text2.setText("yasser");
Upvotes: 0