I am trying to reuse a framelayout that has an image and textview inside it but I don’t think I am doing this right. The code works and the display is right but the performance is very poor and I believe it is because I creating a new ImageView and TextView every time the adapters goes back to the item position.
Can someone tell me how to reuse the embedded ImageView (called i) and TextView (called t) without creating new objects? I am very new to Java and this is my attempt at building a Android application.
public View getView(int position, View convertView, ViewGroup parent) {
FrameLayout F;
FrameLayout ImageBorder;
FrameLayout TextBG;
ImageView i;
TextView t;
if(convertView == null) {
F = new FrameLayout(mContext);
} else {
F = (FrameLayout) convertView;
}
ImageBorder = new FrameLayout(F.getContext());
FrameLayout.LayoutParams params1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,300,Gravity.BOTTOM);
ImageBorder.setLayoutParams(params1);
i = new ImageView(F.getContext());
TextBG = new FrameLayout(F.getContext());
t = new TextView(F.getContext());
F.setBackgroundColor(Color.BLACK);
ImageBorder.setPadding(2, 2, 2, 2);
ImageBorder.setBackgroundColor(Color.BLACK);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,40,Gravity.BOTTOM);
TextBG.setLayoutParams(params);
TextBG.setBackgroundColor(Color.BLACK);
TextBG.setAlpha(.6f);
t.setLayoutParams(params);
t.setGravity(Gravity.CENTER_VERTICAL);
String pathToPhoto = FileList.get(position).toString();
String fileDescription = pathToPhoto.replaceAll("/mnt/external1/PaliPhotography/","");
fileDescription = fileDescription.replaceAll(".jpg","");
fileDescription = fileDescription.toUpperCase();
Bitmap bm = Cache.getCacheFile("thumb",pathToPhoto);
if (bm == null) {
ImageDownloader downloader = new ImageDownloader(i);
downloader.execute("thumb", pathToPhoto, "400", "400");
} else {
i.setImageBitmap(bm);
i.setScaleType(ImageView.ScaleType.CENTER_CROP);
t.setTextAppearance(getApplicationContext(), android.R.style.TextAppearance_Large);
t.setText(" " + fileDescription);
}
ImageBorder.addView(i);
ImageBorder.addView(TextBG);
ImageBorder.addView(t);
F.addView(ImageBorder);
return F;
}
}
Thank you in advance!
[EDIT]
————————— SOLUTION —————————————————–
Here is solution that I implemented based on the feedback below! Thank you!
public View getView(int position, View convertView, ViewGroup parent) {
View ReturnThisView;
ViewHolder holder;
LayoutInflater inflater;
holder = new ViewHolder();
if(convertView == null) {
inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ReturnThisView = inflater.inflate(R.layout.imagecell, null);
ReturnThisView.setTag(holder);
} else {
ReturnThisView = convertView;
}
holder.TextDescription = (TextView) ReturnThisView.findViewById(R.id.PhotoDesc);
holder.ImageThumbnail = (ImageView) ReturnThisView.findViewById(R.id.Thumbnail);
String pathToPhoto = FileList.get(position).toString();
String fileDescription = pathToPhoto.replaceAll("/mnt/external1/PaliPhotography/","");
fileDescription = fileDescription.replaceAll(".jpg","");
fileDescription = fileDescription.toUpperCase();
Bitmap bm = Cache.getCacheFile("thumb",pathToPhoto);
if (bm == null) {
ImageDownloader downloader = new ImageDownloader(holder.ImageThumbnail);
downloader.execute("thumb", pathToPhoto, "400", "400");
} else {
holder.ImageThumbnail.setImageBitmap(bm);
holder.ImageThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.TextDescription.setTextAppearance(getApplicationContext(), android.R.style.TextAppearance_Large);
holder.TextDescription.setText(" " + fileDescription);
}
return ReturnThisView;
}
}
static class ViewHolder {
TextView TextDescription;
ImageView ImageThumbnail;
}
convertView == nullinflate new row by using inflaterconvertView.setTag(holder)holder = convertView.getTag()holder.txt.setText("Foo")Arguably even for your code you can do view initialization and layout once and use Holder pattern to avoid re-initialization of the elements but I think XML will give you better experience