Shimmer Effect not working on Height wrap_content - java

I'm trying to implement the shimmer effect with the Height of wrap_content but the images are not loading, I know why it is not loading the images because the imageView has wrap_content and the shimmer also has wrap_content but I want the Height Should be wrap_content and not fixed.
After implementing a fixed height of eg 200dp in shimmer it works but after that images are not loading
I want to make it like Pinterest where the height is adjusted according to the image
XML Files
post_item_container_search.xml
<com.google.android.material.imageview.ShapeableImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/imagePostSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginTop="11dp"
android:layout_marginEnd="6dp"
android:contentDescription="#string/todo"
app:shapeAppearanceOverlay="#style/RoundedCorner" />
post_item_containe_shimmer.xml
<com.google.android.material.imageview.ShapeableImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/imageShimmer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:layout_marginTop="11dp"
android:background="#E7E7E7"
android:contentDescription="#string/todo"
app:shapeAppearanceOverlay="#style/RoundedCorner" />
this how it looks like after adding minHeight to both or in actual imageView

By default, the wrapcontent doesn't have any size so it is 0dp you need to define 50dp or something for the height of shimmer then only you can see the shimmering.
Can refer this blog
or try to use this
post_item_container_search.xml
<com.google.android.material.imageview.ShapeableImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/imagePostSearch"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="fitCenter"
android:layout_marginStart="6dp"
android:layout_marginTop="11dp"
android:layout_marginEnd="6dp"
android:contentDescription="#string/todo"
app:shapeAppearanceOverlay="#style/RoundedCorner" />

After implementing a fixed height of eg 200dp in shimmer it works but after that images are not loading
In that case, you should probably set an absolute width/height for the ImageView first. Later, you can set it back to WARP_CONTENT if you really need to. But first you'll need an estimated/absolute width/height for the view.
int height = bitmap.getHeight();
int width = bitmap.getWidth();
ShapeableImageView siv = findViewById(R.id.imagePostSearch);
ViewGroup.LayoutParams params = siv.getLayoutParams();
params.height = height;
params.width = width;
//To set it back to warp content or match parent:
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
params.width = ViewGroup.LayoutParams.MATCH_PARENT;

Please keep android:minHeight for the ImageView as it will give you a minimum height and also android:height can be wrap_content so it grows if the image is larger than minHeight.
For example,
<com.google.android.material.imageview.ShapeableImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/imageShimmer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="100dp"
android:layout_marginStart="11dp"
android:layout_marginTop="11dp"
android:background="#E7E7E7"
android:contentDescription="#string/todo"
app:shapeAppearanceOverlay="#style/RoundedCorner" />

You can create a dummy view for shimmer with fixed height, make its visibility to visible and show it until the image loads, and once the image is loaded make the dummy view visibility gone.
//XML
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<shimmerView //You can use your own
android:id="#+id/dummyShimmerView"
android:layout_width="100dp"
android:layout_height="100dp"/>
<ImageView
android:id="#+id/postImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
</RelativeLayout>
//dummyShimmerView visibility is visible byDefault
Glide.with(context)
.load(url)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
//TODO: something on exception
}
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
Log.d(TAG, "OnResourceReady")
dummyShimmerView.visibility = View.GONE
postImageView.visibility = View.VISIBLE
return false
}
})
.into(imgView)

Related

Get view height when part of the view is off screen?

Let's say I have a view structure like
<ConstraintLayout>
<CustomViewLayout>
...
...
</CustomViewLayout>
</ConstraintLayout>
This is simplified but I use the above in a bottom sheet and I sometimes change the height of the ConstraintLayout and the peek height of the bottom sheet depending on my CustomViewLayout height. My problem is that if part of the CustomViewLayout is cut off, that is - it is somewhat outside the screen because the ConstraintLayout isn't high enough - I'm no longer able to get a correct "full height" of it. I always only seem to get the visible part on screen of the view in that case.
So how can I get the full height of a view that is partly off screen?
Thanks!
Edit:
I should add that what I've tried is a globalLayoutListener, as well as a customViewLayout.post {} (and the usual customViewLayout.height of course). But none of these measure the full height when part of the view is outside the screen.
To check my previous answer, I developed a test project to examine the exact situation. It was successful to measure layout height when some part of it is outside of screen (layout height measured 4231px where the screen height was 1920px). If the view is long enough that is not completely shown by the screen, you should put it in a scrollable view. So I put the customViewLayout in a NestedScrollView to consume residual scroll amount after the bottom sheet has expanded. Here is the code and result:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:showIn="#layout/activity_main"
tools:context=".MainActivity">
<android.support.constraint.ConstraintLayout
android:id="#+id/layoutBottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/customViewLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/colorAccent">
<TextView
android:id="#+id/stateTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:layout_marginTop="16dp"
android:gravity="center_horizontal"/>
<TextView
android:id="#+id/sizeTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:padding="24dp"
android:gravity="center_horizontal"/>
<TextView
android:id="#+id/contentTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:padding="24dp"
android:text="#string/lorem"
android:gravity="center_horizontal"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>
MainActivity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
customViewLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
customViewLayout.viewTreeObserver.removeGlobalOnLayoutListener(this)
val height = customViewLayout.measuredHeight
val width = customViewLayout.measuredWidth
sizeTextView.text = "Height: $height px Width: $width px"
}
})
val sheetBehavior = BottomSheetBehavior.from(layoutBottomSheet)
sheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, offset: Float) {
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
when (newState) {
BottomSheetBehavior.STATE_HIDDEN -> stateTextView.text = "State: Hidden"
BottomSheetBehavior.STATE_EXPANDED -> stateTextView.text = "State: Expanded"
BottomSheetBehavior.STATE_COLLAPSED -> stateTextView.text = "State: Collapsed"
BottomSheetBehavior.STATE_DRAGGING -> stateTextView.text = "State: Dragging"
BottomSheetBehavior.STATE_SETTLING -> stateTextView.text = "State: Settling"
}
}
})
}
}
Screen:
If you are looking for the view width and height, try this:
mCustomViewLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mCustomViewLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int height = mCustomViewLayout.getMeasuredHeight()
int width = mCustomViewLayout.getMeasuredWidth()
}
});

How to add buttons in ZXing Scanner View?

I already found this How to add buttons in Zxing Scanner Camera View
But it's doesn't work ...
I use a camera in a pop up window like this
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width =dm.widthPixels;
int height =dm.heightPixels;
getWindow().setLayout((int)(width*.9), (int)(height*.7));
WindowManager.LayoutParams params = getWindow().getAttributes();
params.gravity = Gravity.TOP;
params.x =0;
params.y = -20;
getWindow().setAttributes(params);
mScannerView = (ZXingScannerView) findViewById(R.id.zxscan);
mScannerView.setResultHandler(this);
mScannerView.startCamera();
And this is xml file
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CFD8DC"
android:orientation="vertical"
tools:context="com.example.adisi.turzilnic.S1">
<me.dm7.barcodescanner.zxing.ZXingScannerView
android:id="#+id/zxscan"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="#+id/FlashOFF"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/flashoff"
android:layout_marginLeft="150dp"
android:layout_marginStart="150dp"
android:layout_marginTop="150dp"/>
<ImageButton
android:id="#+id/FlashON"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/flashon"
android:layout_gravity="center"
android:layout_marginTop="50dp"/>
</me.dm7.barcodescanner.zxing.ZXingScannerView>
</RelativeLayout>
What is wrong here? I don't understand.. My buttons aren't shown on camera.. Should be from that pop up? I set the buttons with margintop and marginleft on the middle because I wanted to see if the positions it's the problem.. but the same problem ..
The size of your buttons is wrap_content and instead of setting the image source on the button you are setting the image on the background. The view relative sizes don't keep track of your view's background so you will most probably have a view with width/height set to 0.
Try to set the images using "src" instead.

Scale gifs to fit a horizontal ListView

I have a bunch of gifs of different sizes and I want to align then in a horizontal ListView so that they're all the same height, obviously not necessarily the same width.
We are using https://github.com/koral--/android-gif-drawable
Example:
Gif display xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:paddingLeft="10dp"
android:id="#+id/holder"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<pl.droidsonroids.gif.GifTextureView
android:layout_width="100dp"
android:id="#+id/gif_rec_view"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
</RelativeLayout>
Container
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="#+id/title1"
android:layout_marginTop="5dp"
android:background="#android:color/transparent"
android:id="#+id/xD">
<com.devsmart.android.ui.HorizontalListView
android:id="#+id/gif_search_1"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:background="#e3e3e3"
/>
</RelativeLayout>
Load gif into view:
final GifTextureView textureView = (GifTextureView) convertView.findViewById(R.id.gif_rec_view);
LoadGif gLoad = new LoadGif(_objects.get(position).url, textureView);
gLoad.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
How would I best solve this?
Tried bunch of stuff.
//textureView.setLayoutParams(new RelativeLayout.LayoutParams(_objects.get(position).width, _objects.get(position).height));
//RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
//params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
//textureView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
Edit 1:
So looking at this thread: How to scale an Image in ImageView to keep the aspect ratio
using
android:adjustViewBounds="true"
android:scaleType="centerCrop"
worked wonders, however the images cropped like so:
and
android:adjustViewBounds="true"
android:layout_centerInParent="true"
did not work at all.
Okay so this is how I managed to solve it:
Gif display xml
<pl.droidsonroids.gif.GifTextureView
android:layout_width="150dp"
android:layout_height="match_parent"
android:id="#+id/gif_rec_view"
android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"
/>
Adapter
/*Absolutely fucking ridiculous*/
textureView.setLayoutParams(new RelativeLayout.LayoutParams(Utils.pxToDp(_objects.get(position).width), Utils.pxToDp(_objects.get(position).height)));
Utils ...
public static int pxToDp(int px)
{
//return (int) (px / Resources.getSystem().getDisplayMetrics().density);
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, px, Resources.getSystem().getDisplayMetrics());
}
Hope this may help some lone wanderer in the future.

Android - view does not keep height

I'm trying to add a custom view to a linearlayout, but the view does not keep it's height. The height is 48dp so it's fixed but after I do addView() it change to wrap_content :
LinearLayout cmsList = (LinearLayout) mView.findViewById(R.id.ll_cms_sections);
View group = getActivity().getLayoutInflater().inflate(R.layout.item_cms_group, null);
cmsList.addView(group);
The group :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#color/clear_orange">
<com.dekibae.android.popinthecity.presentation.ui.widgets.FontText
android:id="#+id/tv_cms"
style="#style/TitleOrangexNormal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="#dimen/margin_normal"
android:layout_marginStart="#dimen/margin_normal"
android:layout_toLeftOf="#+id/indicator"
android:gravity="center"
android:paddingTop="4dp"
android:text="TEST SECTION"
app:font="#string/plaak" />
<ImageView
android:id="#+id/indicator"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="#dimen/margin_normal"
android:scaleType="centerInside"
android:src="#drawable/dropdown_arrow" />
</RelativeLayout>
The cmsList
<LinearLayout
android:id="#+id/ll_cms_sections"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
I even tried to force it :
group.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 48));
Picking up on #Abtin Gramian's comment the constructor used takes as a dimension pixels, and not dp (density independent pixels)
From the android documentation
android.view.ViewGroup.LayoutParams public LayoutParams(int width,
int height)
Creates a new set of layout parameters with the specified width and height.
Parameters:
width - either WRAP_CONTENT, FILL_PARENT or a fixed size in pixels
height - either
WRAP_CONTENT, FILL_PARENT or a fixed size in pixels
So through the use of
public static float applyDimension (int unit, float value, DisplayMetrics metrics)
we can make a conversion from a dimension in one type of metrics like TypedValue.COMPLEX_UNIT_DIP to another, in this case one adequate for the current display.
group.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, context.getResources().getDisplayMetrics())));

Android: alignment after scaling and size changed

I have a view which defines its width and height accordingly to layout dimensions (via ViewTreeObserver). I have another two ImageViews (wrapped in the RelativeLayouts).
I need this two images be aligned to the top and bottom of the first view. They do, but use old view dimensions, not the corrected ones: so there is a gap between the views, when central gets smaller.
Here is an image of what I mean:
And the code:
#Override
public void onGlobalLayout() {
layoutWidth = layout.getWidth(); \\ main layout
layoutHeight = layout.getHeight();
LayoutParams params = arrows.getLayoutParams();
params.width = layoutHeight/3;
params.height = layoutHeight/3;
arrows.setLayoutParams(params);
LayoutParams paramseyes = eyes.getLayoutParams();
paramseyes.width = layoutHeight/4;
eyes.setLayoutParams(paramseyes);
mouth.setLayoutParams(paramseyes);
/*
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams
(paramseyes);
lp.addRule(RelativeLayout.ABOVE, R.id.arrows);
eyes.setLayoutParams(lp); ... nah, it didnt work
*/
removeOnGlobalLayoutListener(arrows, this);
}
the XML:
<ee.st.running.arrowwidgt
android1:id="#+id/arrows"
android1:layout_width="wrap_content"
android1:layout_height="wrap_content"
android1:layout_centerInParent="true"
android:dial="#drawable/hourglass1"
android:hand_hour="#drawable/hours"
android:hand_minute="#drawable/minuts"
android:scaleType="fitXY"
android1:src="#drawable/hourglass1" />
<RelativeLayout
android1:id="#+id/eyes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android1:layout_above="#id/arrows" >
<ImageView
android1:layout_width="wrap_content"
android1:layout_height="wrap_content"
android1:layout_centerInParent="true"
android1:src="#drawable/eyes" />
</RelativeLayout>
<RelativeLayout
android1:id="#+id/mouthset"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android1:layout_below="#id/arrows"
android:layout_centerHorizontal="true"
>
<ImageView
android1:layout_width="wrap_content"
android1:layout_height="wrap_content"
android1:layout_centerHorizontal="true"
android1:src="#drawable/mouth"
/>
</RelativeLayout>
This arrows view is big (for multiple screens support I just scale it to certain size later).
I finally realized why.
When I changed layout width, it correspondingly scaled the image. But it didn't change layout height.
I should make
paramseyes.height = ...
(In my situation it is layoutHeight/8;)
So, the problem is solved.

Categories