Long time reader, first time poster. I'm very new to Android development and am having trouble getting images to show when using AsyncTask to insert ImageViews (containing Bitmaps) into a LinearLayout. This is all triggered in the onCreate() method of an Activity I have.
The ImageViews (+Bitmaps) are definitely getting added via AsyncTask to my LinearLayout parent. However, the images don't show properly when I start my Activity. Sometimes an image or two (out of 3+) will display and sometimes none will show. All the images display properly after I fiddle with the UI, such as by bringing up and hiding the keyboard. I suspect that the LinearLayout and/or ImageViews may not be resizing to contain and show all the new children, but I tried many combinations of invalidate() and requestLayout() at the places I marked as "LOCATION1" and "LOCATION2" in attempt to trigger redraws.
Would anyone help on ensuring all images are displayed properly after onCreate() and after each AsyncTask is complete? Thanks a bunch. I'll try to be succinct with my code snippets...
This is my layout XML. I am adding my ImageViews to the LinearLayout with id "horizontal":
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
... />
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
This is some of my onCreate() code. Where I create an AsyncTask for every image I want displayed.
protected void onCreate(Bundle savedInstanceState) {
...
LinearLayout horizontal = (LinearLayout) findViewById(R.id.horizontal);
...
//an array of absolute file paths to JPGs in storage
ArrayList<String> images = report.getImageMain();
PhotoBitmapTask task = null; //extension of AsyncTask
for (int i = 0; i < images.size(); i++) {
task = new PhotoBitmapTask(getApplicationContext(), horizontal, images);
task.execute(i);
//LOCATION1
}
...
}
This is my extension of AsyncTask.
//a bunch of imports
public class PhotoBitmapTask extends AsyncTask<Integer, Void, Bitmap> {
private Context context;
private WeakReference<ViewGroup> parent;
private ArrayList<String> images;
private int data;
public PhotoBitmapTask(Context context, ViewGroup parent, ArrayList<String> images) {
super();
this.context = context;
this.parent = new WeakReference<ViewGroup>(parent);
this.images = images;
this.data = 0;
}
#Override
protected Bitmap doInBackground(Integer... params) {
data = params[0];
return getBitmapFromFile(images.get(params[0]), 600, 600);
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (context != null && parent != null && result != null) {
ViewGroup viewGroup = parent.get();
if (viewGroup != null) {
ImageView imageView = PhotoBitmapTask.getImageView(context);
imageView.setImageBitmap(result);
viewGroup.addView(imageView);
//LOCATION2
}
}
}
public static Bitmap getBitmapFromFile(String filePath, int maxHeight,
int maxWidth) {
// check dimensions for sample size
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
// calculate sample size
options.inSampleSize = getSampleSize(options, maxHeight, maxWidth);
// decode Bitmap with sample size
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
public static int getSampleSize(BitmapFactory.Options options,
int maxHeight, int maxWidth) {
final int height = options.outHeight;
final int width = options.outWidth;
int sampleSize = 1;
if (height > maxHeight || width > maxWidth) {
// calculate ratios of given height/width to max height/width
final int heightRatio = Math.round((float) height / (float) maxHeight);
final int widthRatio = Math.round((float) width / (float) maxWidth);
// select smallest ratio as the sample size
if (heightRatio > widthRatio)
return heightRatio;
else
return widthRatio;
} else
return sampleSize;
}
public int getData() {
return this.data;
}
public static ImageView getImageView(Context context) {
// width and height
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
// margins
params.setMargins(20, 20, 20, 20);
final ImageView view = new ImageView(context);
view.setLayoutParams(params);
// scale type
view.setScaleType(ScaleType.CENTER);
return view;
}
}
After much headache and heartache, I found the answer. I did not mention it previously or search for it specifically because I didn't think it was relevant, but I'm using Nuance's 360 SpeechAnywhere developer SDK to include speech recognition in my app. Hopefully I'm not breaking the terms of my SDK license by saying this:
Every "recognition enabled" activity is supposed to have a custom View as the root in order to embed speech recognition controls and functionality. It turns out that this custom View does not always refresh its children, unless you instruct it to via the custom View's synchronize() function. Long story short, I called the View's synchronize() method once my AsyncTask finished, onPostExecute() ran, and Bitmap was added to the activity.
In the AsynTask you work on UI changes.you can't do changes in the UI in background work.Use runOnUIThread always do computation on UI thread.It better depend on your easy of use.look at here.
Related
I have a listivew that display a bunch of images. am using Universal Image Loader to load this images from files to imageviews.
This images have different dimensions and i want all of them to have same width but different height in respect to each image aspect ratio.
To achieve this, i have tried setting the following to my imageview
<ImageView
android:layout_width = "400dp"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:adjustViewBounds="true"/>
The issue with this method is that there is a lot of flickering when one scrolls the listview since imageview height is not known in advance and images have to be scaled first using my width to calculate each image height in respect to it's aspect ratio.
How can i calculate each image height in advance instead of letting imageview handle it?
if i have an image which is 400 X 700, and i want the imageview to be 300px wide, how can i calculate imageview's height using my image dimension and maintain image aspect ratio? this can help avoid flickering wnen one scroll the listview.
The reason for this flicker is that, in listview list items are reused. When re-used, the imageviews in the list item retains the old image reference which is displayed first. Later on once new image is downloaded, it starts to show. this causes the flickering behavior.
To avoid this flickering issue, always clear the old image reference from the imageview when it is getting reused.
In your case, add holder.image.setImageBitmap(null); after holder = (ViewHolder) convertView.getTag();
So, your getView() method will look like:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
...
if (convertView == null) {
LayoutInflater inflater = getLayoutInflater();
convertView = inflater.inflate(viewResourceId, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
holder.image.setImageBitmap(null)
}
...
return convertView;
}
After hours of research, i was able to know the method that i can use to calculate new imageview height while maintaining image aspect ratio.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//Returns null, sizes are in the options variable
BitmapFactory.decodeFile("/sdcard/image.png", options);
int width = options.outWidth;
int height = options.outHeight;
//calculating image aspect ratio
float ratio =(float) height/(float) width;
//calculating my image height since i want it to be 360px wide
int newHeight = Math.round(ratio*360);
//setting the new dimentions
imageview.getLayoutParams().width = 360;
imageview.getLayoutParams().height = newHeight;
//i'm using universal image loader to display image
imaheview.post(new Runnable(){
ImageLoader.getInstance().displayImage(imageuri,imageview,displayoptions);
});
You can do something like this :
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//Returns null, sizes are in the options variable
BitmapFactory.decodeFile("/sdcard/image.png", options);
int width = options.outWidth;
int height = options.outHeight;
//If you want, the MIME type will also be decoded (if possible)
String type = options.outMimeType;
How I solved it was by creating a Bitmap[] array variable to store images, then in adapter's getView(), I used position to check if image in Bitmap[] array is null or has value. If it is has value, then I use the value instead of calling the new DownloadImageTask() construct again.
For example:
YourCustomArrayAdapter.java
public class MyCustomArrayAdapter extends ArrayAdapter {
private static Bitmap[] myListViewImageViewsArray = new Bitmap[listViewItemsArray.length];
private String[] myListViewImageURLsArray = new String[listViewItemsArray.length]{
"image_url_1",
"image_url_2",
...
...
};
#Override
public View getView(int position, View view, ViewGroup parent){
CustomViewHolder vHolder;
if(view == null){
view = inflater.inflate(R.layout.movies_coming_soon_content_template, null, true);
vHolder = new CustomViewHolder();
vHolder.imageView = (AppCompatImageView) view.findViewById(R.id.my_cutom_image);
vHolder.imageUrl = "";
view.setTag(vHolder);
}
else{
vHolder = (CustomViewHolder)view.getTag();
// -- Set imageview src to null or some predefined placeholder (this is not really necessary but it might help just to flush any conflicting data hanging around)
vHolder.imageView.setImageResource(null);
}
// ...
// -- THIS IS THE MAIN PART THAT STOPPED THE FLICKERING FOR ME
if(myListViewImageViewsArray[position] != null){
vHolder.imageView.setImageBitmap(myListViewImageViewsArray[position]);
}else{
new DownloadImageTask(position, vHolder.imageView).execute(vHolder.imageUrl);
}
// -- END OF THE FLICKERING CONTROL
}
}
Then, in your image downloader construct, after downloading the image, make an insertion into the Bitmap[] image array for that position. For example:
YourImageDownloaderClass.java
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
AppCompatImageView imageView;
int position;
public DownloadImageTask(int position, AppCompatImageView imageView){
this.imageView = imageView;
this.position = position;
}
#Override
protected Bitmap doInBackground(String...urls) {
String urlOfImage = urls[0];
Bitmap logo = null;
try{
logo = BitmapFactory.decodeStream((InputStream) new URL(urlOfImage).getContent());
}catch(Exception e){
e.printStackTrace();
}
return logo;
}
#Override
protected void onPostExecute(Bitmap result){
if(result != null) {
YourCustomArrayAdapter.myListViewImageViewsArray [position] = result;
imageView.setImageBitmap(result);
}else{
YourCustomArrayAdapter.myListViewImageViewsArray [position] = null;
imageView.setImageResource(null);
}
}
}
my suggestion is to use grid view to avoid flickering of images it will load at first time if it is same url , it will load from cache
Glide.with(mContext)
.load(item.getImageUrl())
.into(holder.mIVGridPic);
I'm trying to get a picture from my camera device, to save it, and show a preview in a ImageView.
My ImageView (named imagePreview) is defined inside the following layout:
<LinearLayout
android:id="#+id/ll_selected_image"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:visibility="gone"> <!-- at first this is GONE -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imagePreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"/>
</RelativeLayout>
</LinearLayout>
When the image is acquired from the camera, I try to scale my image following this document, which code is:
private void setPic() {
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
mImageView.setImageBitmap(bitmap);
}
The problem is that I obtain a "division by zero" mImageView.getWidth(); and mImageView.getHeight(); return zero.
Note that the visibility of the parent LinearLayout is setted to GONE. Then, my application sets programmatically it to VISIBLE.
If I remove GONE, and I add VISIBLE instead, all works good!
The strange thing is that I have tried to add in the setPic(), as first code lines, the following code:
if(ivSelectedImage.getVisibility() == View.VISIBLE)
Log.i(TAG,"IS VISIBLE!");
else if(ivSelectedImage.getVisibility() == View.GONE)
Log.i(TAG,"IS GONE!");
else if(ivSelectedImage.getVisibility() == View.INVISIBLE)
Log.i(TAG,"IS INVISIBLE!");
and this prints in my console "IS VISIBLE"!
BRIEFLY: If I set GONE in the XML, and then I set VISIBLE (programmatically) getHeight() and getWidth() can't get the correct value (also if when I call these methods the View is actually VISIBLE).
While, If I set VISIBLE in the XML, the methods getHeight() and getWidth() return me the correct values.
You don't need to use the view size at runtime for this example. Based on your code, while the view visibility is set to gone the main container, your LinearLayout, as a fixed height of 300dp. As a result, you already know one of the dimensions of your view since at best android:layout_height="match_parent" can only be equal to 300dp.
To scale properly you just need the screen width - since your main view (and nested RelativeLayout and ImageView are also set to match_parent). If you're in an activity use this
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
otherwise you can get the display using
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Just run this calculation before you need the set the image. Store the results to SharedPreferences or something and then use that ratio the 300dp height and screen width to scale the image.
I am using Universal ImageLoader for downloading large images from server and displaying them in coverflow. Issue I am facing here is that I am unable to set custom size for my image. It just takes whole screen. For example, I am downloading image of size 500 x 1200 - and I want to display it of size 300 x 300. But it takes full display. Please help me with this issue as I am stuck for more than 3 days. Thanks.
Code
public class HomeCoverFlow {
Context mContext;
public CoverFlow coverFlow;
ImageAdapter coverImageAdapter;
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options;
/** Called when the activity is first created. */
public HomeCoverFlow(Context context)
{
mContext = context;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.flyer_placeholder)
.showImageForEmptyUri(R.drawable.flyer_placeholder)
.imageScaleType(ImageScaleType.EXACTLY)
.cacheInMemory(true)
.build();
coverFlow = new CoverFlow(context);
coverImageAdapter = new ImageAdapter(mContext);
coverFlow.setAdapter(coverImageAdapter);
coverFlow.setSpacing(-25);
coverFlow.setSelection(2, true);
coverFlow.setAnimationDuration(1000);
coverFlow.setGravity(Gravity.CENTER_VERTICAL);
// HEIGHT
coverImageAdapter.coverflowHeight = 100; //display.getHeight() / 3;
//WIDTH
coverImageAdapter.coverflowWidth = 100;// display.getWidth() / 2;
}
A method in adapter to create item views, Here I use imageloader to download image and display
public View getView(int position, View convertView, ViewGroup parent) {
FeaturedFlyerData data = (FeaturedFlyerData) getItem(position);
if(data.flyerImage == null)
{
setNewImage(position);
}
//see text or image
if(data.displayImage)
{
data.flyerImage.setBackgroundColor(Color.BLACK);
imageLoader.displayImage(data.url, data.flyerImage, options, null);
}
return data.flyerImage;
}
void setNewImage(int position)
{
FeaturedFlyerData data = (FeaturedFlyerData) getItem(position);
data.flyerImage = new ImageView(mContext);
data.flyerImage.layout(0, 10, 200,350);
data.flyerImage.setScaleType(ScaleType.CENTER_INSIDE);
data.flyerImage.setTag(Integer.toString(position));
data.flyerImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
imageClicked(Integer.parseInt(v.getTag().toString()));
}
});
}
}
I don't know what else code snippet to provide here. Please comment if you need any further clarifications. Thanks.
I am using following code to display custom size images in coverflow using universal imageloader.
In constructor, set DisplayImageOptions as:
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.flyer_placeholder)
.showImageForEmptyUri(R.drawable.flyer_placeholder)
.imageScaleType(ImageScaleType.EXACTLY)
.cacheInMemory(true)
.build();
//set coverflow full screen, and images size.
coverFlow.setSpacing(-25);
coverFlow.setAnimationDuration(1000);
coverFlow.setGravity(Gravity.CENTER_VERTICAL);
coverFlow.setLayoutParams(new CoverFlow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// GET SCREEN SIZE
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
//Here I am setting image size using my custom adapter in "dp". Avoid to use pixels as things will mess up for different screen sizes
coverImageAdapter.coverflowWidth = (int) Math.ceil(dm.widthPixels * (dm.densityDpi / 160.0));
coverImageAdapter.coverflowHeight = (int) Math.ceil(dm.heightPixels * (dm.densityDpi / 160.0)) / 2;
In adapter's setNewImage method (called in getView), use Gallery.LayoutParams:
void setNewImage(int position)
{
FeaturedFlyerData data = (FeaturedFlyerData) getItem(position);
data.flyerImage = new ImageView(mContext);
data.flyerImage.setLayoutParams(new Gallery.LayoutParams(coverflowWidth, coverflowHeight));
data.flyerImage.setScaleType(ScaleType.CENTER_INSIDE);
}
I have a layout resource like this and a I want to inflate it with the layout width and height:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="75px"
android:layout_height="25px">
<TextView
android:id="#+id/drawable_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Name" />
<TextView
android:id="#+id/drawable_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/drawable_name"
android:layout_alignParentLeft="true"
android:gravity="center_horizontal"
android:layout_below="#+id/drawable_name"
android:text="Some Text" />
</RelativeLayout>
The View could be anything, and I'm converting it to Bitmap.
private Bitmap getBitmap(View v){
v.measure(MeasureSpec.makeMeasureSpec(mDrawableWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mDrawableHeight, MeasureSpec.EXACTLY));
v.layout(0, 0, mDrawableWidth, mDrawableHeight);
Bitmap returnedBitmap = Bitmap.createBitmap(mDrawableWidth, mDrawableHeight,Bitmap.Config.ARGB_8888);
Canvas c=new Canvas(returnedBitmap);
v.draw(c);
return returnedBitmap;
}
Until now, I have the Width and Height hardcoded and I want to be able to do it programatically, accessing the layout_width and layout_height.
Is there any way to achieve this?
If there's another way of inflating the view with this values without specifying them in the measure, please let me know.
If I create a Custom View, is there any chance of specifying the fixed width and height?
This example should work. Might take some tweaking to get it perfect, depending on your needs, but give it a shot:
//Get a bitmap from a layout resource. Inflates it into a discarded LinearLayout
//so that the LayoutParams are preserved
public static Bitmap getLayoutBitmap (Context c, int layoutRes, int maxWidth, int maxHeight) {
View view = LayoutInflater.from(c).inflate(layoutRes, new LinearLayout(c), false);
return getViewBitmap(view, maxWidth, maxHeight);
}
public static Bitmap getViewBitmap (View v, int maxWidth, int maxHeight) {
ViewGroup.LayoutParams vParams = v.getLayoutParams();
//If the View hasn't been attached to a layout, or had LayoutParams set
//return null, or handle this case however you want
if (vParams == null) {
return null;
}
int wSpec = measureSpecFromDimension(vParams.width, maxWidth);
int hSpec = measureSpecFromDimension(vParams.height, maxHeight);
v.measure(wSpec, hSpec);
final int width = v.getMeasuredWidth();
final int height = v.getMeasuredHeight();
//Cannot make a zero-width or zero-height bitmap
if (width == 0 || height == 0) {
return null;
}
v.layout(0, 0, width, height);
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
v.draw(canvas);
return result;
}
private static int measureSpecFromDimension (int dimension, int maxDimension) {
switch (dimension) {
case ViewGroup.LayoutParams.MATCH_PARENT:
return View.MeasureSpec.makeMeasureSpec(maxDimension, View.MeasureSpec.EXACTLY);
case ViewGroup.LayoutParams.WRAP_CONTENT:
return View.MeasureSpec.makeMeasureSpec(maxDimension, View.MeasureSpec.AT_MOST);
default:
return View.MeasureSpec.makeMeasureSpec(dimension, View.MeasureSpec.EXACTLY);
}
}
One option is to define constants for layout_width and layout_height in the form of attributes and access them programatically in getBitmap.
I have a bitmap and below it is a time line.
As an example consider the right side layout of the FIGURE.
All the bottom timelines (1, 2, 3...) are in the same height from top.
The timeline is a textview which has fixed layout height and width as it is defined in xml
like timeline 1 is defined as:
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/HView"
android:layout_marginLeft="18dp"
android:layout_marginTop="345dp"
android:textSize="14sp"
android:text="1"
android:textColor="#000000" />
However the bitmap height and width can vary as it is done programatically.
So in certain cases, the bitmap height increases enough to overlap the timeline. In other words,
the vertical position of bitmap increases with respect to the vertical position of the timeline.
I want to get:
1) the ended vertical position of bitmap with respect to top of the screen.
2) the ended vertical position of timeline with respect to top of the screen.
I tried to do the following:
TextView bottomTimeLine = (TextView) view.findViewById(R.id.textView1);
bottomTimeLine.getHeight(); //returns 0.
bottomTimeLine.getBottom(); //returns 0.
ImageView img = new ImageView(getActivity());
img.setImageDrawable(getResources().getDrawable(R.drawable.disp_bg));
img.getHeight(); //returns 0.
img.getBottom(); //returns 0.
As seen from the code, both the methods, getHeight() and getBottom() are returning height as 0.
How to get the height (view end position) of both with respect to top of the cell display ?
Hope this helps
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(
parentWidth / 2, parentHeight);
}
This is how it can be done:
final TextView bottomTimeLine = (TextView) view.findViewById(R.id.textView1);
final int[] timelineCoord = new int[2];
final int[] imgCoord = new int[2];
ViewTreeObserver vto = bottomTimeLine.getViewTreeObserver();
vto.addOnGlobalLayoutListener((new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
bottomTimeLine.getLocationOnScreen(timelineCoord);
Log.d(" bottomTimeLine H ", ""+timelineCoord[1]);
timelineHeight = timelineCoord[1];
}
}));
ViewTreeObserver vt1 = img.getViewTreeObserver();
vt1.addOnGlobalLayoutListener((new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
img.getLocationOnScreen(imgCoord);
imgHeight = imgCoord[1] + img.getHeight();
Log.d("Img H ", ""+imgHeight);
if(imgHeight < timelineHeight)
{
int heightDiff = imgHeight - timelineHeight ;
heightDiff = heightDiff + 3;
img.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, heightDiff));
}
}
}));