I have a simple CursorAdapter that gets a title and image.
It shows the title and then loads the image from the Internet.
However, when I call the image loader the image is loaded at the wrong place, and it starts going really wild: see here.
My complete code is here.
The adapter is RestaurantListActivityCursorAdapter
public class RestaurantListActivityCursorAdapter extends CursorAdapter {
/* Api variables */
String websiteURL = "http://cicolife.com";
public RestaurantListActivityCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.activity_main_list_item, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Extract properties from cursor
int get_Id = cursor.getInt(cursor.getColumnIndexOrThrow("_id"));
String getTitle = cursor.getString(cursor.getColumnIndexOrThrow("title"));
String getImage = cursor.getString(cursor.getColumnIndexOrThrow("image"));
// Name
TextView listViewTitle = (TextView) view.findViewById(R.id.listViewTitle);
listViewTitle.setText(getTitle);
// Img
ImageView listViewImage = (ImageView) view.findViewById(R.id.listViewImage);
if(getImage != null) {
if (!(getImage.equals(""))) {
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+ File.separatorChar+"/Android/data/com.nettport.restaurants/imgs";
File file = new File (destinationPath, getImage);
if (file.exists ()){
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
listViewImage.setImageBitmap(myBitmap);
}
else {
String loadImage = websiteURL + "/_cache/" + getImage;
new HttpRequestImageLoadTask(context, loadImage, listViewImage, getImage,"imgs").execute();
}
}
}
}
}
The image loader HttpRequestImageLoadTask
public class HttpRequestImageLoadTask extends AsyncTask<Void, Void, Bitmap> {
private String url;
private ImageView imageView;
private LinearLayout linearLayout;
private Resources resources;
private Context context;
private String storeDirectory;
private String imageName;
public interface TaskListener {
void onFinished(String result);
}
public HttpRequestImageLoadTask(Context ctx, String url, ImageView imageView, String imgName, String storeDirectory) {
this.context = ctx;
this.url = url;
this.imageView = imageView;
this.imageName = imgName;
this.storeDirectory = storeDirectory;
}
public HttpRequestImageLoadTask(Context ctx, String url, LinearLayout linearLayout, Resources resources, String imgName, String storeDirectory) {
this.context = ctx;
this.url = url;
this.linearLayout = linearLayout;
this.imageName = imgName;
this.storeDirectory = storeDirectory;
}
#Override
protected Bitmap doInBackground(Void... params) {
if (checkIfCacheExists(imageName)) {
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants/" + storeDirectory;
File file = new File (destinationPath, imageName);
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
return myBitmap;
} else {
try {
URL urlConnection = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlConnection
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
saveImage(myBitmap);
return myBitmap;
} catch(Exception e){
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if(imageView != null) {
imageView.setImageBitmap(result);
} else {
if(linearLayout != null){
BitmapDrawable background = new BitmapDrawable(resources, result);
linearLayout.setBackground(background);
}
}
}
public boolean checkIfCacheExists(String imgName){
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants/" + storeDirectory;
File file = new File (destinationPath, imgName);
return file.exists();
}
private void saveImage(Bitmap finalBitmap) {
// Make dir
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants/" + storeDirectory;
File folder = new File(destinationPath);
try {
if (!folder.exists()) {
// Make Android
destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android";
folder = new File(destinationPath);
if (!folder.exists()) {
folder.mkdir();
}
// Make Android/data
destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data";
folder = new File(destinationPath);
if (!folder.exists()) {
folder.mkdir();
}
// Make Android/data/com.nettport.restaurants
destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants";
folder = new File(destinationPath);
if (!folder.exists()) {
folder.mkdir();
}
// Make Android/data/com.nettport.restaurants/storeDirectory
destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants/" + storeDirectory;
folder = new File(destinationPath);
if (!folder.exists()) {
folder.mkdir();
}
}
} catch (Exception e){
Toast.makeText(context, "Could not create directory:\n" + e.toString(), Toast.LENGTH_LONG).show();
}
if(imageName != null) {
File file = new File(destinationPath, imageName);
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
// Toast.makeText(context, "Cant save image\n" + e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
You have not put any else condition for your ImageView in your adapter. I see there are several else blocks are missing here.
if(getImage != null) {
if (!(getImage.equals(""))) {
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+ File.separatorChar+"/Android/data/com.nettport.restaurants/imgs";
File file = new File (destinationPath, getImage);
if (file.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
listViewImage.setImageBitmap(myBitmap);
} else {
String loadImage = websiteURL + "/_cache/" + getImage;
// Add nothing here when the image is being fetched
listViewImage.setImageBitmap(null);
new HttpRequestImageLoadTask(context, loadImage, listViewImage, getImage,"imgs").execute();
}
} else {
// Add an else block here when image is equals ""
listViewImage.setImageBitmap(null);
}
} else {
// Add an else block here when image is null
listViewImage.setImageBitmap(null);
}
You need to specify every possible combination in your adapter while loading the images in your ImageView.
And if you have the image url from server, just use Glide to load the images when they are not available in cache.
Related
I'm a beginner Android Developer (graduating univ and looking for a job)
So, I'm developing app uploading so many GIF files and others downloading and save their phones.
I can download GIF or other image files and save to my directory. But the problem is that Bitmap.compress not support GIF(only png,jpg..etc).
So, I compressed GIF files to png or jpg. As expected, the image didn't animated. My images are all GIF files. How can I compress GIF files and save to my directory??
Bellow is my code
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final ViewGroup view1 = (ViewGroup) inflater.inflate(R.layout.fragment1, container, false);
Button button = (Button) view1.findViewById(R.id.saveBtn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
new Thread(new Runnable() {
#Override
public void run() {
try{
bm = getBitmap(myUrl);
}catch (Exception e){
}finally {
if(bm != null){
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
getAlbumStorageDir(albumName,"GifImage_"+num);
num++;
}//end run()
});
}
}
}
}).start();
return view1;
}
private Bitmap getBitmap(String url) {
URL imgUrl = null;
HttpURLConnection connection = null;
InputStream is = null;
Bitmap retBitmap = null;
try{
imgUrl = new URL(url);
connection = (HttpURLConnection) imgUrl.openConnection();
connection.setDoInput(true);
connection.connect();
is = connection.getInputStream(); // get inputstream
retBitmap = BitmapFactory.decodeStream(is);
}catch(Exception e) {
e.printStackTrace();
return null;
}finally {
if(connection!=null) {
connection.disconnect();
}
return retBitmap;
}
}
public void getAlbumStorageDir(String albumName, String imageName) {
String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath();
String folder_name = "/" + albumName + "/";
String file_name = imageName;
String string_path = root + folder_name;
String save_path = string_path + file_name;
File file_path;
try {
file_path = new File(string_path);
if (!file_path.isDirectory()) {
file_path.mkdirs();
}
FileOutputStream out = new FileOutputStream(string_path + file_name);
bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+save_path))); //갤러리 갱신
Toast.makeText(getContext(), "save success ", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have created a ImageLoading class which downloads and saves data to local storage. I am also calling it from multiple activities. After saving I need to update collection of class from which the instance of asyncTask is created. I don't want to use if statements in task to handle this and I don't want to inherit this task to other activities. Please Suggest me how to do this. I am sharing my code here.
public class LoadImageTask extends AsyncTask<Void, Void, Bitmap> {
private String url;
private ImageView imageView;
private long ID;
private Context context;
private SQLiteHandler sqLiteHandler;
private String imageType;
private int position;
public LoadImageTask(String url, ImageView imageView, long ID, Context context, String imageType, int position) {
this.url = url;
this.imageView = imageView;
this.ID = ID;
this.context = context;
this.imageType = imageType;
this.position = position;
sqLiteHandler = new SQLiteHandler(context);
}
String getRandomString(int length)
{
String data = "";
Random rand = new Random();
for (int i = 1 ; i <= length ; i++) {
int n = rand.nextInt(26) + 97;
data += String.valueOf((char)n);
}
return data;
}
private File getOutputMediaFile(){
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ context.getPackageName()
+ "/Files");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmssSSS").format(new Date());
timeStamp = String.format("%s_%s", timeStamp, getRandomString(10));
File mediaFile;
String mImageName="Image_"+ timeStamp +".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
private void storeImage(Bitmap image) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d("Error:","Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
ImageDownload imageDownload = new ImageDownload(ID,pictureFile.getAbsolutePath());
if(imageType.equals(Constants.ImageType.PROFILE)) {
sqLiteHandler.UpdateUserImagePath(imageDownload,Constants.ImageType.PROFILE);
}
else if(imageType.equals(Constants.ImageType.BANNER)) {
sqLiteHandler.UpdateUserImagePath(imageDownload,Constants.ImageType.BANNER);
}
else if(imageType.equals(Constants.ImageType.SUBJECT)) {
if(sqLiteHandler.UpdateUserImagePath(imageDownload,Constants.ImageType.SUBJECT)){
((MainActivity) context).subjectsItems.get(position).Image = imageDownload.ImagePath;
//((MainActivity) context).subjectsItems.get(position).Image = imageDownload.ImagePath;
//((MessageList) context).messageDataItems.get(position).SubjectImage = imageDownload.ImagePath;
}
}
} catch (FileNotFoundException e) {
Log.d("Error:", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Error:", "Error accessing file: " + e.getMessage());
}
}
#Override
protected Bitmap doInBackground(Void... params) {
try {
URL urlConnection = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlConnection
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
Drawable d = new BitmapDrawable(imageView.getResources(), result);
imageView.setBackground(d);
storeImage(result);
//imageView.setImageBitmap(result);
}
}
Simply just do it like this :
((AppCompatActivity) context).subjectsItems.get(position).Image = imageDownload.ImagePath;
Please pardon any bad English as this is my first time posting question on stackoverflow.
I would like to create a OCR Android Application using tesseract OCR engine and faced the following error, I have tried to search around but however did not find any solution, would appreciate your help. Thanks.
Codes I am trying:
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.init(Environment.getExternalStorageDirectory().toString()+"/", `"eng");`
I have already created a tessdata folder in my device root with the eng.traineddata file inside, but I was prompted the following error when I access the function.
Could not initialize Tesseract API with language=eng!
I am using Android 6.0.1, API 23
Would appreciate any help! Thanks in advance~
Try this code out . It allows you to take a picture and displays the text .There are minor bugs in this code .Try this code on letters typed in notepad
Ignore the various files being placed in the tessdata folder . I am trying to read maths equation hence i need those . I have commented out the other files, it shouldn't bother you. If you are willing to try , try Mobile Vision API.
Hope this helps :)
public class MainActivity extends AppCompatActivity {
String imgPath;
Bitmap imgBitmap;
Uri imgUri;
InputStream trainDataInputStream;
OutputStream trainDataOutputStream;
AssetManager assetManager;
String externalDataPath;
TextView t;
String[] fileToBeCopied = {"eng.cube.bigrams", "eng.cube.fold", "eng.cube.lm", "eng.cube.nn", "eng.cube.params", "eng.cube.size", "eng.cube.word-freq", "eng.tesseract_cube.nn", "eng.traineddata","equ.traineddata"};
ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t = (TextView) findViewById(R.id.text);
new CopyFile().execute();
//placeFileFromAssetsToExternalStorage();
takePicture();
}
class CopyFile extends AsyncTask {
#Override
protected void onPreExecute() {
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Fetching image...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Object doInBackground(Object[] objects) {
//placeFileFromAssetsToExternalStorage(fileToBeCopied[0]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[1]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[2]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[3]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[4]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[5]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[6]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[7]);
placeFileFromAssetsToExternalStorage(fileToBeCopied[8]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[9]);
return null;
}
#Override
protected void onPostExecute(Object o) {
pDialog.dismiss();
}
}
private void takePicture() {
File photoFile = null;
Intent iPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (iPicture.resolveActivity(getPackageManager()) != null) {
try {
photoFile = createImageFile();
} catch (Exception e) {
e.printStackTrace();
}
//if photo file is created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getApplicationContext(), "com.scorpio.fileprovider", photoFile);
System.out.println(imgPath);
iPicture.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(iPicture, 1);
}
}
}
private File createImageFile() {
File imgFile = null;
String fileStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File storageDir = Environment.getExternalStorageDirectory();
try {
imgFile = File.createTempFile(fileStamp, ".jpeg", storageDir);
} catch (IOException e) {
e.printStackTrace();
}
imgPath = imgFile.getAbsolutePath();
return imgFile;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
galleryAddPic();
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(imgPath);
System.out.println("Image path ->" + imgPath);
Uri contentUri = Uri.fromFile(f);
imgUri = contentUri;
System.out.println("Image uri " + imgUri);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
ocrImage();
}
public void ocrImage() {
try {
//getting image for ocr
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
imgBitmap = BitmapFactory.decodeFile(imgPath, options);
} catch (Exception e) {
e.printStackTrace();
}
ExifInterface exif = null;
try {
exif = new ExifInterface(imgPath);
} catch (IOException e) {
e.printStackTrace();
}
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0) {
int w = imgBitmap.getWidth();
int h = imgBitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
imgBitmap = Bitmap.createBitmap(imgBitmap, 0, 0, w, h, mtx, false);
}
imgBitmap = imgBitmap.copy(Bitmap.Config.ARGB_8888, true);
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.init(externalDataPath, "eng");
baseApi.setImage(imgBitmap);
String ocrResult = baseApi.getUTF8Text();
System.out.println(ocrResult);
baseApi.end();
t.setText(ocrResult);
}
public void placeFileFromAssetsToExternalStorage(String filename) {
System.out.println("Running DataRunnable class ");
assetManager = getResources().getAssets();
externalDataPath = Environment.getExternalStorageDirectory() + "/tessdata";
System.out.println("external data path " + externalDataPath);
//creating eng.trainedData
File f = new File(externalDataPath);
try {
if (!f.exists()) {
f.mkdir();
}
externalDataPath = externalDataPath + "/" + filename;
f = new File(externalDataPath);
if (!f.exists())
f.createNewFile();
externalDataPath = Environment.getExternalStorageDirectory().toString();
trainDataInputStream = assetManager.open(filename);
trainDataOutputStream = new FileOutputStream(f);
byte[] buffer = new byte[1024];
int read;
while ((read = trainDataInputStream.read(buffer)) != -1) {
trainDataOutputStream.write(buffer, 0, read);
}
trainDataOutputStream.flush();
trainDataOutputStream.close();
trainDataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is the code:
public void Displayimg(View v) {
File path = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp");
ipath[0] = String.valueOf(((TextView) v).getText());
String sifile = ipath[0].substring(45,52); // extracting the filename from the view eg: abc.jpg
File imgfile = new File(path,sifile); // it fails on this line with unfortunately, main application has stopped.
// if the sifile conatians a name of the file that exist, it give error and comes out
// if I give file name in sifile that does not exisit, if give file does on exisit and comes our with error.
// Basically I am having problem to open an image file that exisit and dispaly.
// File("/storage/sdcard0/Pictures/MyCameraApp/Zimg20151105_1535133.Jpg");
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
ImageView myImage = (ImageView) findViewById(R.id.mc_imgview);
if(imgfile.exists()){
Toast.makeText(getApplicationContext(),file.getAbsolutePath() + "File Exisit", Toast.LENGTH_SHORT).show();
myImage.setImageBitmap(myBitmap);
}
else
{
Toast.makeText(getApplicationContext(),file.getAbsolutePath() + " File Does not Exisit", Toast.LENGTH_SHORT).show();
}
}
Display image :
Try to Search Volley or Universal-Image-Loader or Glide.
Save Image:
public static String getSdPath(){
//todo test path
return Environment.getExternalStorageDirectory().getAbsolutePath();
// return "";
}
public static String getImageDir (String type,Activity activity){
if(type.equalsIgnoreCase("pure")){
return getSdPath()+ activity.getDir("pure", Context.MODE_PRIVATE).getAbsolutePath();
}else{
return getSdPath()+activity.getDir("deal", Context.MODE_PRIVATE).getAbsolutePath();
}
}
private static final String APPLICATION_NAME = "test";
private static final Uri IMAGE_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
private static final String PATH = getImageDir("deal", mActivity);
public static Uri savePngImage(ContentResolver cr, Bitmap bitmap) {
long dateTaken = System.currentTimeMillis();
String name = String.valueOf(dateTaken) + ".png";
return savePngImage(cr, name, dateTaken, PATH, name, bitmap);
}
public static Uri savePngImage(ContentResolver cr, String name, long dateTaken, String directory,
String filename, Bitmap source) {
OutputStream outputStream = null;
String filePath = directory + File.separator + filename;
try {
File dir = new File(directory);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(directory, filename);
if (file.createNewFile()) {
outputStream = new FileOutputStream(file);
if (source != null) {
source.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
} else {
}
}
// FileUtils.updateFile(file);
} catch (FileNotFoundException ex) {
return null;
} catch (IOException ex) {
return null;
} catch (NullPointerException ex) {
return null;
}finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (Throwable t) {
}
}
}
ContentValues values = new ContentValues(7);
values.put(MediaStore.Images.Media.TITLE, name);
values.put(MediaStore.Images.Media.DISPLAY_NAME, filename);
values.put(MediaStore.Images.Media.DATE_TAKEN, dateTaken);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATA, filePath);
// FileUtils.updateFile(filePath);
return cr.insert(IMAGE_URI, values);
}
I have a ListAdapter that contains a bunch of images that are being downloaded from the internet. When I scroll up and down there seems to be a performance hit and things get jerky. How can I resolve this?
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.message_row, null);
}
STMessage aMessage = messages.get(position);
if (aMessage != null) {
TextView usernameTextView = (TextView) v.findViewById(R.id.usernameTextView);
TextView bodyTextView = (TextView) v.findViewById(R.id.bodyTextView);
TextView dateTextView = (TextView) v.findViewById(R.id.dateTextView);
ImageView avatarImageView = (ImageView)v.findViewById(R.id.avatarImageView);
if (usernameTextView != null) {
usernameTextView.setText(Html.fromHtml(aMessage.getUser_login()));
}
if (bodyTextView != null) {
bodyTextView.setText(aMessage.getBody());
//linkify urls
Linkify.addLinks(bodyTextView, Linkify.WEB_URLS);
//linkify symbols
Pattern symbolMatcher = Pattern.compile("/(?:^|\\s|[\\.(\\+\\-\\,])(?:\\$?)\\$((?:[0-9]+(?=[a-z])|(?![0-9\\.\\:\\_\\-]))(?:[a-z0-9]|[\\_\\.\\-\\:](?![\\.\\_\\.\\-\\:]))*[a-z0-9]+)/i");
String symbolURL = "content://com.stocktwits.activity/symbol/";
Linkify.addLinks(bodyTextView, symbolMatcher, symbolURL);
}
if (dateTextView != null) {
dateTextView.setText(aMessage.getUpdated_at());
}
if (avatarImageView != null) {
imageDownloader.download(aMessage.getAvatar_url(), avatarImageView);
}
}
return v;
}
Use Lazy Loading of Images - Lazy load of images in ListView
Maybe by using a Threads pool (queue) and placing a temporal image in the meantime?
Here is a nice way to go about it.
At least I think its nice. I did it :)
here is the class I used to load the ImageView in the background.
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
private ImageView destination;
private String cachedFile;
private Date startTime;
private DownloadCompletedListener completedListener;
public DownloadImageTask(ImageView destination, String cachedFile, DownloadCompletedListener completedListener)
{
this.destination = destination;
this.cachedFile = cachedFile;
this.startTime = new Date();
this.completedListener = completedListener;
}
protected Bitmap doInBackground(String... urls)
{
Bitmap result = getBitmapFromURL(urls[0]);
if (result != null)
{
try {
FileOutputStream out = new FileOutputStream(HSAppUtil.getFilePath(getFilenameFromUrl(urls[0])));
result.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
result = Bitmap.createBitmap(1,1,Config.ARGB_8888);
}
return result;
}
public String getHost() {
return "http://MyMainHost";
}
public Bitmap getBitmapFromURL(String fileUrl) {
String newFileUrl = null;
if (!fileUrl.contains("://"))
{
newFileUrl = getHost() + fileUrl;
}
else
{
newFileUrl = fileUrl;
}
URL myFileUrl = null;
try {
myFileUrl = new URL(newFileUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
int length = conn.getContentLength();
InputStream is = conn.getInputStream();
length++;
return BitmapFactory.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Bitmap result)
{
synchronized (destination)
{
Date lastUpdated = (Date)destination.getTag();
if (lastUpdated == null || lastUpdated.before(startTime))
{
boolean handled = false;
if (completedListener != null)
{
handled = completedListener.handleDownloadCompleted(destination, result);
}
if (!handled && destination != null)
{
destination.setTag(startTime);
destination.setImageBitmap(result);
}
}
result = null;
}
}
public interface DownloadCompletedListener {
boolean handleDownloadCompleted(ImageView i, Bitmap b);
}
}
then when you want to use it, You would call it like this.
new DownloadImageTask(imView, fileUrl, completedListener).execute(fileUrl);
and send the imView to the UI. it will load the image in when it downloads it.
Please give me your honest feedback.