I'm trying to use the library to perform volley download images from my server.
In my activity I add items dynamically and then realize the exchange of image at runtime.
Below is the code of the attempt to get the picture:
public void updateThumbnails(ArrayList<Book> arrBook,ArrayList<View> arrView){
if(arrBook.size()<= 0){
return;
}
if(arrView.size() <= 0){
return;
}
int intBooks = arrView.size();
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
for(int intIndex = 0; intIndex < intBooks; intIndex++){
View _view = arrView.get(intIndex);
final View _viewLoader = _view;
imageLoader.get(Const.START_REQUEST_BOOK_IMAGE + arrBook.get(intIndex).getId().toString() + ".jpg", new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer imageContainer, boolean b) {
ImageView imgBook = (ImageView) _viewLoader.findViewById(R.id.img_book);
animationChangeImage(imageContainer.getBitmap(),imgBook);
}
#Override
public void onErrorResponse(VolleyError volleyError) {
}
});
TextView txtTitleBook = (TextView) _view.findViewById(R.id.name_book);
txtTitleBook.setVisibility(View.INVISIBLE);
}
}
You need to check that the returned bitmap (imageContainer.getBitmap()) isn't null before going ahead and assigning it.
Try and adding log prints to see if you're getting errors or a null bitmap, which could mean you're performing a bad request or server error, or perhaps the fault is in the animationChangeImage method if the bitmap is received successfully.
Did you try using the ImageRequest class? For example:
ImageRequest irq = new ImageRequest(imgUrl, new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap response) {
imView.setImageBitmap(response);
}
}, 0, 0, null, null);
Related
The app I am making need to take pictures to send them to a server.
I need to take 6 photos at least. I have a recyclerView in which I am displaying a preview of my photo. It's working perfectly (I am using Picasso as photo library).
I need to be able to delete photos before sending them away (and consequently their preview). With a click on the preview, I remove it from my photo tab and update my recyclerview with notifyDataSetChanged().
The photo disappears.
When I take an other picture, I have its preview but the preview from the deleted picture is coming back.
If I delete three pictures and take a new one, I have the preview of the new one and the preview of the 3 deleted pictures.
Here's part of my adapter where I bind my view
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
mImageView = holder.mPhotoIV;
File mFile = new File(String.valueOf(Uri.parse(mListOfPhotos.get(position))));
int width = mImageView.getLayoutParams().width;
int height = mImageView.getLayoutParams().height;
Picasso.get()
.load(mFile)
.resize(200, 200)
.error(R.drawable.ic_no_photo_foreground)
.into(mImageView, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError(Exception e) {
}
});
}
Here part of my activity where I'm calling my adapter
mTakePhotoFAB.setOnClickListener(view -> {
mDir = new File(getExternalCacheDir(), "PhotosAuthentifier");
boolean success = true;
if (!mDir.exists()) {
success = mDir.mkdir();
}
if (success) {
File mFile = new File(mDir, new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault()).format(new Date()) + ".jpg");
mImageCapture.takePicture(mFile,
new ImageCapture.OnImageSavedListener() {
#Override
public void onImageSaved(#NonNull File file) {
mListOfPhotos.add(file.getAbsolutePath());
mNumberOfPhotoTV.setText(getResources().getString(R.string.minPhotos, mListOfPhotos.size()));
if (mListOfPhotos.size() >= 6) {
mSendPhotoFAB.setVisibility(View.VISIBLE);
}
mAdapter = new CameraPhotoAdapter(mListOfPhotos, getBaseContext());
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void onError(#NonNull ImageCapture.ImageCaptureError imageCaptureError, #NonNull String message, #Nullable Throwable cause) {
String mMessage = "Photo capture failed: " + message;
Toast.makeText(CameraActivity.this, mMessage, Toast.LENGTH_SHORT).show();
assert cause != null;
cause.printStackTrace();
}
});
}
});
Function (in my adapter) to remove picture
protected void removePhoto(Context context, ArrayList<String> array, int position) {
File mDir = new File(context.getExternalCacheDir(), "PhotosAuthentifier");
File mFile = new File(array.get(position));
if (mDir.exists()) {
File[] mFilesIntoDir = mDir.listFiles();
if (mFilesIntoDir == null) {
return;
} else {
for (int i = 0; i < mFilesIntoDir.length; i++) {
if (mFilesIntoDir[i].getAbsolutePath().equals(mFile.getAbsolutePath())) {
boolean mSuccess = mFilesIntoDir[i].delete();
if (mSuccess) {
Picasso.get().invalidate(mFile.getAbsolutePath());
mListOfPhotos.remove(mFile.getAbsolutePath());
notifyDataSetChanged();
}
}
}
}
}
}
I tried to invalidate Picasso cache but when I take a new picture, instead of the deleted picture reappearing I have the default behavior when I don't have a good url to upload (a black cross)
Could anyone help please :)?
I want to get a Bitmap[] from my String[] with links. But this doesn't work as I want. I have this Method:
private Bitmap[] getBitmaps(String[] images){
ArrayList<Bitmap> temp = new ArrayList<>();
for(int i = 0; i < images.length; i++){
ImageView img = new ImageView(getContext());
FrameLayout.LayoutParams x = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
img.setLayoutParams(x);
Picasso.with(getContext()).load(MainPostAdapter.USER_URL+images[i]+".png").into(img, new Callback() {
#Override
public void onSuccess() {
temp.add(BitmapRes.drawableToBitmap(img.getDrawable()));
movableBackgroundContainer.removeView(img);
}
#Override
public void onError() {
}
});
movableBackgroundContainer.addView(img);
}
return temp.toArray(new Bitmap[temp.size()]);
}
The problem is I get a null Array because it adds the Bitmap to the list after the onSuccess function. How can I now wait until all onSuccess added the bitmaps and then return?
The get() function of Picasso does what you're looking for. It downloads a Bitmap rather than load an image into an ImageView. Note that Picasso's get() method cannot be called on the main thread. My example uses an AsyncTask to download images on a separate thread.
String[] images = new String[] {"http://path.to.image1.jpg", "http://path.to.image2.jpg"};
new AsyncTask<String[], Void, List<Bitmap>>() {
#Override
protected List<Bitmap> doInBackground(String[]... params) {
try {
List<Bitmap> bitmaps = new ArrayList<Bitmap>();
for (int i = 0; i < params[0].length; ++i) {
bitmaps.add(Picasso.with(getActivity()).load(params[0][i]).get());
}
return bitmaps;
} catch (IOException e) {
return null;
}
}
#Override
public void onPostExecute(List<Bitmap> bitmaps) {
if (bitmaps != null) {
// Do stuff with your loaded bitmaps
}
}
}.execute(images);
You could increase an integer every time on success until the integer equals to the images.lengh(). You could check this with a loop. And in the loop is an if clause within the return.
For example
int currentSuccess = 0;
In the loop:
#Override
public void onSuccess() {
temp.add(BitmapRes.drawableToBitmap(img.getDrawable()));
movableBackgroundContainer.removeView(img);
currentSuccess++;
}
And for the return:
while(true){
if(currentSuccess == images.length){
return temp.toArray(new Bitmap[temp.size()]);
}
}
Hope that helps.
I can't wrap my head around this, probably because of lack of my experience. I have images on server, I get their path in JSON along with description and a name. I am getting all of that data with Volley.
private static final String TAG = "StoreActivity";
private RecyclerView shopsRecyclerView;
private RecyclerView.LayoutManager layoutManager;
private ArrayList<Store> stores;
private StoreAdapter storeAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store);
shopsRecyclerView = (RecyclerView) findViewById(R.id.shopsRecyclerView);
shopsRecyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
shopsRecyclerView.setLayoutManager(layoutManager);
stores = new ArrayList<>();
storeAdapter = new StoreAdapter(getApplicationContext(), stores);
shopsRecyclerView.addOnItemTouchListener(new StoreAdapter.RecyclerTouchListener(getApplicationContext(), shopsRecyclerView, new StoreAdapter.ClickListener() {
#Override
public void onClick(View view, int position) {
Intent i = new Intent(StoreActivity.this, ProductsActivity.class);
startActivity(i);
}
#Override
public void onLongClick(View view, int position) {
}
}));
fetchStores();
}
private void fetchStores() {
JsonObjectRequest fetchAllStores = new JsonObjectRequest(Request.Method.POST, API.GET_STORES, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "Fetch Stores: " + response);
showStores(response);
shopsRecyclerView.setAdapter(storeAdapter);
storeAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Fetch Stores Error: " + error.getMessage());
}
});
ApplicationController.getInstance().addToRequestQueue(fetchAllStores);
}
private void showStores(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("images");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Store store = new Store();
store.setId(jsonObject.getString("id"));
store.setImage_url(jsonObject.getString("url"));
store.setTitle(jsonObject.getString("name"));
stores.add(store);
}
} catch (JSONException e) {
Log.d(TAG, "Show Stores: " + e.getMessage());
}
}
Then I put that path/url I got from Volley in Glide and load all of the images in RecyclerView.
#Override
public void onBindViewHolder(StoreViewHolder holder, final int position) {
Store store = stores.get(position);
holder.tvDescription.setText(store.getTitle());
Glide.with(context)
.load(store.getImage_url())
.placeholder(android.R.drawable.ic_menu_upload_you_tube)
.error(android.R.drawable.stat_notify_error)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(holder.ivImage);
}
Next time I turn on the same activity, the request is sent again and images are downloaded again? Or are they previously cached somehow and they are loaded from cache?
When I turn off internet and turn on the same activity, nothing happens, because the volley request can't be sent, and the images I thought were cached aren't shown.
What would be the best approach for my problem? Basically, I need to get the images's path from server and place them in my recyclerview but I also want them to be cached so they are not downloaded every time.
I would like to suggest you to use Glide lib, very simple and caches images for your app, I have tried it myself. You can also add signature to the url so that next time it is updated it has to change.
Glide Url
Below is code Snippet :
dependencies {
// glide
compile 'com.github.bumptech.glide:glide:3.7.0'
}
String imgUrl = "http://imageurl";
ImageView imageView = (ImageView) view.findViewById(R.id.thumbnail);
Glide.with(mContext).load(imgUrl)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
Hope this Helps.
I am fetching json from the web using volley. One of the json objects ("content"), has <img> tags embedded in the string returned.
With the code below, I have successfully parsed and displayed the objects but the images in "content" are not displaying.
So I wanted the images to display in the positions that they are found in the "content" object.
FruitDetails
public class FruitDetails extends AppCompatActivity {
private final String TAG = "FruitDetails";
TextView fruitTitle, fruitContent;
NetworkImageView authorImg;
ImageLoader AuthImgLoader;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fruit_details);
fruitTitle = (TextView) findViewById(R.id.dfruit_title);
fruitContent = (TextView) findViewById(R.id.dfruit_content);
authorImg = (NetworkImageView) findViewById(R.id.author_img);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
if (savedInstanceState != null) {
fruitTitle.setText(savedInstanceState.getString("fruitTitle"));
fruitContent.setText(savedInstanceState.getString("fruitContent"));
} else {
loadFruit();
}
}
private void loadFruit() {
Log.d(TAG, "loadFruit called");
final ProgressBar progressBar;
progressBar = (ProgressBar) findViewById(R.id.progress_circle);
progressBar.setVisibility(View.VISIBLE);
int news_id = getIntent().getIntExtra("FruitId", -1);
Log.d(TAG, "You clicked fruit id " + news_id);
final JsonObjectRequest jsonObjReq = new JsonObjectRequest( DetailConfig.GET_DURL + news_id, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("Debug", response.toString());
//Dismissing progressbar;
if (progressBar != null) {
progressBar.setVisibility(View.GONE);
}
//Calling method to parse json array
parseFruit(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("", "Error: " + error.getMessage());
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to queue
requestQueue.add(jsonObjReq);
}
//This method will parse json data of fruit
private void parseFruit(JSONObject jsonObject) {
Log.d(TAG, "Parsing fruit array");
try {
String title = jsonObject.getString(DetailConfig.TAG_DFRUIT_TITLE);
fruitTitle.setText(Html.fromHtml(title));
JSONObject pAuthor = jsonObject.getJSONObject("author");
String authorimg = pAuthor.getString("avatar");
AuthImgLoader = VolleyRequest.getInstance(getApplicationContext()).getImageLoader();
AuthImgLoader.get(authorimg, ImageLoader.getImageListener(authorImg, R.drawable.ic_author, R.drawable.ic_author));
authorImg.setImageUrl(authorimg, AuthImgLoader);
String content = jsonObject.getString(DetailConfig.TAG_DFRUIT_CONTENT);
fruitContent.setText(Html.fromHtml(content));
} catch (JSONException w) {
w.printStackTrace();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("fruitTitle", fruitTitle.getText().toString());
outState.putString("fruitContent", fruitContent.getText().toString());
}
}
I have seen the accepted answer to similar question but I am having problems trying to implement it it keeps telling me "cannot resolve symbol urlDrawable.
UILImageGetter
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.view.View;
import android.widget.TextView;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
public class UILImageGetter implements Html.ImageGetter{
Context c;
TextView conatiner;
UrlImageDownloader urlDrawable;
public UILImageGetter(View textView, Context context) {
this.c = context;
this.conatiner = (TextView) textView;
}
#Override
public Drawable getDrawable(String source) {
urlDrawable = new UrlImageDownloader(c.getResources(), source);
urlDrawable.mDrawable = c.getResources().getDrawable(R.drawable.default_thumb);
ImageLoader.getInstance().loadImage(source, new SimpleListener(urlDrawable));
return urlDrawable;
}
private class SimpleListener extends SimpleImageLoadingListener {
UrlImageDownloader mUrlImageDownloader;
public SimpleListener(UrlImageDownloader downloader) {
super();
mUrlImageDownloader= downloader;
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
int width = loadedImage.getWidth();
int height = loadedImage.getHeight();
int newWidth = width;
int newHeight = height;
if (width > conatiner.getWidth()) {
newWidth = conatiner.getWidth();
newHeight = (newWidth * height) / width;
}
if (view != null) {
view.getLayoutParams().width = newWidth;
view.getLayoutParams().height = newHeight;
}
Drawable result = new BitmapDrawable(c.getResources(), loadedImage);
result.setBounds(0, 0, newWidth, newHeight);
mUrlImageDownloader.setBounds(0, 0, newWidth, newHeight);
mUrlImageDownloader.mDrawable = result;
conatiner.setHeight((conatiner.getHeight() + result.getIntrinsicHeight()));
conatiner.invalidate();
}
}
private class UrlImageDownloader extends BitmapDrawable {
public Drawable mDrawable;
public UrlImageDownloader(Resources resources, String filepath) {
super(resources, filepath);
mDrawable = new BitmapDrawable(resources, filepath);
}
#Override
public void draw(Canvas canvas) {
if (mDrawable != null) {
mDrawable.draw(canvas);
}
}
}
}
The easiest one is if the Json object is just a string with the following syntax (without the spaces in the img tags):
<img src= "https://www.myWebstie/images/myimgx92dp.png" />
and!!! you know it won't change then you can just substring it:
String response = "this is your image link";
int x = response.length();
x -= 3;
String subString = new String(response.substring(10, x));
so for example 10 for img tag + the src= at the beggining of the string and 3 for the closing tag at the end of the string.
As for your example you should notice that sometimes there is additional info in the img tag like width and height so make sure you substring the link without it and also learn from it how big the picture should be in your app (dont forget that there's px vs dp difference).
I checked the content you posted here.
If this is realy the website you are trying to parse I would suggest to find a 3rd party library to parse html objects.
Seems like jsoup might do the trick but I have never used it or Html.ImageGetter before although jsoup might seem as the better option for the content you added.
you will just need to try both and check what's the better solution for you.
Check this as well.
Please be aware that if you are going to download and show multiple images and maybe even videos you should use volley for the download as well (after you retrieved all the images links).
If it's just one picture as mentioned before and that content was just for example I would still recommend to just substring it.
I simply used UILImageGetter above, then came to FruitDetails and wrote
protected com.nostra13.universalimageloader.core.ImageLoader mImageLoader;
before onCreate.
In onCreate, I wrote
mImageLoader = com.nostra13.universalimageloader.core.ImageLoader.getInstance();
mImageLoader.init(ImageLoaderConfiguration.createDefault(this));.
Then I also changed
fruitContent.setText(Html.fromHtml(content));
in FruitDetails to
Spanned spanned = Html.fromHtml(content, new UILImageGetter(fruitContent, this), null);
fruitContent.setText(spanned);
This solved my problem.
I am fetching data from JSON with volley. In the data displayed in bookContent, there are <img> tags in varying positions.
I'm using Universal Image Loader to Load the images in the <img> tags.
This is my Activity.
BookDetails
public class BookDetails extends AppCompatActivity{
private final String TAG = "BookDetails";
private JSONObject bookData;
protected com.nostra13.universalimageloader.core.ImageLoader mImageLoader;
TextView bookTitle, bookAuthorDate, bookContent;
View firstView, secView;
CircularNetworkImageView authorImg;
ImageLoader AuthImgLoader;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_details);
showDialog();
bookTitle = (TextView) findViewById(R.id.dbook_title);
bookAuthorDate = (TextView) findViewById(R.id.author_date);
bookContent = (TextView) findViewById(R.id.dbook_content);
authorImg = (CircularNetworkImageView) findViewById(R.id.author_img);
firstView = findViewById(R.id.dviewtop);
secView = findViewById(R.id.dviewbottom);
DisplayImageOptions defaultoptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultoptions)
.writeDebugLogs()
.build();
mImageLoader = com.nostra13.universalimageloader.core.ImageLoader.getInstance();
mImageLoader.init(config);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
if (savedInstanceState != null) {
try {
String bookDataStr = savedInstanceState.getString("bookData");
bookData = new JSONObject(bookDataStr);
parseBook(bookData);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
if (NetworkCheck.isAvailableAndConnected(this)) {
//Calling method to load books
loadBook();
} else {
internetDialog.show();
}
}
}
private void loadBook() {
Log.d(TAG, "loadBook called");
final ProgressBar progressBar;
progressBar = (ProgressBar) findViewById(R.id.progress_circle);
progressBar.setVisibility(View.VISIBLE);
int news_id = getIntent().getIntExtra("BookId", -1);
Log.d(TAG, "You clicked book id " + book_id);
final JsonObjectRequest jsonObjReq = new JsonObjectRequest( DetailConfig.GET_DURL + book_id, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("Debug", response.toString());
//Dismissing progressbar;
if (progressBar != null) {
progressBar.setVisibility(View.GONE);
}
bookData = response;
//Calling method to parse json array
parseBook(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("", "Error: " + error.getMessage());
if (progressBar != null) {
progressBar.setVisibility(View.GONE);
}
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to queue
requestQueue.add(jsonObjReq);
}
//This method will parse json data of book
private void parseBook(JSONObject jsonObject) {
Log.d(TAG, "Parsing book array");
try {
String title = jsonObject.getString(DetailConfig.TAG_DPOST_TITLE);
bookTitle.setText(Html.fromHtml(title));
JSONObject pAuthor = jsonObject.getJSONObject("author");
String author = pAuthor.getString("name");
String authorimg = pAuthor.getString("avatar");
AuthImgLoader = VolleyRequest.getInstance(getApplicationContext()).getImageLoader();
AuthImgLoader.get(authorimg, ImageLoader.getImageListener(authorImg, R.drawable.ic_author, R.drawable.ic_author));
authorImg.setImageUrl(authorimg, AuthImgLoader);
String content = jsonObject.getString(DetailConfig.TAG_DPOST_CONTENT);
Spanned spanned = Html.fromHtml(content, new UILImageGetter(bookContent, this), null);
bookContent.setText(spanned);
} catch (JSONException w) {
w.printStackTrace();
}
//Unhiding views
bookTitle.setVisibility(View.VISIBLE);
bookAuthorDate.setVisibility(View.VISIBLE);
bookContent.setVisibility(View.VISIBLE);
authorImg.setVisibility(View.VISIBLE);
firstView.setVisibility(View.VISIBLE);
secView.setVisibility(View.VISIBLE);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("bookData", bookData.toString());
}
}
Below, I use this piece of code I got from the accepted answer in this question to load the images in bookContent.
This class uses Universal Image Loader.
UILImageGetter
public class UILImageGetter implements Html.ImageGetter{
Context c;
TextView conatiner;
UrlImageDownloader urlDrawable;
public UILImageGetter(View textView, Context context) {
this.c = context;
this.conatiner = (TextView) textView;
}
#Override
public Drawable getDrawable(String source) {
urlDrawable = new UrlImageDownloader(c.getResources(), source);
if (Build.VERSION.SDK_INT >= 21) {
urlDrawable.mDrawable = c.getResources().getDrawable(R.drawable.default_thumb,null);
} else {
urlDrawable.mDrawable = c.getResources().getDrawable(R.drawable.default_thumb);
}
ImageLoader.getInstance().loadImage(source, new SimpleListener(urlDrawable));
return urlDrawable;
}
private class SimpleListener extends SimpleImageLoadingListener {
UrlImageDownloader mUrlImageDownloader;
public SimpleListener(UrlImageDownloader downloader) {
super();
mUrlImageDownloader= downloader;
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
int width = loadedImage.getWidth();
int height = loadedImage.getHeight();
int newWidth = width;
int newHeight = height;
if (width > conatiner.getWidth()) {
newWidth = conatiner.getWidth();
newHeight = (newWidth * height) / width;
}
if (view != null) {
view.getLayoutParams().width = newWidth;
view.getLayoutParams().height = newHeight;
}
Drawable result = new BitmapDrawable(c.getResources(), loadedImage);
result.setBounds(0, 0, newWidth, newHeight);
mUrlImageDownloader.setBounds(0, 0, newWidth, newHeight);
mUrlImageDownloader.mDrawable = result;
conatiner.setHeight((conatiner.getHeight() + result.getIntrinsicHeight()));
conatiner.invalidate();
}
}
private class UrlImageDownloader extends BitmapDrawable {
public Drawable mDrawable;
public UrlImageDownloader(Resources resources, String filepath) {
super(resources, filepath);
mDrawable = new BitmapDrawable(resources, filepath);
}
#Override
public void draw(Canvas canvas) {
if (mDrawable != null) {
mDrawable.draw(canvas);
}
}
}
}
Everything works fine, the JSON is properly parsed and displayed, the images are loaded but there is a problem.
The loaded images are affecting the vertical lines that are displayed in bookContent. If there are many vertical lines, some part of it is cut off.
And if the bookContent has very few vertical lines, a large empty space is left at the bottom of the TextView.
However, if I don't load the images, the bookContent appears fine, no cut-offs, no extra space.
Please, how do I fix it?
I go the answer to this problem from dcow's comment in this question. What I did is that I removed
conatiner.setHeight((conatiner.getHeight() + result.getIntrinsicHeight()));
and wrote
container.setText(container.getText()); under
container.setText(container.getText());.