I'm not sure why it's not working, but what my code should do is very simple.
I have a ListView with default text color (BLACK) and typeface (MONOSPACE) that I declared in getView(), so everything works well when the view is created.
When I select an item from the list it should change the text color to RED and the typeface to MONOSPACE and BOLD, and if I click another item, it will change that item to RED and BOLD and return the previous text to BLACK and NORMAL. This works just fine, but if I scroll away from the RED and BOLD text until it's not visible, and then scroll back, the text is no longer RED and BOLD, but BLACK and NORMAL.
Help is greatly appreciated! Thanks
private ArrayList<String> list;
private ListView myView;
private ListAdapter listAdapter;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add("Hello world " + i);
}
listAdapter = new ListAdapter();
myView = (ListView) findViewById(R.id.myList);
myView.setAdapter(listAdapter);
myView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView tv = (TextView) view.findViewById(R.id.textView);
tv.setTextColor(Color.RED);
tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
}
});
}
public class ListAdapter extends BaseAdapter {
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.listview_layout, null);
TextView txt = (TextView) view.findViewById(R.id.textView);
txt.setText(list.get(i));
txt.setTextColor(Color.BLACK);
txt.setTypeface(Typeface.MONOSPACE, Typeface.NORMAL);
return view;
}
}
Ok, first of all you should keep the style difference between the rows by a flag. So instead of passing a list of String to the adapter, you should consider a list containing pair of a string and a flag. This problem happens because ListView holds limited count of views and when scrolling happened, it assigns values to them.
public class MainActivity extends AppCompatActivity {
private List<Pair> list;
private ListAdapter listAdapter;
private ListView myView;
private int lastClickedPosition = 0;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(new Pair("Hello world " + i, false));
}
listAdapter = new ListAdapter();
myView = (ListView) findViewById(R.id.myList);
myView.setAdapter(listAdapter);
myView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
list.get(lastClickedPosition).flag = false;
list.get(position).flag = true;
lastClickedPosition = position;
listAdapter.notifyDataSetChanged();
}
});
}
public class ListAdapter extends BaseAdapter {
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.listview_layout, null);
TextView txt = (TextView) view.findViewById(R.id.textView);
txt.setText(list.get(i).text);
if (list.get(i).flag) {
txt.setTextColor(Color.RED);
txt.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
} else {
txt.setTextColor(Color.BLACK);
txt.setTypeface(Typeface.MONOSPACE, Typeface.NORMAL);
}
return view;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
}
static class Pair {
String text;
boolean flag;
Pair(String text, boolean flag){
this.text = text;
this.flag = flag;
}
}
}