I have a ListView
in which every row has some text and two ImageView
: one is the same for every row, the other depends on the current item.
This is my adapter:
mArrayAdapter(Context context, int layoutResourceId, ArrayList<Exhibition> data) {
super(context, layoutResourceId, data);
this.context = context;
this.layoutResourceId = layoutResourceId;
this.list = data;
this.originalList = data;
viewHolder = new ViewHolder();
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
}
@Override
@NonNull
public View getView(final int position, View convertView, @NonNull final ViewGroup parent) {
View row;
final Exhibition ex;
if(convertView==null){
row = LayoutInflater.from(getContext()).inflate(R.layout.row,parent,false);
viewHolder.expand = (ImageView)row.findViewById(R.id.expand);
row.setTag(viewHolder);
}
else {
row = convertView;
viewHolder = (ViewHolder)row.getTag();
}
ex = list.get(position);
descr = (TextView)row.findViewById(R.id.descr);
ttl = (TextView)row.findViewById(R.id.title);
city = (TextView)row.findViewById(R.id.city);
dates = (TextView)row.findViewById(R.id.dates);
museum = (TextView)row.findViewById(R.id.location);
header = (ImageView)row.findViewById(R.id.hd);
ttl.setText(ex.name);
descr.setText(ex.longdescr);
museum.setText(ex.museum);
city.setText(ex.city);
final Bitmap bitmap = getBitmapFromMemCache(ex.key);
if (bitmap != null) {
header.setImageBitmap(bitmap);
} else {
header.setImageBitmap(ex.getHeader());
addBitmapToMemoryCache(ex.key,ex.header);
}
SimpleDateFormat myFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.ITALY);
Date start = new Date(ex.getStart()), end = new Date(ex.getEnd());
String startEx = myFormat.format(start);
String endEx = myFormat.format(end);
String finalDate = getContext().getResources().getString(R.string.ex_date, startEx, endEx);
dates.setText(finalDate);
viewHolder.expand.setId(position);
if(position == selectedId){
descr.setVisibility(View.VISIBLE);
ttl.setMaxLines(Integer.MAX_VALUE);
dates.setMaxLines(Integer.MAX_VALUE);
museum.setMaxLines(Integer.MAX_VALUE);
city.setMaxLines(Integer.MAX_VALUE);
}else{
descr.setVisibility(View.GONE);
ttl.setMaxLines(1);
dates.setMaxLines(1);
museum.setMaxLines(1);
city.setMaxLines(1);
}
viewHolder.expand.setOnClickListener(this.onCustomClickListener);
return row;
}
public void setDescr(int p){
selectedId = p;
}
public void setOnCustomClickListener(final View.OnClickListener onClickListener) {
this.onCustomClickListener = onClickListener;
}
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
@Override
public int getCount()
{
return list.size();
}
@Override
public boolean isEnabled(int position)
{
return true;
}
@Override
public Exhibition getItem (int pos){
return list.get(pos);
}
void resetData() {
list = originalList;
}
private class ViewHolder {
ImageView expand,header;
}
@Override
@NonNull
public Filter getFilter() {
if (valueFilter == null) {
Log.d("SEARCH1","New filter");
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint == null || constraint.length() == 0){
results.values = originalList;
results.count = originalList.size();
}
else {
List<Exhibition> nExhList = new ArrayList<>();
for(Exhibition e : list){
Log.d("NAMEE",e.name + " " + constraint.toString());
if (e.getName().toUpperCase().contains(constraint.toString().toUpperCase()) || e.getCity().toUpperCase().contains(constraint.toString().toUpperCase())
||e.getMuseum().toUpperCase().contains(constraint.toString().toUpperCase()) || e.getLongDescription().toUpperCase().contains(constraint.toString().toUpperCase())
|| e.getDescription().toUpperCase().contains(constraint.toString().toUpperCase()) || e.getCategory().toUpperCase().contains(constraint.toString().toUpperCase())){
nExhList.add(e);
}
}
results.values= nExhList;
results.count=nExhList.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if(results.count==0){
notifyDataSetInvalidated();
}
else{
list = (ArrayList<Exhibition>)results.values;
notifyDataSetChanged();
}
}
}
The first ImageView
is a Bitmap
stored in a Exhibition
variable.
The second one changes the visibility of a text to get a expandable-like effect (because for now I can't convert the ListView
to a ExpandableListView
).
I tried different things like the cache, an AsyncTask
, removing the custom click listener, put everything in ViewHolder
but the scrolling is full of microlags. Is there something wrong in the adapter that I don't get it?