I have a problem with Android Glide. I am trying to quickly swap my image, they just become all placeholder size, and my placeholder image is very low size. So what I need to do?
Maybe I need to check if it's loaded or something, but I don't know how.
Glide.with(this)
.load(quest.get(id).getImage())
.placeholder(R.drawable.load)
.fitCenter()
.crossFade()
.into(imageView);
According to this issue on Glide GitHub page you can fix it with adding following line to your request of Glide:
.dontAnimate()
That would make your full load line:
Glide.with(context)
.load("http://lorempixel.com/150/150")
.placeholder(R.drawable.no_image)
.override(100, 100)
.dontAnimate()
.into(imageView);
I do it like mentioned below:
The idea is to set the scale type to as required by the place holder initially & attach listener to change the scale type again to as required by the downloaded image after the image is downloaded.
//ivBuilderLogo = Target ImageView
//Set the scale type to as required by your place holder
//ScaleType.CENTER_INSIDE will maintain aspect ration and fit the placeholder inside the image view
holder.ivBuilderLogo.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
//AnimationDrawable is required when you are using transition drawables
//You can directly send resource id to glide if your placeholder is static
//However if you are using GIFs, it is better to create a transition drawable in xml
//& use it as shown in this example
AnimationDrawable animationDrawable;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
animationDrawable=(AnimationDrawable)context.getDrawable(R.drawable.anim_image_placeholder);
else
animationDrawable=(AnimationDrawable)context.getResources().getDrawable(R.drawable.anim_image_placeholder);
animationDrawable.start();
Glide.with(context).load(logo_url)
.placeholder(animationDrawable)
.listener(new RequestListener<String, GlideDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource)
{
return false;
}
//This is invoked when your image is downloaded and is ready
//to be loaded to the image view
#Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource)
{
//This is used to remove the placeholder image from your ImageView
//and load the downloaded image with desired scale-type(FIT_XY in this case)
//Changing the scale type from 'CENTER_INSIDE' to 'FIT_XY'
//will stretch the placeholder for a (very) short duration,
//till the downloaded image is loaded
//setImageResource(0) removes the placeholder from the image-view
//before setting the scale type to FIT_XY and ensures that the UX
//is not spoiled, even for a (very) short duration
holder.ivBuilderLogo.setImageResource(0);
holder.ivBuilderLogo.setScaleType(ImageView.ScaleType.FIT_XY);
return false;
}
})
.into( holder.ivBuilderLogo);
My transition drawable (R.drawable.anim_image_placeholder) :
(not required if using a static image)
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/loading_frame1" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame2" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame3" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame4" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame5" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame6" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame7" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame8" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame9" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame10" android:duration="100" />-->
</animation-list>
What I did in this regard was to use override() to enforce image size. If you have a gridview and you need to have two images in each row, this is how you find the screen size in pixels to calculate the correct width and height of the image:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
placeholderWidth = size.x / 2 ;
placeholderHeight = size.x * 3 / 2 ; // based on the image's height to width ratio
Once the desired width and height for each image is in hand, it's easy to use override:
Glide.with(context)
.load(url)
.placeholder(R.drawable.loading)
.override(placeholderWidth,placeholderHeight)
.into(viewHolder.imageViewHolder);
If I correctly understand your problem, you need to load images, but they must have width and height bigger than your placeholder image.
To solve your problem you first should read documentation for Glide.
I can't see your ImageView definition in the xml file, but i think that you use wrap_content attribute for width and height.
If I am right there is your bottleneck.
Before image loading is started, Glide gets exact ImageView width and height. After that it loads image from the network and at the same time resize it according to the one of the ImageView attributes(width or height).
Thats why you get small images after loading.
To solve your problem just set width or height of the ImageView in value that you expect to see. Other side of the image will be automatically calculated by the Glide logic.
If someone came here from search just like me and wondering how to change Glide's placeholder size but remain image size original (in my case placeholder was to big), here's the solution. Wrap your placeholder drawable in another drawable with tag inset:
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="20%">
<animated-rotate
android:drawable="#drawable/ic_loading"
android:pivotX="50%"
android:pivotY="50%" />
</inset>
Note that you can replace animated-rotate with any of allowed tags. Also, you can set different insets for each side of drawable (insetTop, insetBottom and so on), and specify insets in dp or %
Related
I have a ImageView with the following layout
<ImageView
android:id="#+id/view_row_circular_icon_with_text_icon"
style="#style/ImageView"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_gravity="right|center_vertical"
android:padding="5dp"
android:src="#drawable/ic_broadband_router_white"/>
The android:src property is useful for previewing this component.
And I set the image I want do display with the following
ImageView mIcon = (ImageView) findViewById(R.id.view_row_circular_icon_with_text_icon_bg);
mIcon.setImageDrawable(rowEntry.getIcon());
rowEntry.getIcon() returns a Drawable.
The end result is both the image from android:src property and the image set from mIcon.setImageDrawable() in the ImageView.
How can I programmatically override the image so that only the latter is shown?
As i can see that your setting image of a another view which
R.id.view_row_circular_icon_with_text_icon_bg
Check the proper id and set the image
Soft input mode is "SOFT_INPUT_ADJUST_PAN", and when keyboard shown, EditText moves up to stay visible, but the keyboard and txt's bottom are always sticked together as seen on screenshot, I want some space between them, is it possible?
Also input mode must stay as "SOFT_INPUT_ADJUST_PAN".
Sorry form my english, Thanks in Advance...
I applied above methods which worked for me was
Set android:windowSoftInputMode on the Activity to "adjustPan"
than i added the padding to the edittext with gravity bottom
and it works like charm.
Thanks,
May this help you:
If this line is written in your code then remove it:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
OR:
You should not be setting your layout_width and layout_heights with explicit pixel values. Instead, use wrap_parent or fill_parent as appropriate.
OR:
If you have set your minSdkVersion to 3 then change it to minSdkVersion=4
Edit:
Set android:windowSoftInputMode on the Activity to "adjustPan"
OR:
Add this code in your main activity in setOnTouchListener() of your EditText:
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED);
Why don't you try this?
android:windowSoftInputMode="adjustResize"
I know you want to adjust pan but this would solve your problem aswell.
Since you really want to stay with adjustPan, maybe you can try re-designing the XML layout a little bit.
You must also add your required padding to the outer most container element in the layout file.
Simple padding in edit text won't work.
Use drawable with your edit text like below:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp">
<shape android:shape="rectangle">
<corners android:radius="10dp" />
<stroke
android:width="1dp"
android:color="#color/white" />
<solid android:color="#color/transparent" />
</shape>
</item>
</layer-list>
and then use
android:windowSoftInputMode="adjustPan"
in your manifest file.
Just wondering, is your app full screen? does it have the status bar? If it is try to disable full screen mode and try to see if that solves your problem. I remember there was a bug about this some time ago.
try to use GlobalLayoutListener:
private var focusView:View?=null
// Register global layout listener.
decorView?.viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
private val windowVisibleDisplayFrame = Rect()
private var lastVisibleDecorViewHeight: Int = 0
override fun onGlobalLayout() {
// Retrieve visible rectangle inside window.
decorView.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame)
val visibleDecorViewHeight = windowVisibleDisplayFrame.height()
// Decide whether keyboard is visible from changing decor view height.
if (lastVisibleDecorViewHeight != 0) {
if (lastVisibleDecorViewHeight > visibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX) {
// Calculate current keyboard height (this includes also navigation bar height when in fullscreen mode).
val currentKeyboardHeight = decorView.height - windowVisibleDisplayFrame.bottom
//keyboardHeight = currentKeyboardHeight
focusView = activity?.currentFocus
focusView.setPadding(0, 0, 0, SET_BOTTOM_PADDING_SPACE) // <---set space here
} else if (lastVisibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX < visibleDecorViewHeight) {
focusView.setPadding(0, 0, 0, 0)
}
}
// Save current decor view height for the next call.
lastVisibleDecorViewHeight = visibleDecorViewHeight
}
})
I create a TableLayout dynamically via code and want to set a margin between columns. The only type of content my TableRows contain are TextViews.
My intention was to put a simple android:layout_marginRight on each TextView. But I want to definde this via xml instead of code.
What I tried:
The code:
txtView.setTextAppearance(context, R.style.TableTextView);
txtView.setText(content);
tableRow.addView(txtView);
The XML
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TableTextView">
<item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_marginRight">5dip</item>
</style>
</resources>
What happens:
The layout_marginRight set in the XML does not work, but the textAppearance and textStyle set in the XML do work. I assume the setTextAppearance-method is the wrong way for assigning a margin to a TextView? It would be really nice if I could do this via XML (like I tried it above) instead of Java-code.
Thank you!
This happens because you're setting the style to the text itself and not the TextView element.
You should set the element style in the XML. it's possible to achive this from the code as well, but i think it's best to do that in the XML Layout file.
Something like :
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/mTableTextView" />
About setting that from code, i'm not an expert but i understood you can inflate it somehow.
Check out This, And This questions.
You want to give margin between columns
android.widget.TableRow.LayoutParams param = new android.widget.TableRow.LayoutParams();
param.rightMargin = Converter.dpToPixel(10, getContext()); // right-margin = 10dp
button.setLayoutParams(param);
// Converter:
private static Float scale;
public static int dpToPixel(int dp, Context context) {
if (scale == null)
scale = context.getResources().getDisplayMetrics().density;
return (int) ((float) dp * scale);
}
you can set different of value table parameters.
It is advantageous in my application if I preload certain images. I do this correctly, in AsyncTask, as it is written in the official documentation. But I have a problem/question about when they should be set.
I'll show code snippets. Note that it's simplified (their interoperability is better in my real code, it checks for nulls, etc.).
Let's see the original (non-preloaded) version first:
<ImageView
android:id="#+id/imageViewMyGraphicalImageElement"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="#drawable/my_graphical_element" >
</ImageView>
The preloaded version has the following XML (notice that the src attribute is missing):
<ImageView
android:id="#+id/imageViewMyGraphicalImageElement"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop">
</ImageView>
And a snippet from the preload code:
sBitmap = bitmapBitmapFactory.decodeResource(context.getResources(), R.drawable.my_graphical_element, options);
// 'sBitmap' is a Bitmap reference, while 'options' is BitmapFactory.Options
Finally, the place where I set it:
setContentView(R.layout.main);
...
ImageView imageViewMyGraphicalImageElement= (ImageView) findViewById(R.id.imageViewMyGraphicalImageElement);
imageViewMyGraphicalImageElement.setImageBitmap(sBitmap);
Question:
Obviously, the xml-based solution knows about the image before setContentView(...) is called. The preload version sets the image after that call. Is there any difference? Can some autoscaling or other things done by the system be skipped due to this?
I just wrote up an article for this. Wish to be able to answer your question.
https://plus.google.com/112740367348600290235/posts/VNAfFLDcKrw
ImageView has 4 APIs to specify the image. Which one to use? What is the difference?
setImageDrawable(Drawable drawable)
setImageBitmap(Bitmap bm)
setImageResource(int resId)
setImageURI(URI uri)
ImageView, by the name, is used to display an image. But what is a image? A Bitmap is-a image, not hard to understand and we use setImageBitmap for that purpose. However, internally, the ImageView has-a Drawable but not a Bitmap and that is what setImageDrawable for. When you call setImageBitmap, internally, first the bitmap will be wrapped to BitmapDrawable, which IS-A Drawable, and then call setImageDrawable.
Here is the code.
public void setImageBitmap(Bitmap bm) {
setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}
So, what about the 3 and 4 API?
You should already know that that are bunches of ways to create a bitmap, from a file path, from the Uri, or from the resource file.
BitmapFactory.decodeFile(String pathName)
BitmapFactory.decodeStream(Inputstream)
BitmapFactory.decodeResource(Resource res, int id)
BitmapFactory.decodeByteArray(byte[] data)
Aware of this, it is easy to understand setImageResource/setImageUri is just same as setImageBitmap.
To sum up, setImageDrawable is the primitive function other APIs rely on. The other 3 are just helper methods making you write less code.
In addition, it is very important to keep in mind that ImageView actually has-a Drawable, which not necessarily to be a BitmapDrawable! You could set any Drawable to the Image view.
Besides setting the Drawable through Java API, you could also using XML attribution to set the source Drawable for ImageView. See example below. Note that the shape could be either an image file (.png, .jpg, .bmp) or xml file.
<ImageView
android:layout_width="match_parent"
android:layout_height="50dip"
android:src="#drawable/shape"/>
shape.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="270"/>
<padding android:left="7dp" android:top="7dp android:right="7dp" android:bottom="7dp" />
<corners android:radius="8dp" />
</shape>
There is no difference at all. You can consider that all the ImageView constructor does with the android:src attribute is call setImageResource.
Update: Actually it uses setImageDrawable, this is the actual code for ImageView constructor taking attributes:
Drawable d = a.getDrawable(com.android.internal.R.styleable.ImageView_src);
if (d != null) {
setImageDrawable(d);
}
Reference: ImageView.java
I am using a custom Group indicator as shown in the code below. Now if I leave the default I can use setBounds perfectly, but when using my custom image which is the same dimensions and setup as the same .9 patch file it is always half off screen. No matter what values I use for setBounds()
Drawable plus = (Drawable) getResources().getDrawable(R.drawable.expander_group);
getExpandableListView().setGroupIndicator(plus);
Display newDisplay = getWindowManager().getDefaultDisplay();
int width = newDisplay.getWidth();
getExpandableListView().setIndicatorBounds(0,0);
XML expander_group
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_expanded="true"
android:drawable="#drawable/minus" />
<item
android:drawable="#drawable/plus" />
</selector>
EDIT:
Interestingly. I have copied the exact xml and image files from the standard Android files. And when I use the above method to define it the exact same thing happens! So it is not the xml or image files that are causing the issue I think.